【问题标题】:I need to calculate a point on an arc based on a point not at its center我需要根据不在其中心的点计算弧上的点
【发布时间】:2016-08-25 13:42:27
【问题描述】:

我知道如何在给定半径和距离的情况下计算圆上点的 X/Y 位置。这不是我需要计算的。

我需要计算一个圆上的 X/Y 位置,但基于不是该圆心的点和角度。

已知值为:

  • 圆心的 X/Y 坐标。
  • 圆的半径。
  • 第二个点的 X/Y 坐标,已知角度的中心点。
  • 与第二点的角度。

我正在做的是计算曲线刻度上的线以用于仪表显示。线条需要与仪表的指针平行,但其轴心点可能与刻度圆弧的半径点不同。

它需要使用 Javascript 并用于在 HTML5 画布对象上绘图。

这里有一张图片可以帮助解释我在寻找什么:


(来源:sloansweb.com

参考图纸,CP1永远在CP2所在圆的内半径内。

编辑:我已更新绘图以简化它,仅显示围绕 CP2 的一个圆圈。请注意,相对于 CP2 的交叉点的角度是未知的。此外,相对于 CP1 到交叉点的距离是未知的。

提前致谢!!

【问题讨论】:

    标签: javascript math geometry trigonometry


    【解决方案1】:

    也许通过这种方式是可能的:如果你有圆的半径和圆心,你可以为此写出你的方程(比如 Cr(x) )。现在,如果你只有 CP2 和 A1_angle,你可以写出从 CP2 开始的直线方程,角度系数=A1_angle,这样你就可以在几何上截取“Crossing Point 1”和“Crossing Point 2”某处,使用直线方程或 Cr(x) 找出坐标。
    更实用:
    1)Cr(x) := (x-CP2.x)^2+(y-CP2.y)^2=radius1^2 其中 x,y, 变量和 CP2.x, CP2.y 是 CP2 的 x 坐标和 y 坐标。
    2)然后你必须找出从CP1开始并以斜率=A1继续的线的功能是什么:y=tan(A1)*x+bb = CP1.y-tan(A1)*CP1.x
    3) 让这两个函数相互拦截,以求出它们共有多少个点(不超过 2 个!):
    { Cr(x) AND y=tan(A1)*x+b } 。在这里你必须替换 y 变量(我认为这种方式比替换 x 变量更简单......你选择)并使方程等于 0。
    ((x-CP2.x)^2+(tan(A1)*x+b-CP2.y)^2 - radius1^2=0
    如果你做了权利,你必须在末端有 2 个点(因为线与圆相交两次),没什么好说的,只是选择权利并做你需要的。
    radius2 也是如此第二个圆,只需获取半径为 2 的圆的 Cr(x) 函数(线保持不变!)并找出坐标 :)
    我知道这可能比绘制画布所需的更数学和复杂,但这是我最初想到的。
    希望我很清楚:)

    编辑:
    在你的 javascript 代码中试试这个,希望它能正常工作:

    function GetPoints(Center_x, Center_y, Radius, CP1_x, CP1_y, angle){
        var a=Center_x;
        var b=Center_y;
        var c=CP1_x;
        var d=CP1_y;
        var TAN=Math.tan((2*Math.PI*angle) / 360);
    
        var res_x= [];
        var res_y= [];
    
        if(angle!=90 && angle!=180 && angle!=270 && angle!=360){
        res_x[0]= ((2*TAN*TAN*c+2*b*TAN-2*d*TAN+2*a)  + 
                Math.sqrt( 
                    -2*c*TAN*TAN-2*b*TAN+2*d*TAN-2*a - (4*TAN*TAN + 4)*(c*c*TAN*TAN-2*c*d*TAN+2*c*b*TAN-2*d*b+d*d+b*b-Radius*Radius+a*a)
                    )
                ) / (2*TAN*TAN+2);
    
        res_x[1]= ((2*TAN*TAN*c+2*b*TAN-2*d*TAN+2*a)  - 
                Math.sqrt( 
                    -2*c*TAN*TAN-2*b*TAN+2*d*TAN-2*a - 4*(TAN*TAN + 1)*(c*c*TAN*TAN-2*c*d*TAN+2*c*b*TAN-2*d*b+d*d+b*b-Radius*Radius+a*a)
                    )
                ) / (2*TAN*TAN+2);
    
        res_y[0]= TAN*res_x[0]+d-TAN*c;
        res_y[1]= TAN*res_x[1]+d-TAN*c;
    
    }
    else{
        res_y[0]= b +  
        Math.sqrt(
            -c*c+2*c*a-a*a+Radius*Radius
            );
    
        res_y[1]= b - 
        Math.sqrt(
            -c*c+2*c*a-a*a+Radius*Radius
            );
        }
        res_x[0]=res_x[1]=c;
    
    
        console.log("x0= "+res_x[0]+ "\nx1= "+res_x[1]+"\n");
        console.log("y0= "+res_y[0]+ "\ny1= "+res_y[1]+"\n");
    
    
    }
    


    那些 console.logs 在调试时应该很有用,所以我留下了它们。
    角度以度为单位,我已经实现了到 grads 的隐式切换,并以默认方式计算(关于 grads)。我不知道你的A1 角度有多少变化,所以我更喜欢这种方式,但我认为进行这种改变并不是很复杂。在 res_x[] 中存储了交叉点的 x 值,在 res_y[] 中存储了 y 值。我看到最终它可以做出一些由我认为的数学引起的近似值。还有一件事,你看到的函数没有处理异常。

    2 编辑:
    我想出了第二个解决方案。要了解所有三角形,我们至少需要 3 个数据。我们已经有了三角形 ABC 的 3 个数据!

    我们知道 A 和 B 在哪里,所以他们的距离,我们知道 alpha 角,所以 B 的所有角度 (90° + alpha),我们知道 AC。当然,我们知道 2 个边和一个角度……也许我们不需要其他任何东西。
    从理论上,我们知道在任意三角形中,对角的一侧超过对角的正弦对每一边和每个角都是常数。在这种情况下,我们知道 AC(它是半径)和 B_angle(它是 90 度加上你的值 alpha),所以 AC/sin(alpha+pi/2) 等于 AB/sin(C_angle) 再次等于 BC/sin(A_angle)。 做一些方程式:

    AC/sin(alpha+90°)=AB/sin(C_angle)
    

    所以

    sin(C_angle)=AB*sin(alpha+90°)/AC
    

    C_angle= arcsin ( AB*sin(alpha+90°)/AC )
    

    现在,如果我们知道 C_angle 和 alpha,我们可以计算 A_angle,因为三角形中所有 3 个角的总和为 180°。所以 A_angle=180°-alpha-C_angle。 现在我们知道了所有的角度和两条边。对于最后一个,我们可以应用与上面相同的公式:

    BC/sin(A_angle)=AC/sin(alpha+90°)=AB/sin(C_angle)
    

    选择您喜欢的并检索 BC。 现在我们有:

    AC=radius;
    AB= known with coordinates;
    BC= retrieved from previous relations
    B_angle= alpha + 90°
    A_angle and C_angle= retrieved from previous relations as for BC.
    

    我们现在什么都知道了,尤其是 BC。 为了通过知道 C 点到 B 的距离来检索 C 点的坐标,我们可以做一个技巧:
    制作从 B 开始并以 tan(alpha) 为斜率的 line(x) 方程,知道 B 到 C 的距离,我们可以通过以下方式检索 C 的 X/Y 坐标:
    C.x= BC*cos(alpha)
    C.y= line(x+BC*cos(alpha)) 你去吧。
    我发现这个过程比我建议的另一个过程简单得多,也许用 JS 编码会容易得多。 这一直有效,直到 B 点位于 A 的同一轴上。如果 B 点应该移动,B_angle 可能会发生很大变化,而不是添加 90°,您应该添加 A 和 B 之间的角度。

    【讨论】:

    • 注意作者的A1是角度,所以你的斜率是Tan(A1)
    • 感谢 pippo,但角度是相对于 CP1。您的解决方案可能有效,但我无法弄清楚它如何转化为 JS 代码
    • 对不起,我错了。交叉点是沿着圆圈移动还是只是设置在某个地方?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多