找到一个点的路径上 [英] finding a point on a path

查看:191
本文介绍了找到一个点的路径上的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个应用程序,绘制贝塞尔曲线在的UIView ,我需要找到在X相交,当我设置一个值Y.首先,据我所知,有没有一种方法,直接在 UIBezierPath 中找到一个点,但你可以找到一个点 CGPath 的。

首先,如果我中风我的 UIBezierPath (正如我在code所做的)是这实际上创建CGPath或者我需要采取进一步步骤其实将此转换为 CGPath

二,我想找到的曲线相交位于X通过Y的提供的价值。

我的目的是自动地计算x为Y的定值作为用户移动滑块(而移动左或右分别曲线)。

我开始显示。

会发生什么事我目前调整滑块。

我要什么我显示太的模样。

GraphView.h

 #进口< UIKit中/ UIKit.h>

@interface GraphView:UIView的
{
    浮动调整;
    INT X;
    诠释Ÿ;
}

 - (IBAction为)sliderChanged:(ID)发送;
 - (IBAction为)yChanged:(ID)发送;

@property(弱,非原子)IBOutlet UISlider * sliderValue;
@property(弱,非原子)IBOutlet的UITextField *与xValue;
@property(弱,非原子)IBOutlet的UITextField * y值;

@结束
 

GraphView.m

 #进口GraphView.h

@interface GraphView()


@结束

@implementation GraphView

@synthesize sliderValue与xValue,y值;

 - (ID)initWith codeR:(NS codeR *)graphView
{
    自= [超级initWith codeR:graphView]。
    如果(个体经营){
        调整= 194;
        Y = 100;
    }
    回归自我;
}

 - (IBAction为)sliderChanged:(ID)发件人
{
    调整= sliderValue.value;
    // Calcualtion的X值和xValue.text textField的的设置到这里
    [自我setNeedsDisplay];
}

 - (IBAction为)yChanged:(ID)发件人
{
    Y = yValue.text.intValue;
    [自我setNeedsDisplay];
    [自resignFirstResponder]
}

 - (无效)的touchesBegan:(的NSSet *)触及withEvent:(的UIEvent *)事件{
    UITouch *触摸= [触摸anyObject]
    如果(touch.phase == UITouchPhaseBegan){
        Y = yValue.text.intValue;
        [自我setNeedsDisplay];
        [y值resignFirstResponder]
    }
}

 - (无效)的drawRect:(CGRect)RECT
{
    UIBezierPath *线= [[UIBezierPath页头]初始化];
    [行moveToPoint:CGPointMake(0,Y)];
    [行addLineToPoint:CGPointMake(200,Y)];
    [线条addLineToPoint:CGPointMake(200,280)];
    [线条setLineWidth:1];
    [的UIColor redColor] setStroke]。
    浮dashPattern [] = {2,2};
    [行setLineDash:dashPattern数:2阶段:0.0]。
    [线路行程];

    UIBezierPath *曲线= [[UIBezierPath页头]初始化];
    [曲线moveToPoint:CGPointMake(0,280)];
    [曲线addCurveToPoint:CGPointMake(280,0)controlPoint1:CGPointMake(调整,280)controlPoint2:CGPointMake(调整,0);
    [曲线setLineWidth:2];
    [的UIColor blueColor] setStroke]。
    [曲线行程];

}

@结束
 

解决方案

一个三次贝塞尔曲线是由4个点定义

  P0 =(X0,Y0)=起点,
P1 =(X1,Y1)=第一控制点,
P2 =(X2,Y2)=第二控制点,
P3 =(X3,Y3)=结束点,
 

和由所有点的

  X(t)=(1-T)^ 3 * X0 + 3 * T *(1-T)^ 2 * X1 + 3 * T ^ 2 *(1- T)* 2 + T ^ 3 * X3
Y(吨)=(1-t)的^ 3 * Y0 + 3 * T *(1-t)的^ 2 * Y1 + 3 *吨^ 2 *(1-t)的* Y2 + T ^ 3 * Y3
 

其中, T 0 运行到 1

因此​​,要计算x对于y的给定值,你首先要计算出一个 参数值 T ,使得 0℃= T< = 1

  Y =(1-T)^ 3 * Y0 + 3 * T *(1-T)^ 2 * Y1 + 3 * T ^ 2 *(1-T)* Y2 + T ^ 3 * Y 3(1)
 

,然后计算在X与协调

  X =(1-T)^ 3 * Y0 + 3 * T *(1-T)^ 2 * Y1 + 3 * T ^ 2 *(1-T)* Y2 + T ^ 3 * Y3(2)
 

所以,你必须解决的三次方程(1) T 并替换值代入式(2)。

三次方程可以显式(解决如见 http://en.wikipedia.org/wiki/Cubic_function )或迭代(例如使用 http://en.wikipedia.org/wiki/Bisection_method )。

在一般情况下,一个三次方程最多可以有三个不同的解决方案。在您的具体情况,我们有

  P0 =(0,280),P1 =(调整,280),P3 =(调整,0),P4 =(280,0)
 

使得等式(1)变为

  Y =(1-T)^ 3 * 280 + 3 * T *(1-T)^ 2 * 280
 

这简化了

  Y / 280 = 1  -  3 * T ^ 2 + 2 * T ^ 3(3)
 

(3)为 T 在区间严格递减函数 [0,1] ,所以不难看出,(3)有且只有一个解决办法,如果 0℃= Y< = 280 。 代此溶液注入(2),得到所需的X值。

I have an app that draws a bezier curve in a UIView and I need to find the X intersect when I set a value for Y. First, as I understand, there isn’t a way to find a point directly of a UIBezierPath but you can locate a point of a CGPath.

First, if I "stroke" my UIBezierPath (as I have done in my code) is this actually creating a CGPath or do I need to take further steps to actually convert this to a CGPath?

Second, I want to find the curves intersect at X by providing the value for Y.

My intention is to automatically calculate X for the given value of Y as the user moves the slider (which moves the curve left or right respectively).

My starting display.

What happens when I currently adjust slider.

What I want my display too look like.

GraphView.h

#import <UIKit/UIKit.h>

@interface GraphView : UIView
{
    float adjust;
    int x;
    int y;
}

- (IBAction)sliderChanged:(id)sender;
- (IBAction)yChanged:(id)sender;

@property (weak, nonatomic) IBOutlet UISlider *sliderValue;
@property (weak, nonatomic) IBOutlet UITextField *xValue;
@property (weak, nonatomic) IBOutlet UITextField *yValue;

@end

GraphView.m

#import "GraphView.h"

@interface GraphView ()


@end

@implementation GraphView

@synthesize sliderValue, xValue, yValue;

- (id)initWithCoder:(NSCoder *)graphView
{
    self = [super initWithCoder:graphView];
    if (self) {
        adjust = 194;
        y = 100;
    }
    return self;
}

- (IBAction)sliderChanged:(id)sender
{
    adjust = sliderValue.value;
    // Calcualtion of the X Value and setting of xValue.text textField goes here
    [self setNeedsDisplay];
}

- (IBAction)yChanged:(id)sender
{
    y = yValue.text.intValue;
    [self setNeedsDisplay];
    [self resignFirstResponder];
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    UITouch * touch = [touches anyObject];
    if(touch.phase == UITouchPhaseBegan) {
        y = yValue.text.intValue;
        [self setNeedsDisplay];
        [yValue resignFirstResponder];
    }
}

- (void)drawRect:(CGRect)rect
{
    UIBezierPath *lines = [[UIBezierPath alloc] init];
    [lines moveToPoint:CGPointMake(0, y)];
    [lines addLineToPoint:CGPointMake(200, y)];
    [lines addLineToPoint:CGPointMake(200, 280)];
    [lines setLineWidth:1];
    [[UIColor redColor] setStroke];
    float dashPattern[] = {2, 2};
    [lines setLineDash:dashPattern count:2 phase:0.0];
    [lines stroke];

    UIBezierPath *curve = [[UIBezierPath alloc] init];
    [curve moveToPoint:CGPointMake(0, 280)];
    [curve addCurveToPoint:CGPointMake(280, 0) controlPoint1:CGPointMake(adjust, 280) controlPoint2:CGPointMake(adjust, 0)];
    [curve setLineWidth:2];
    [[UIColor blueColor] setStroke];
    [curve stroke];

}

@end

解决方案

A cubic Bézier curve is defined by 4 points

P0 = (x0, y0) = start point,
P1 = (x1, y1) = first control point,
P2 = (x2, y2) = second control point,
P3 = (x3, y3) = end point,

and consists of all points

x(t) = (1-t)^3 * x0 + 3*t*(1-t)^2 * x1 + 3*t^2*(1-t) * x2 + t^3 * x3
y(t) = (1-t)^3 * y0 + 3*t*(1-t)^2 * y1 + 3*t^2*(1-t) * y2 + t^3 * y3

where t runs from 0 to 1.

Therefore, to calculate X for a given value of Y, you first have to calculate a parameter value T such that 0 <= T <= 1 and

 Y = (1-T)^3 * y0 + 3*T*(1-T)^2 * y1 + 3*T^2*(1-T) * y2 + T^3 * y3      (1)

and then compute the X coordinate with

 X = (1-T)^3 * y0 + 3*T*(1-T)^2 * y1 + 3*T^2*(1-T) * y2 + T^3 * y3      (2)

So you have to solve the cubic equation (1) for T and substitute the value into (2).

Cubic equations can be solved explicitly (see e.g. http://en.wikipedia.org/wiki/Cubic_function) or iteratively (for example using the http://en.wikipedia.org/wiki/Bisection_method).

In general, a cubic equation can have up to three different solutions. In your concrete case we have

P0 = (0, 280), P1 = (adjust, 280), P3 = (adjust, 0), P4 = (280, 0)

so that the equation (1) becomes

Y = (1-T)^3 * 280 + 3*T*(1-T)^2 * 280

which simplifies to

Y/280 = 1 - 3*T^2 + 2*T^3    (3)

The right hand side of (3) is a strictly decreasing function of T in the interval [0, 1], so it is not difficult to see that (3) has exactly one solution if 0 <= Y <= 280. Substituting this solution into (2) gives the desired X value.

这篇关于找到一个点的路径上的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆