C# 从地平线获取直线的角度
我想知道如何得到a-B线与水平轴X的夹角,其他问题只在两条线之间。我知道我总是可以画第二条线A-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),因此只需
编辑:我很确定我没有做过早的优化。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所说的,在资源有限的情况下,性能非常重要,我只是想让他意识到这种优化的可能性,它可能是问题的解决方案,也可能不是,因为他没有说明角度的典型或最坏情况的大小。