我如何绘制两条线之间有一些角度,以后可以通过拖动任何一条线来改变角度

时间:2013-12-02 13:40:46

标签: ios iphone drawing line angle

我想像app(http://blog.ubersense.com/2013/01/03/how-to-use-the-drawing-tools-in-ubersense/)一样制作UBersense,我需要用一些角度绘制两条线,然后我可以通过拖动任何线或交叉点来调整两条线之间的角度。 你能不能给我一些想法或代码片段。

截图网址: https://picasaweb.google.com/yunusm7/AppScreenshots#slideshow/5952787957718627714

提前致谢。

1 个答案:

答案 0 :(得分:1)

你有一个有三个点的结构,一个点是一个角点,另外两个只是顶点。首先,你应该创建一个这样的新类:

@interface MyAngle : NSObject {

}

@property (nonatomic) CGPoint p1;
@property (nonatomic) CGPoint p2;
@property (nonatomic) CGPoint v; // this is an angle point

@end 

您可以使用此默认实现,而无需使用此类示例init的任何技巧:

- (id)init {
   if (self = [super init]) {
       p1 = CGPointMake(1,0);
       p2 = CGPointMake(0,1);
       v = CGPointZero;
   }
   return self;
}

但据我所知,你需要知道角度的值。您可以使用以下方式执行此操作:

- (CGFloat)valueOfAngle {
    CGPoint v1 = CGPointMake(p1.x-v.x, p1.y-v.y);
    CGPoint v2 = CGPointMake(p2.x-v.x, p2.y-v.y);

    CGFloat scalarProduct = v1.x*v2.x + v1.y*v2.y;
    CGFloat lengthProduct = sqrt(v1.x*v1.x + v1.y*v1.y)*sqrt(v2.x*v2.x + v2.y*v2.y);
    CGFloat fraction = scalarProduct / lengthProduct;
    if (fraction < -1) fraction = -1;
    if (fraction > 1) fraction = 1;

    return acos(fraction);
}

如果您想获得超过180度的角度,您应该将代码更改一点。但有关如何在互联网上执行此操作的信息太多,因此我将跳过此部分。

然后你需要在viewController中创建一个MyAngle实例。让它被称为“角度”。知道每三个点的坐标,如果足够的话绘制它(!!!)。在包含MyAngle实例的视图中实现drawRect方法(我强烈建议您在自己的UIView子类上执行此操作):

- (void)drawRect {
    [super drawRect];

    // set options of drawing
    CGContextRef c = UIGraphicsGetCurrentContext();
    CGFloat red[4] = {1.0f, 0.0f, 0.0f, 1.0f};
    CGContextSetLineWidth(c, 3.0);
    CGContextSetStrokeColor(c, red);

    // draw an angle directly
    CGContextBeginPath(c);
    CGContextMoveToPoint(c, angle.p1.x, angle.p1.y);
    CGContextAddLineToPoint(c, angle.v.x, angle.v.y);
    CGContextAddLineToPoint(c, angle.p2.x, angle.p2.y);
    CGContextStrokePath(c);

    // draw circles around vertices (like on the screenshot you provided)
    CGFloat R = 7.0f;
    CGContextBeginPath(c);
    CGContextAddEllipseInRect(c, CGRectMake(angle.p1.x - R, angle.p1.y - R, 2*R, 2*R));
    CGContextStrokePath(c);

    CGContextBeginPath(c);
    CGContextAddEllipseInRect(c, CGRectMake(angle.p2.x - R, angle.p2.y - R, 2*R, 2*R));
    CGContextStrokePath(c);

    CGContextBeginPath(c);
    CGContextAddEllipseInRect(c, CGRectMake(angle.v.x - R, angle.v.y - R, 2*R, 2*R));
    CGContextStrokePath(c);
}

这就是你需要知道的所有你想要的东西!如果需要,可以更改三个圆的笔触颜色或半径。

然后你需要有可能改变角度点的位置。为此,您可以在viewController的viewDidLoad方法中实现panGestureRecognizer,如下所示:

UIPanGestureRecognizer *pan = [[[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(moveAngle:)] autorelease];
pan.delegate = self;
[self.view addGestureRecognizer:pan]; 

实施UIGestureRecognizerDelegate方法:

- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {
    if ([gestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]]) {
        CGPoint p = [gestureRecognizer locationInView:self.view];
        CGFloat d1 = sqrt((p.x-angle.p1.x)*(p.x-angle.p1.x) + (p.y-angle.p1.y)*(p.y-angle.p1.y);
        CGFloat d2 = sqrt((p.x-angle.p2.x)*(p.x-angle.p2.x) + (p.y-angle.p2.y)*(p.y-angle.p2.y);
        CGFloat d3 = sqrt((p.x-angle.v.x)*(p.x-angle.v.x) + (p.y-angle.v.y)*(p.y-angle.v.y);

        // just check if we touched the screen near some of angle's points
        CGFloat tolerance = 15.0f;
        return (d1 < tolerance) || (d2 < tolerance) || (d3 < tolerance);
    }
    return YES;
}

和tagret的选择器(也在你的viewController中):

- (void)moveAngle:(UIPanGestureRecognizer *)gr {
    CGPoint p = [gr locationInView:self.view];

    if (gr.state == UIGestureRecognizerStateBegan) {
        CGFloat d1 = sqrt((p.x-angle.p1.x)*(p.x-angle.p1.x) + (p.y-angle.p1.y)*(p.y-angle.p1.y);
        CGFloat d2 = sqrt((p.x-angle.p2.x)*(p.x-angle.p2.x) + (p.y-angle.p2.y)*(p.y-angle.p2.y);
        CGFloat d3 = sqrt((p.x-angle.v.x)*(p.x-angle.v.x) + (p.y-angle.v.y)*(p.y-angle.v.y);

        // pointToMove is your int variable
        CGFloat tolerance = 15.0f;
        if (d1 < tolerance) {
            pointToMove = 1;
        }
        else if (d2 < tolerance) {
            pointToMove = 2;
        }
        else {
            pointToMove = 3;
        }
    }
    else {
        if (pointToMove == 1) {
            angle.p1 = loc;
        }
        else if (pointToMove == 2) {
            angle.p2 = loc;
        }
        else {
            angle.v = loc;
        }
        [yourCustomView setNeedsDisplay];
        [yourLabel setText:[NSString stringWithFormat:@"%.3f", [angle valueOfangle]*180/PI]];
    }
}

也许我会跳过一些明显的事情,但我认为你应该开始写一些代码了。