贝塞尔曲线的参数表达式 [英] Parametric Expression of a Bezier Curve

查看:619
本文介绍了贝塞尔曲线的参数表达式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经使用贝塞尔曲线的参数表达式来沿曲线定位点,并且该点应能正常工作.问题是我将t值设置为y轴的百分比,不幸的是(很明显),它不相关,因为我的曲线比我的Y轴长.因此,在此程序中,如果我将Y值设置为75,我想返回Y值为25的直线上的点(反之,因为在iOS中,(0,0)位于左上角而不是底部留在我的图表中).当前设置我的Y值会将曲线上的点重新调整为75%,Y值为15.62.

I have used the Parametric Expression of a Bezier Curve to locate a point along my curve and it's working as it should. The problem is I'm setting my t value as the percentage of the y axis and unfortunately (and obviously) it doesn't correlate because my curve is longer than my Y axis. So in this program if I set my Y Value to 75 I want to return the point on my line that sits at the Y value of 25 (the inverse because in iOS the (0, 0) sits at the top left instead of the bottom left as my graph reads). Currently setting my Y value retunes the point on my curve at 75% which has a Y of 15.62.

任何人都建议如何在曲线上将点设为Y而不是75%?

Anyone have a recommendation of how to get the point on my curve at Y instead of at 75%?

这是上一个问题的后续问题,在路径,但我觉得保证自己的线程足够不同.

This is a follow-up question to a previous question, finding a point on a path, but I felt it was different enough to warrant its own thread.

#import "GraphView.h"

@interface GraphView ()
{
    float yVal;
}

@end

@implementation GraphView

@synthesize myLabel, yValue;

- (id)initWithCoder:(NSCoder *)aDecoder
{
    self = [super initWithCoder:aDecoder];
    if (self) {
        yVal = 50;
    }
    return self;
}

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

- (void)drawRect:(CGRect)rect
{
    float t = yVal / 100;

    // Starting point
    float p1x = 0;
    float p1y = 100;

    // Control point 1
    float c1x = 50;
    float c1y = 100;

    // Control point 2
    float c2x = 50;
    float c2y = 0;

    // End Point
    float p2x = 100;
    float p2y = 0;

    CGPoint p1 = CGPointMake(p1x, p1y);
    CGPoint c1 = CGPointMake(c1x, c1y);
    CGPoint c2 = CGPointMake(c2x, c2y);
    CGPoint p2 = CGPointMake(p2x, p2y);

    // Cubic Bezier Curver Parmetic Expression
    float X = pow((1 - t), 3) * p1x + 3 * pow((1 - t), 2) * t * c1x + 3 * (1 - t) * pow(t, 2) * c2x + pow(t, 3) * p2x;
    float Y = pow((1 - t), 3) * p1y + 3 * pow((1 - t), 2) * t * c1y + 3 * (1 - t) * pow(t, 2) * c2y + pow(t, 3) * p2y;

    myLabel.text = [NSString stringWithFormat:@"Coord = %.2f, %.2f", X, Y];

    UIBezierPath *circle = [UIBezierPath bezierPathWithOvalInRect:CGRectMake((X - 2), (Y - 2), 4, 4)];
    [[UIColor blackColor] setFill];
    [circle fill];

    UIBezierPath *curve = [[UIBezierPath alloc] init];
    [curve moveToPoint:p1];
    [curve addCurveToPoint:p2 controlPoint1:c1 controlPoint2:c2];
    [curve setLineWidth:1];
    [[UIColor blueColor] setStroke];
    [curve stroke];
}

@end

推荐答案

这是在贝塞尔曲线上找到我的点的解决方案.有关此背景的更多信息,请参阅我的另一篇相关文章-> 在路径上找到一个点

Here is my solution to finding my point on my bezier curve. For more background regarding this see another related post of mine --> finding a point on a path

#import "Calculation.h"

@implementation Calculation

@synthesize a, b, c, d, xy;

- (float) calc
{

    float squareRootCalc =
    sqrt(
    6*pow(xy,2)*b*d
    +4*a*pow(c,3)
    -3*pow(b,2)*pow(c,2)
    +9*pow(xy,2)*pow(c,2)
    -6*a*c*b*d
    +6*a*xy*c*b
    -18*pow(xy,2)*b*c
    +6*a*pow(xy,2)*c
    -12*a*xy*pow(c,2)
    -2*pow(a,2)*xy*d
    +pow(a,2)*pow(d,2)
    +4*pow(b,3)*d
    +pow(xy,2)*pow(d,2)
    -4*pow(b,3)*xy
    -4*pow(c,3)*xy
    +pow(a,2)*pow(xy,2)
    +6*c*b*d*xy
    +6*a*c*d*xy
    +6*a*b*d*xy
    -12*pow(b,2)*d*xy
    +6*xy*c*pow(b,2)
    +6*xy*b*pow(c,2)
    -2*a*pow(xy,2)*d
    -2*a*xy*pow(d,2)
    -6*c*d*pow(xy,2)
    +9*pow(xy,2)*pow(b,2)
    -6*a*pow(xy,2)*b)
    ;

    float aCalc = 24*c*d*xy + 24*a*pow(c,2) - 36*xy*pow(c,2) + 4 * squareRootCalc * a;

    float bCalc = -12 * squareRootCalc * b;

    float cCalc = 12 * squareRootCalc * c;

    float dCalc = -4 * squareRootCalc * d;


    float xyCalc =
    24*xy*a*b
    -24*xy*b*d
    -12*b*a*d
    -12*c*a*d
    -12*c*b*d
    +8*xy*a*d
    +8*pow(b,3)
    +8*pow(c,3)
    +4*pow(a,2)*d
    +24*pow(b,2)*d
    -4*xy*pow(a,2)
    -4*xy*pow(d,2)
    +4*a*pow(d,2)
    -12*c*pow(b,2)
    -12*b*pow(c,2)
    -12*a*b*c
    -24*xy*a*c
    +72*xy*c*b
    -36*xy*pow(b,2)
    ;

    float cubeRootCalc = cbrt(aCalc + bCalc + cCalc + dCalc + xyCalc);

    float denomCalc = (a-3*b+3*c-d);

    float secOneCalc = 0.5 * cubeRootCalc / denomCalc;

    float secTwoCalc = -2 * ((a*c - a*d - pow(b,2) + c*b + b*d - pow(c,2)) / (denomCalc * cubeRootCalc));

    float secThreeCalc = (a - 2*b + c) / denomCalc;

    return secOneCalc + secTwoCalc + secThreeCalc;


}

- (Calculation *) initWithA:(float)p0 andB:(float)p1 andC:(float)p2 andD:(float)p3 andXy:(float)xyValue
{
    self = [super init];

    if (self) {
        [self setA:p0];
        [self setB:p1];
        [self setC:p2];
        [self setD:p3];
        [self setXy:xyValue];
    }
    return self;
}

- (void) setA:(float)p0 andB:(float)p1 andC:(float)p2 andD:(float)p3 andXy:(float)xyValue
{
    [self setA:p0];
    [self setB:p1];
    [self setC:p2];
    [self setD:p3];
    [self setXy:xyValue];
}

@end

这篇关于贝塞尔曲线的参数表达式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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