2012-08-04 56 views
1

我已經嘗試了幾種不同的解決方案,但目前爲止沒有運氣。我有一條線從一個圓的中心點到另一個點。我想找到線與圓的圓周相交的點

- (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

我認爲你的罪和cos可能會相反。 – rickster 2012-08-04 20:24:12

+0

沒關係。只需要做一個乾淨的,並重新編譯 – cugrz 2012-08-04 20:29:02

回答

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

更清潔,然後我有 - 謝謝你 – cugrz 2012-08-04 20:46:38

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); 

雖然您的公式在座標系統內是一致的,但它可能與屏幕/顯示設備座標系統有衝突。

相關問題