2013-05-27 26 views
0

我已經使用貝塞爾曲線的參數化表達式來定位沿着曲線的一個點,它的工作方式應該如此。問題是我將我的t值設置爲y軸的百分比,不幸的是(顯然)它不相關,因爲我的曲線比我的Y軸長。所以在這個程序中,如果我將Y值設置爲75,我想返回座標爲25的Y值的線上的點(因爲在iOS中,(0,0)位於左上角而不是底部留作我的圖表讀取)。目前設置我的Y值會將曲線上的點重新調整爲75%,其Y值爲15.62。貝塞爾曲線的參數化表達式

任何人都有如何讓我的曲線上的點在Y而不是在75%的建議?

這是對前一個問題finding a point on a path的後續問題,但我覺得它有足夠的不同以保證它自己的線程。

#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 
+0

會http://pomax.github.com/bezierinfo是對你有用嗎? –

回答

0

這是我的解決方案,以找到我的貝塞爾曲線上的點。有關此看到我的另一個相關帖子更多的背景 - >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