我想像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
提前致谢。
答案 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]];
}
}
也许我会跳过一些明显的事情,但我认为你应该开始写一些代码了。