Ale*_*vic 10 iphone cocoa-touch objective-c
如何沿特定的UiBezierPath移动球?那可能吗?
我已经尝试了一切,包括使用命中测试
-(BOOL)containsPoint:(CGPoint)point onPath:(UIBezierPath*)path inFillArea:(BOOL)inFill
Run Code Online (Sandbox Code Playgroud)
如何检测路径上的触摸?
Fat*_*tie 14
首先......这绝对是一个事实:
当然,Apple提供的NO方法是
从UIBezierPath中提取点数.
截至2011年2月,在最新的操作系统中,这是绝对的事实,一切都在即将到来.我已经和Apple的相关工程师讨论了这个问题.它在很多游戏编程环境中都很烦人,但这就是事实.那么,它可能会回答你的问题?
第二:不要忘记它是那么容易,因为馅饼动画的东西沿着一个UIBezierPath.在SO上有很多答案,例如,我如何设置沿弯曲路径的视图或图像的移动动画?
第三:关于找出触摸发生的地方,如果这就是你所要求的,正如科里所说,这是一个难题!但是您可以使用CGContextPathContainsPoint来确定点(或触摸)是否在给定厚度的路径上.
在那之后,假设我们正在谈论立方体,你需要找到沿着贝塞尔曲线的点和可能的速度(也就是切线).
以下是完成此操作的完整代码: 在三次贝塞尔曲线上找到一个点的切线(在iPhone上).我也把它贴在下面.
根据您的具体情况,您必须实施自己的MCsim或迭代以找到它所在的位置.那不是那么难.
(第四 - 作为一个脚注,有一个新的东西,你可以逐步绘制一个bezpath,可能与你的问题无关,只是一个注释.)
为了方便将来阅读,以下是两个"方便"例程的链接问题的摘要......
最后,这里以最简单的方式计算等距点(事实上,大致等距)和沿着贝塞尔曲线立方的切线的两个例程:
CGFloat bezierPoint(CGFloat t, CGFloat a, CGFloat b, CGFloat c, CGFloat d)
{
CGFloat C1 = ( d - (3.0 * c) + (3.0 * b) - a );
CGFloat C2 = ( (3.0 * c) - (6.0 * b) + (3.0 * a) );
CGFloat C3 = ( (3.0 * b) - (3.0 * a) );
CGFloat C4 = ( a );
return ( C1*t*t*t + C2*t*t + C3*t + C4 );
}
CGFloat bezierTangent(CGFloat t, CGFloat a, CGFloat b, CGFloat c, CGFloat d)
{
CGFloat C1 = ( d - (3.0 * c) + (3.0 * b) - a );
CGFloat C2 = ( (3.0 * c) - (6.0 * b) + (3.0 * a) );
CGFloat C3 = ( (3.0 * b) - (3.0 * a) );
CGFloat C4 = ( a );
return ( ( 3.0 * C1 * t* t ) + ( 2.0 * C2 * t ) + C3 );
}
Run Code Online (Sandbox Code Playgroud)
四个预先计算的值C1 C2 C3 C4有时被称为贝塞尔曲线的系数.(回想一下,abcd通常被称为四个控制点.)当然,t从0到1运行,也许例如每0.05.只需为X调用一次这些例程,为Y单独调用一次.希望它可以帮到某人!
bezierpath类中有一个名为containsPoint的方法:..参考:http://developer.apple.com/library/ios/#documentation/2ddrawing/conceptual/drawingprintingios/BezierPaths/BezierPaths.html
并且您可以检测触摸点是否在贝塞尔路径对象中的天气.我已经用自己的方法使用了这个方法,用户可以通过这种方法轻松检测贝塞尔曲线路径上的触摸(如果有圆圈或关闭路径,则不在内部或外部).
此代码允许用户在触摸时选择贝塞尔曲线路径绘图对象,并在其上显示带动画的虚线.希望它可以帮到某人.这是我自己项目的代码:
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
if([[self tapTargetForPath:path] containsPoint:startPoint]) // 'path' is bezier path object
{
[self selectShape:currentSelectedPath];// now select a new/same shape
NSLog(@"selectedShapeIndex: %d", selectedShapeIndex);
break;
}
}
// this method will let you easily select a bezier path ( 15 px up and down of a path drawing)
- (UIBezierPath *)tapTargetForPath:(UIBezierPath *)path
{
if (path == nil) {
return nil;
}
CGPathRef tapTargetPath = CGPathCreateCopyByStrokingPath(path.CGPath, NULL, fmaxf(35.0f, path.lineWidth), path.lineCapStyle, path.lineJoinStyle, path.miterLimit);
if (tapTargetPath == NULL) {
return nil;
}
UIBezierPath *tapTarget = [UIBezierPath bezierPathWithCGPath:tapTargetPath];
CGPathRelease(tapTargetPath);
return tapTarget;
}
-(void)selectShape:(UIBezierPath *)pathToSelect
{
centerline = [CAShapeLayer layer];
centerline.path = pathToSelect.CGPath;
centerline.strokeColor = [UIColor whiteColor].CGColor;
centerline.fillColor = [UIColor clearColor].CGColor;
centerline.lineWidth = 1.0;
centerline.lineDashPattern = [NSArray arrayWithObjects:[NSNumber numberWithInt:10], [NSNumber numberWithInt:5], nil];
[self.layer addSublayer:centerline];
// showing animation on line
CABasicAnimation *dashAnimation;
dashAnimation = [CABasicAnimation animationWithKeyPath:@"lineDashPhase"];
[dashAnimation setFromValue:[NSNumber numberWithFloat:0.0f]];
[dashAnimation setToValue:[NSNumber numberWithFloat:30.0f]];
[dashAnimation setDuration:1.0f];
[dashAnimation setRepeatCount:10000];
[centerline addAnimation:dashAnimation forKey:@"linePhase"];
}
Run Code Online (Sandbox Code Playgroud)
这是一个非常困难的问题。您需要确定路径上最接近触摸点的点,这是一个复杂的数学问题。这是我通过快速谷歌搜索能找到的最好的东西。(注意:代码是 BASIC 语言。)
http://www.tinaja.com/glib/bezdist.pdf
我承认,我很想自己写这篇文章。这非常有用,而且我喜欢挑战。
| 归档时间: |
|
| 查看次数: |
8282 次 |
| 最近记录: |