计算通过中心的圆和线的交点

时间:2014-01-17 17:14:58

标签: javascript geometry

如何获得直线和圆的交点..我收到了很多关于这个主题的信息,但是我的要求不匹配..

我有一条线,其一个终点位于圆的原点......另一端位于圆的外面..现在我需要这条线和圆的交点...

我试图使用以下公式从圆圈外部找到最近的边缘点,但无法破解它 -

closestCirclePoint = function(px, py, x, y, ray){
    var tg = (x += ray, y += ray, 0);
    return function(x, y, x0, y0){return Math.sqrt((x -= x0) * x + (y -= y0) * y);}(px, py, x, y) > ray ?
        {x: Math.cos(tg = Math.atan2(py - y, px - x)) * ray + x, y: Math.sin(tg) * ray + y}
        //{x: (px - x) / (length / ray) + x, y: (py - y) / (length / ray) + y}
        : {x: px, y: py};
};

任何方式来解决这个问题.. ?? 提前谢谢!

3 个答案:

答案 0 :(得分:3)

Lindenhovius的JavaScript版本答案如下:

/**
 * Finds the intersection between a circles border 
 * and a line from the origin to the otherLineEndPoint.
 * @param  {Vector} origin            - center of the circle and start of the line
 * @param  {number} radius            - radius of the circle
 * @param  {Vector} otherLineEndPoint - end of the line
 * @return {Vector}                   - point of the intersection
 */
function findIntersect (origin, radius, otherLineEndPoint) {
    var v = otherLineEndPoint.subtract(origin);
    var lineLength = v.length();    
    if (lineLength === 0) throw new Error("Length has to be positive");
    v = v.normalize();
    return origin.add(v.multiplyScalar(radius)); 
}

但是你需要实现向量"类" *你自己:

function Vector (x, y) {
    this.x = x || 0;
    this.y = y || 0;
}

Vector.prototype.add = function (vector) {
    return new Vector(this.x + vector.x, this.y + vector.y);
};

Vector.prototype.subtract = function (vector) {
    return new Vector(this.x - vector.x, this.y - vector.y);
};

Vector.prototype.multiply = function (vector) {
    return new Vector(this.x * vector.x, this.y * vector.y);
};

Vector.prototype.multiplyScalar = function (scalar) {
    return new Vector(this.x * scalar, this.y * scalar);
};

Vector.prototype.divide = function (vector) {
    return new Vector(this.x / vector.x, this.y / vector.y);
};

Vector.prototype.divideScalar = function (scalar) {
    return new Vector(this.x / scalar, this.y / scalar);
};

Vector.prototype.length = function () {
    return Math.sqrt(Math.pow(this.x, 2) + Math.pow(this.y, 2));
};

Vector.prototype.normalize = function () {
    return this.divideScalar(this.length());
};

* JavaScript中没有真正的类 - 只有constructor functionsprototypes,事情随着ES6而改变,但这是另一个话题。

答案 1 :(得分:2)

伪代码的简单解决方案:

Point findIntersect (Point origin, double radius, Point otherLineEndPoint) {
    Vector v = otherLineEndPoint - origin;
    double lineLength = v.length();    
    assert (!Math.isZero(lineLength));  //assert line has positive length
    v = v / lineLength;   //normalize v
    return origin + v * radius; 
}

答案 2 :(得分:0)

作为一个打字稿类,但是不知道如何操作符重载:

class Vector {
    constructor(public x = 0, public y = 0) {}
    add = (vector: Vector) => new Vector(this.x + vector.x, this.y + vector.y)
    subtract = (vector: Vector) => new Vector(this.x - vector.x, this.y - vector.y)
    multiply = (vector: Vector) => new Vector(this.x * vector.x, this.y * vector.y)
    multiplyScalar = (scalar: number) => new Vector(this.x * scalar, this.y * scalar)
    divide = (vector: Vector) => new Vector(this.x / vector.x, this.y / vector.y)
    divideScalar = (scalar: number): Vector => new Vector(this.x / scalar, this.y / scalar)
    length = (): number => Math.sqrt(Math.pow(this.x, 2) + Math.pow(this.y, 2))
    normalize = () => this.divideScalar(this.length())
    findIntersect(o: Vector, p: Vector, radius: number) {
        let v = p.subtract(o)
        const lineLength = v.length()
        if (lineLength === 0) throw new Error('Length must be positive')
        v = v.normalize()
        return o.add(v.multiplyScalar(radius))
    }
}