[英]Decide if a circle intersects with an infinite line
因此,我需要檢查圓是否與代數線相交。 我嘗試通過與穿過圓心的無限垂直線垂直來做到這一點。 然后,我測量垂直於圓半徑的垂直線,並指出如果d > r
則該線不相交。
import java.util.Scanner;
public class LineCircle_Intersection {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
double p1x, p2x, p1y, p2y, cx, cy, r;
System.out.print("Enter p1x: ");
p1x = in.nextDouble();
System.out.print("Enter p1y: ");
p1y = in.nextDouble();
System.out.print("Enter p2x: ");
p2x = in.nextDouble();
System.out.print("Enter p2y: ");
p2y = in.nextDouble();
System.out.print("Enter cx: ");
cx = in.nextDouble();
System.out.print("Enter cy: ");
cy = in.nextDouble();
System.out.print("Enter r: ");
r = in.nextDouble();
double m = (p2y - p1y) / (p2x - p1x);
double pem = -1 / m;
double pey = pem + p1y; // pe = perpendicular line (used E instead of L because lowercase l looks too much like 1)
double pex = (pey - p1y) / pem;
double d = Math.sqrt((pex - cx) * (pex - cx) + (pey - cy) * (pey - cy));
if (d <= r) {
if (d == r) {
System.out.println("Line intersects the circle at one point.");
} else {
System.out.println("Line intersects the circle at two points.");
}
} else if (m == 1) {
if (d <= r) // There's a problem in this area. I'm not sure what, or how to fix it.
{
if (d == r) {
System.out.println("The line intersects the circle at one point.");
} else {
System.out.println("Line intersects the circle at two points.");
}
} else {
System.out.println("Line does not intersect the circle.");
}
} else {
System.out.println("Else."); //This says "Else" for testing purposes.
}
}
}
這是開始出錯的地方。 可以輸入的幾個點顯然應該相交或不相交,但是程序經常說不。
我們將為此工作幾個小時,因此,如果我在其他人之前解決了該問題,我將發布更新以及解決方法。
原理是正確的,但我不會驗證您的計算。
簡而言之:
boolean intersects=false, is_tangent=false;
double p2p1x=p2x-p1x, p2p1y=p2y-p1y;
double p1p2DistSq=p2p1x*p2p1x+p2p1y*p2p1y;
if(p1p2DistSq > 1e-12) { // well-behaved line
double p1cx=p1x-cx, p1cy=p1y-cy;
double crossprod=p2p1x*p1cy-p2p1y*p1cx;
double distCenterToLineSquare=crossprod*crossprod/p1p2DistSq;
double rSquare=r*r;
intersects = (distCenterToLineSquare <= rSquare); // r is radius
// for practical purposes, if the relative error of
// (r-dist) is 1e-6 of r, we might consider the line as tangent.
is_tangent = Math.abs(distCenterToLineSquare - rSquare)/rSquare < 1e-12;
} // cowardly refusing to deal with ill-configured lines
詳細說明:
初步(如果您目前沒有互聯網,可將其作為推論點與線之間距離的簡便方法)
兩個向量之間的叉積
{ax, ay} x {bx, by} = |a|*|b|*sin(angle_between_dir_a_and_b)
這個叉積也是(ax*by-ay*bx)
現在,假設一條直線通過P1,其方向由by矢量{ux,uy}定義。 點的距離{cx。 cy}到這行
dist=sin(alpha)*|P1-C|
|| P1-C | 是C和P1之間的距離,而alpha是方向{ux,uy}與線{P1,C}方向之間的角度。 讓我們用{vx,vy}表示{P1,C}行的單一方向。 在這種情況下,由於u和v是單一的( |u|=|v|=1
)
sin(alpha)=ux*vy-uy*vx
從而
dist=(ux*vy-uy*vx)*|P1-C|
插入vx,vy使用
vx=(P1x-Cx)/|P1-C| // it's a unitary vector
vy=(P1y-Cy)/|P1-C|
結果是
dist=ux*(P1y-Cy)-uy*(P1x-Cx)
現在,唯一剩下的就是ux和uy。 由於您的行由P1和P2定義
ux=(P2x-P1x)/|P1-P2|
uy=(P2y-P1y)/|P1-P2|
(再次使用| P1-P2 |,是P1和P2之間的距離)
dist=( (P2x-P1x)*(P1y-Cy)-(P2y-P1y)*(P1x-Cx) )/ |P1-P2|
好的,| P1-P2 | 需要sqrt評估,我們可以通過將dist^2
與radius^2
進行比較來擺脫它
然后,“線相交圓”變為
double p1cx=p1x-cx, p1cy=p1y-cy;
double p2p1x=p2x-p1x, p2p1y=p2y-p1y;
double crossprod=p2p1x*p1cy-p2p1y*p1cx;
double distCenterToLineSquare=crossprod*crossprod/(p2p1x*p2p1x+p2p1y*p2p1y);
boolean intersects= (distCenterToLineSquare <= r*r); // r is radius
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.