到目前为止,我尝试了几种不同的解决方案但没有运气。
- (CGPoint)contractLineTemp:(CGPoint)point :(CGPoint)circle :(float)circleRadius {
CGFloat x,y;
x = point.x - circle.x;
y = point.y - circle.y;
CGFloat theta = atan2(x, y);
CGPoint newPoint;
newPoint.x = circle.x + circleRadius * sin(theta);
newPoint.y = circle.y + circleRadius * cos(theta);
return newPoint;
}
- (CGPoint)contractLineTemp:(CGPoint)startPoint :(CGPoint)endPoint :(float)scaleBy {
float dx = endPoint.x - startPoint.x;
float dy = endPoint.y - startPoint.y;
float scale = scaleBy * Q_rsqrt(dx * dx + dy * dy);
return CGPointMake (endPoint.x - dx * scale, endPoint.y - dy * scale);
}
这两种解决方案都很有效。如果我将线条绘制到圆的中心,您可以看到它与圆圈的确切位置相交。
http://www.freeimagehosting.net/le5pi
如果我使用上述任何一种解决方案并根据角度绘制圆周,则不再朝向圆心。在第二个图像中,线应位于圆的右边缘的中间并向右直。
http://www.freeimagehosting.net/53ovs
http://www.freeimagehosting.net/sb3b2
很抱歉这些链接。我是新来的,目前发布图片。
谢谢你的帮助。
答案 0 :(得分:5)
将此视为矢量问题更容易。您的第二种方法很接近,但是您没有正确地缩放两点之间的向量。在这种情况下,使用标准化向量更容易,尽管您必须假设线上两点之间的距离不为零。
鉴于:
double x0 = CIRC_X0; /* x-coord of center of circle */
double y0 = CIRC_Y0; /* y-coord of center of circle */
double x1 = LINE_X1; /* x-coord of other point on the line */
double y1 = LINE_Y1; /* y-coord of other point on the line */
然后两点之间的向量是(vx,vy):
double vx = x1 - x0;
double vy = y1 - y0;
使用单位向量更容易,我们可以通过规范化(vx,vy)来获得:
double vmag = sqrt(vx*vx + vy*vy);
vx /= vmag; /* Assumption is vmag > 0 */
vy /= vmag;
现在,沿线的任何一点都可以描述为:
x0 + dist * vx
y0 + dist * vy
其中dist
是距离中心的距离。圆与线的交点必须与CIRC_RADIUS
的距离为中心,因此:
double x_intersect = x0 + CIRC_RADIUS * vx;
double y_intersect = y0 + CIRC_RADIUS * vy;
答案 1 :(得分:0)
我认为theta,x和y可能存在约定冲突。 atan2函数产生-pi..pi范围内的值,通过将θ的约定作为从X轴向Y增长的角度。然而,您将θ视为从Y到X的角度。 尝试更改代码:
CGFloat theta = atan2(y, x);
CGPoint newPoint;
newPoint.x = circle.x + circleRadius * cos(theta);
newPoint.y = circle.y + circleRadius * sin(theta);
虽然您的公式在坐标系内是一致的,但它可能与屏幕/显示设备坐标系有冲突。