从UIBezierPath获取积分 [英] Get points from a UIBezierPath

查看:83
本文介绍了从UIBezierPath获取积分的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我通过执行以下操作绘制了上面的BezierPath: //位置是用户触摸屏幕的位置. //位置将是图表的最大值 CGPoint原点= CGPointMake(xStart,620.0); CGPoint endpt = CGPointMake(xEnd,620.0); CGPoint midpt1 = midPointForPoints(来源,位置); CGPoint midpt2 = midPointForPoints(location,endpt);

I drew the above BezierPath by doing: // location is where the user touches screen. // location will be the maximum of the graph CGPoint origin = CGPointMake(xStart, 620.0); CGPoint endpt = CGPointMake(xEnd, 620.0); CGPoint midpt1 = midPointForPoints(origin, location); CGPoint midpt2 = midPointForPoints(location, endpt);

UIBezierPath *path = [UIBezierPath bezierPath];
[path moveToPoint:origin];
[path addQuadCurveToPoint:location controlPoint:CGPointMake(midpt1.x, midpt1.y+50)];
[path addQuadCurveToPoint:endpt controlPoint:CGPointMake(midpt2.x, midpt2.y+50)];

[shapeLayer setPath:path.CGPath];

现在,我想检索路径上某些x坐标的y坐标.例如,给定x = 0.0,我想得到y = 0.0,或者给定x = 300.0,y = 50.0.

Now, I want to retrieve y-coordinates for certain x-coordinates that lie on the path. For example, given x = 0.0, I want to get y = 0.0, or given x = 300.0, y = 50.0.

我查看了一些类似这样的参考文献问题

I looked at some references like this question and sample code I am still not sure. Update: basically, I want to do something like this.

更新: 遵循@Fang的建议:

Update: Following @Fang's advice:

给出方程式

X = (1-t)^2*X0 + 2*t*(1-t)*X1 + t^2 *X2

我解决t

t = ((2.0 * x0 - x1) + sqrt(((-2.0 * x0 + x1) ** 2.0) 
- ((4 * (x0 - 2.0 * x1 + x2)) * (x0 - x)))) / (2.0 * (x0 - 2.0 * x1 + x2))

t = ((2.0 * x0 - x1) - sqrt(((-2.0 * x0 + x1) ** 2.0) 
- ((4 * (x0 - 2.0 * x1 + x2)) * (x0 - x)))) / (2.0 * (x0 - 2.0 * x1 + x2))

使用此值,找到与X对应的Y(我们使用X来找到上述t值)

Using this value, find Y that corresponds to X (we used X to find the above t value)

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

按照上面的公式,我应该得到贝塞尔曲线上的点的y值,但我得到的点离正确的点很远.任何进一步的帮助将不胜感激..

Following the above equation, I am supposed to get the y-value of the point that lies on the Bezier curve but I get a point that's far from the right one. Any further help will be very much appreciated..

关注点:我认为一个可能的问题是,我用两个控制点两次调用addQuadCurveToPoint(),而不是用两个控制点一次.这是否意味着我绘制了两条贝塞尔曲线路径并将其合并?我也在查看

Concern: I think one possible problem is that I am calling addQuadCurveToPoint() twice with two control points instead of once with two control points. Does it mean I draw two Bezier paths and combine them? I am also looking at this to see what's wrong with my computation and the only difference seems to be that he uses two control points when calling addQuadCurveToPoint().

经过方的密切咨询之后的更新:

- (float)getYFromBezierPath:(float)x location:(CGPoint)location ctrlpt1:(CGPoint)ctrlpt1 ctrlpt2:(CGPoint)ctrlpt2 endpt:(CGPoint)endpt {
    float yVal;
    float tVal;
    if (x <= location.x) {
        tVal = [self getTvalFromBezierPath:x x0Val:0.0 x1Val:ctrlpt1.x x2Val:location.x];
        yVal = [self getCoordFromBezierPath:tVal origin:0.0 p1Val:ctrlpt1.y p2Val:location.y];
    } else {
        // THIS PART IS THE PROBLEM //
        tVal = [self getTvalFromBezierPath:x x0Val:location.x x1Val:ctrlpt2.x x2Val:endpt.x];
        yVal = [self getCoordFromBezierPath:tVal origin:location.y p1Val:ctrlpt2.y p2Val:endpt.y];
    }
    return yVal;
}

- (float)getTvalFromBezierPath:(float)x x0Val:(float)x0 x1Val:(float)x1 x2Val:(float)x2 {
    float tVal = (x-x0)/(2*(x1-x0));
    return tVal;
}

- (float)getCoordFromBezierPath:(float)t origin: (float)origin p1Val: (float)p1 p2Val: (float)p2 {
// tVal = (sqrt((-2.0 * x * x1) + (x * x0) + (x * x2) + pow(x1, 2) - (x0 * x2)) + x0 - x1) / (x0 - (2.0 * x1) + x2);
    return (pow((1-t),2) * origin) + (2 * t * (1-t) * p1) + (pow(t,2) * p2);
}

最后一个问题: 对于第二个Bezeir路径,y值应随t值的增加而减小.目前,y值一直在增加.我该如何解决?经过大量调试后,我仍未找到发生这种情况的原因,因为所有内容都符合该文档.

Last question: for the second Bezeir path, y-value should decrease as t-value increases. Right now, y-value keeps increasing. How should I fix this? After intensive debugging I haven't found why this is happening because everything conforms to the document.

推荐答案

应该可以沿着Bezier路径获取点,因为addQuadCurveToPoint会将二次Bezier线段添加到路径中.因此,您的第一个二次贝塞尔曲线的三个控制点是(请参阅原始文章中的代码段)

It should be possible to get points along a Bezier path as addQuadCurveToPoint is to add a quadratic Bezier segment into the path. So, the three control points of your first quadratic Bezier curve are (refer to the code piece in original post)

P(0)=起源
P(1)=(midpt1.x,midpt1.y + 50)
P(2)=位置

P(0) = origin
P(1) = (midpt1.x, midpt1.y+50)
P(2) = location

您可以通过将参数t从0更改为1任意小的增量值,来根据需要在此二次Bezier曲线上计算任意数量的点

You can compute as many points on this quadratic Bezier curve as you want by varying the parameter t from 0 to 1 by any small increment value as

C(t)=(1-t)^ 2 * P(0)+ 2 * t *(1-t)* P(1)+ t ^ 2 * P(2)

C(t) = (1-t)^2*P(0) + 2*t*(1-t)*P(1) + t^2 *P(2)

要从给定的X值中获取Y值,您将必须从t的二次多项式中的给定X值中求解t值:

To get the Y value from a given X value, you will have to solve for the t value from the given X value from this quadratic polynomial of t:

X =(1-t)^ 2 * X0 + 2 * t *(1-t)* X1 + t ^ 2 * X2

X = (1-t)^2*X0 + 2*t*(1-t)*X1 + t^2 *X2

其中X0,X1和X2是P(0),P(1)和P(2)的X坐标,这意味着X0 = origin.x,X1 = midpt1.x和X2 = location.x.

where X0, X1 and X2 are the X coordinates of P(0), P(1) and P(2), which means X0=origin.x, X1=midpt1.x and X2=location.x.

由此,我们可以得到一个二次方程式

From this, we can obtain a quadratic equation

(X0-2 * X1 + X2) t ^ 2 + 2 (X1-X0)* t +(X0-X)= 0

(X0-2*X1+X2)t^2 + 2(X1-X0)*t + (X0-X) = 0

您可以使用二次公式求解t.如果您的X0,X1和X2值恰好使t ^ 2项的系数为零,则可以直接求解t,因为t =(X-X0)/(2 *(X1-X0)).

You can solve for t using the quadratic formula. If your X0, X1 and X2 values happens to make the coefficient of t^2 term zero, you can solve for t directly as t = (X-X0)/(2*(X1-X0)).

一旦有了t值,就可以轻松评估相应的Y值.

Once you have the t value, you can easily evaluate the corresponding Y value.

这篇关于从UIBezierPath获取积分的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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