线圆相交的垂直线和水平线 [英] Line Circle intersection for Vertical and Horizontal Lines

查看:147
本文介绍了线圆相交的垂直线和水平线的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想检测何时线相交在javascript了一圈。我发现了一个功能,几乎完美的作品,但最近,我发现它不工作时,相贯线是完全水平或垂直。因为我不具备这个函数的实际工作有很大的了解,我不知道如何编辑它得到的结果,我想。

 函数lineCircleCollision(circleX,circleY,半径,lineX1,lineY1,lineX2,lineY2){
    VAR D1 = pDist(lineX1,lineY1,circleX,circleY);
    VAR D2 = pDist(lineX2,lineY2,circleX,circleY);
    如果(D1< =半径|| D2< =半径){
            返回true;
    }

    变种K1 =((lineY2-lineY1)/(lineX2-lineX1));
    VAR K2 = lineY1;
    VAR K3 = -1 / K1;
    VAR K4 = circleY;

    VAR XX =(K1 * lineX1-K2-K3 * circleX + K4)/(K1-K3);
    VAR YY = K1 *(XX-lineX1)+ lineY1;

    VAR允许= TRUE;
    如果(lineX2> lineX1){
        如果(XX> = lineX1和放大器;&安培; XX< = lineX2){}
        其他{允许= FALSE;}
    } 其他 {
        如果(XX> = lineX2和放大器;&安培; XX< = lineX1){}
        其他{允许= FALSE;}
    }

    如果(lineY2> lineY1){
        如果(YY> = lineY1和放大器;&安培; YY< = lineY2){}
        其他{允许= FALSE;}
    } 其他 {
        如果(YY> = lineY2和放大器;&安培; YY< = lineY1){}
        其他{允许= FALSE;}
    }
    如果(让){
        如果(pDist(circleX,circleY,XX,YY)<半径){
            返回true;
        }
        其他 {
            返回false;
        }
    } 其他 {
        返回false;
    }
}

功能pDist(X1,Y1,X2,Y2){
    变种XD = X2-X1;
    VAR YD = Y2,Y1;
    返回的Math.sqrt(XD * XD +码*码);
}
 

解决方案

您可以EX preSS行作为两个关系:

  X = X1 + K *(X2  -  X1)= X1 + K * DX
Y = Y1 + K *(Y2  -  Y1)= Y1 + K * DY
 

0℃ K< 1 。圆上的一个点满足方程:

 (X  -  CX)2 +(Y  -  CY)2 = R 2
 

替换 X 的行式,你会得到一个二次方程:

  A *K²+ B * K + C = 0

A =dx²+dy²
B = 2 * DX *(X1  -  CX)+ S * DY *(Y1  -  CY)
C =(X 1  -  CX)²+(Y1  - 赛扬)2  -  R 2
 

解决了,如果有任何的 K 的两个可能的解决办法在于介于0和1之间,你必须一炮打响。此方法检查真正的十字路口,错过那里的线完全包含在圈内的情况下,这样的附加检查是否该行的终点所在的圆内是必要的。

这里的code:

 函数collision_circle_line(CX,CY,R,X1,Y1,X2,Y2){
    变种DX = X2  -  X1;
    变种DY = Y2  -  Y1;

    VAR SX = X1  -  CX;
    变种SY = Y1  - 赛扬;

    VAR TX = X2  -  CX;
    变种TY = Y2  - 赛扬;

    如果(TX * TX + TY * TY< R * R)返回true;

    变种C = SX * SX + SY * SY  -  R的* R;
    如果(C< 0)返回true;

    变种B = 2 *(DX * SX + DY * SY);
    VAR一个= DX * DX + DY * DY;

    如果(Math.abs(一)LT; 1.0E-12)返回false;

    VAR DISCR = B * B  -  4 * A * C;
    如果(DISCR℃下)返回false;
    DISCR =的Math.sqrt(DISCR);

    变种K1 =(-b  -  DISCR)/(2 * A);
    如果(K1> = 0&功放;&安培; K1< = 1)返回true;

    变种K2 =(-b + DISCR)/(2 * A);
    如果(K2> = 0&功放;&安培; K2< = 1)返回true;

    返回false;
}
 

I'm trying to detect when a line intersects a circle in javascript. I found a function that works almost perfectly but I recently noticed that it does not work when the intersecting line is perfectly horizontal or vertical. Since I don't have a great understanding of how this function actually works, I'm not sure how to edit it to get the results I'd like.

function lineCircleCollision(circleX,circleY,radius,lineX1,lineY1,lineX2,lineY2) {
    var d1 = pDist(lineX1,lineY1,circleX,circleY);
    var d2 = pDist(lineX2,lineY2,circleX,circleY);
    if (d1<=radius || d2<=radius) {
            return true;
    }

    var k1 = ((lineY2-lineY1)/(lineX2-lineX1));
    var k2 = lineY1;
    var k3 = -1/k1;
    var k4 = circleY;

    var xx = (k1*lineX1-k2-k3*circleX+k4)/(k1-k3);
    var yy = k1*(xx-lineX1)+lineY1;

    var allow = true;
    if (lineX2>lineX1) {
        if (xx>=lineX1 && xx<=lineX2) {}
        else {allow = false;}
    } else {
        if (xx>=lineX2 && xx<=lineX1) {}
        else {allow = false;}
    }

    if (lineY2>lineY1) {
        if (yy>=lineY1 && yy<=lineY2) {}
        else {allow = false;}
    } else {
        if (yy>=lineY2 && yy<=lineY1) {}
        else {allow = false;}
    }
    if (allow) {
        if (pDist(circleX,circleY,xx,yy)<radius) {
            return true;
        }
        else {
            return false;
        }
    } else {
        return false;
    }
}

function pDist(x1,y1,x2,y2) {
    var xd = x2-x1;
    var yd = y2-y1;
    return Math.sqrt(xd*xd+yd*yd);
}

解决方案

You can express the line as two relations:

x = x1 + k * (x2 - x1) = x1 + k * dx
y = y1 + k * (y2 - y1) = y1 + k * dy

with 0 < k < 1. A point on the circle satisfies the equation:

(x - Cx)² + (y - Cy)² = r²

Replace x and y by the line equations and you'll get a quadratic equation:

a*k² + b*k + c = 0

a = dx² + dy²
b = 2*dx*(x1 - Cx) + s*dy*(y1 - Cy)
c = (x1 - Cx)² + (y1 - Cy)² - r²

Solve that and if any of the two possible solutions for k lies in the range between 0 and 1, you have a hit. This method checks real intersections and misses the case where the line is entirely contained in the circle, so an additional check whether the line's end points lie within the circle is necessary.

Here's the code:

function collision_circle_line(Cx, Cy, r, x1, y1, x2, y2) {
    var dx = x2 - x1;
    var dy = y2 - y1;

    var sx = x1 - Cx;
    var sy = y1 - Cy;

    var tx = x2 - Cx;
    var ty = y2 - Cy;

    if (tx*tx + ty*ty < r*r) return true;

    var c = sx*sx + sy*sy - r*r;
    if (c < 0) return true;

    var b = 2 * (dx * sx + dy * sy);
    var a = dx*dx + dy*dy;

    if (Math.abs(a) < 1.0e-12) return false;

    var discr = b*b - 4*a*c;
    if (discr < 0) return false;
    discr = Math.sqrt(discr);

    var k1 = (-b - discr) / (2 * a);
    if (k1 >= 0 && k1 <= 1) return true;

    var k2 = (-b + discr) / (2 * a);
    if (k2 >= 0 && k2 <= 1) return true;

    return false;
}

这篇关于线圆相交的垂直线和水平线的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆