Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/266.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 从地平线获取直线的角度_C#_Math_Geometry_Drawing - Fatal编程技术网

C# 从地平线获取直线的角度

C# 从地平线获取直线的角度,c#,math,geometry,drawing,C#,Math,Geometry,Drawing,我想知道如何得到a-B线与水平轴X的夹角,其他问题只在两条线之间。我知道我总是可以画第二条线A-C并计算,但我想知道是否有更快的方法 编辑:我很确定我没有做过早的优化。x轴实际上是一条带等式的直线 y=0 因此,您可以使用已有的解决方案。您可以使用atan来实现这一点 angle = atan((By-Ay)/(Bx-Ax)) 如果 角度小, 你可以忍受微小的误差,并且 可以使用弧度而不是度表示的角度 然后有一个快速的解决方案:在这些条件下,您可以假设tan(a)=a=atan(a),因此只需

我想知道如何得到a-B线与水平轴X的夹角,其他问题只在两条线之间。我知道我总是可以画第二条线A-C并计算,但我想知道是否有更快的方法


编辑:我很确定我没有做过早的优化。

x轴实际上是一条带等式的直线

y=0


因此,您可以使用已有的解决方案。

您可以使用
atan
来实现这一点

angle = atan((By-Ay)/(Bx-Ax))
如果

  • 角度小,
  • 你可以忍受微小的误差,并且
  • 可以使用弧度而不是度表示的角度

  • 然后有一个快速的解决方案:在这些条件下,您可以假设tan(a)=a=atan(a),因此只需省略atan()调用。

    如果行的形式为
    [r\u x,r\u y]
    ,则您也可以使用反余弦,其中
    r\u x
    是x中的更改,
    r\u y
    是y中的更改

    angle = arccos( r_x/( r_x*r_x + r_y*r_y ) )
    

    它有点不透明,但基本上是点积定律:

    angle = arccos (r . v)
    
    其中
    r
    v
    都是单位向量(长度为1的向量)。在我们的例子中,
    v
    是向量
    [1,0]
    ,r是

    [r_x,r_y] / (r_x^2+r_y^2)
    
    以使其成为单位向量。

    专用双角度(int-x1,int-y1,int-x2,int-y2)
    
        private double Angulo(int x1, int y1, int x2, int y2)
        {
            double degrees;
    
            // Avoid divide by zero run values.
            if (x2 - x1 == 0)
            {
                if (y2 > y1)
                    degrees = 90;
                else
                    degrees = 270;
            }
            else
            {
                // Calculate angle from offset.
                double riseoverrun = (double)(y2 - y1) / (double)(x2 - x1);
                double radians = Math.Atan(riseoverrun);
                degrees = radians * ((double)180 / Math.PI);
    
                // Handle quadrant specific transformations.       
                if ((x2 - x1) < 0 || (y2 - y1) < 0)
                    degrees += 180;
                if ((x2 - x1) > 0 && (y2 - y1) < 0)
                    degrees -= 180;
                if (degrees < 0)
                    degrees += 360;
            }
            return degrees;
        }
    
    { 双学位; //避免除以零运行值。 如果(x2-x1==0) { 如果(y2>y1) 度=90度; 其他的 度=270度; } 其他的 { //从偏移量计算角度。 双上升管超限=(双)(y2-y1)/(双)(x2-x1); 双弧度=Math.Atan(上升溢出); 度=弧度*((双)180/数学π); //处理特定于象限的变换。 如果((x2-x1)<0 | |(y2-y1)<0) 度+=180; 如果((x2-x1)>0&(y2-y1)<0) 度数-=180; 如果(度<0) 度+=360度; } 返回度; }
    如果您需要所有四个象限,Atan2比Atan更合适

    public static int GetAngleBetweenPoints(PointF pt1, PointF pt2)
    {
        float dx = pt2.X - pt1.X;
        float dy = pt2.Y - pt1.Y;
    
        int deg = Convert.ToInt32(Math.Atan2(dy, dx) * (180 / Math.PI));
        if (deg < 0) { deg += 360; }
    
        return deg;
    }
    
    public static int GetAngleBetweenPoints(PointF pt1,PointF pt2)
    {
    浮点dx=pt2.X-pt1.X;
    浮动dy=pt2.Y-pt1.Y;
    int deg=转换为32(数学Atan2(dy,dx)*(180/数学PI));
    如果(deg<0){deg+=360;}
    返回度;
    }
    
    我一直在寻找更快(cpu更少)的方法,如果有的话。要警惕过早的优化。你分析过密码了吗?我不明白那些反对票。这是一个愚蠢的问题吗?或者说是冒犯?嗯…@VOX-发布你的分析结果。向自己证明你需要一个更快的解决方案。“想让它尽可能快”是问题所在。首先,你应该想让它发挥作用。然后,如果它不能令人满意地执行,您可以找出问题的原因并加以解决。我很确定这是一个合理的问题。答案很简单,很容易理解,没有理由不使用它。这种情况下,过早的优化不会使事情变得更难理解或更复杂。这实际上简化了事情。“tan(a)=a=atan(a)”呃……什么?@Bart van Heukelom:是的,正如我所写的,这不是精确的,但对于小角度来说是一个很好的近似值。例如。tan(0.1)=0.1003,tan(0.2)=0.203,因此对于该范围内的角度,如果不需要绝对精度,可以节省一些计算工作量。是的,这似乎是真的。但是,一旦角度大于10度,误差就会变得太大,我认为如果你处理的是小角度,你通常都需要最高的精度。@Bart:正如OP所说的,在资源有限的情况下,性能非常重要,我只是想让他意识到这种优化的可能性,它可能是问题的解决方案,也可能不是,因为他没有说明角度的典型或最坏情况的大小。