所以,我需要检查圆是否以代数方式与一条线相交。我试图通过对穿过圆心的无限远垂直线来做到这一点。然后,我测量垂直于圆的半径,并指出如果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.
}
}
}
这里的事情开始出错了。有几个点可以输入,显然应该相交或不相交,但程序经常说不然。
将在这个问题上工作几个小时,所以如果我在别人面前解决这个问题,我会发布更新以及我是如何解决的。
答案 0 :(得分:0)
原则是正确的,但我不会验证您的计算。
简而言之:
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,方向由酉向量{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,vyvx=(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