但是,AngleBetweenLines存在问题.结果总是积极的.我需要检测正角度和负角度,因此如果一条线在另一条线"高于"或"低于"15度,则形状显然看起来不同.
我的配置是一条线保持静止,而另一条线旋转,我需要通过将它与固定线进行比较来了解它旋转的方向.
编辑:为了回应下面swestrup的评论,情况实际上是我有一条线,我记录了它的起始位置.然后该线从其起始位置旋转,我需要计算从其起始位置到当前位置的角度.例如,如果它顺时针旋转,则为正旋转; 如果逆时针,则为负.(或相反亦然.)
如何改进算法,使其根据线的位置返回正负角度?
Jaa*_*nus 20
这是brainjam建议的实现.(它符合我的约束条件,线条之间的差异保证足够小,不需要对任何东西进行标准化.)
CGFloat angleBetweenLinesInRad(CGPoint line1Start, CGPoint line1End, CGPoint line2Start, CGPoint line2End) {
CGFloat a = line1End.x - line1Start.x;
CGFloat b = line1End.y - line1Start.y;
CGFloat c = line2End.x - line2Start.x;
CGFloat d = line2End.y - line2Start.y;
CGFloat atanA = atan2(a, b);
CGFloat atanB = atan2(c, d);
return atanA - atanB;
}
Run Code Online (Sandbox Code Playgroud)
我喜欢它简洁.矢量版本会更简洁吗?
这是涉及2D矢量的简单问题.两个矢量之间的角度的正弦值与两个矢量之间的交叉积相关.并且"上方"或"下方"由交叉乘积产生的向量的符号确定:如果跨越两个向量A和B,并且产生的交叉积为正,则A"低于"B; 如果它是否定的,A是"高于"B.有关详细信息,请参阅Mathworld.
以下是我在Java中编写代码的方法:
package cruft;
import java.text.DecimalFormat;
import java.text.NumberFormat;
/**
* VectorUtils
* User: Michael
* Date: Apr 18, 2010
* Time: 4:12:45 PM
*/
public class VectorUtils
{
private static final int DEFAULT_DIMENSIONS = 3;
private static final NumberFormat DEFAULT_FORMAT = new DecimalFormat("0.###");
public static void main(String[] args)
{
double [] a = { 1.0, 0.0, 0.0 };
double [] b = { 0.0, 1.0, 0.0 };
double [] c = VectorUtils.crossProduct(a, b);
System.out.println(VectorUtils.toString(c));
}
public static double [] crossProduct(double [] a, double [] b)
{
assert ((a != null) && (a.length >= DEFAULT_DIMENSIONS ) && (b != null) && (b.length >= DEFAULT_DIMENSIONS));
double [] c = new double[DEFAULT_DIMENSIONS];
c[0] = +a[1]*b[2] - a[2]*b[1];
c[1] = +a[2]*b[0] - a[0]*b[2];
c[2] = +a[0]*b[1] - a[1]*b[0];
return c;
}
public static String toString(double [] a)
{
StringBuilder builder = new StringBuilder(128);
builder.append("{ ");
for (double c : a)
{
builder.append(DEFAULT_FORMAT.format(c)).append(' ');
}
builder.append("}");
return builder.toString();
}
}
Run Code Online (Sandbox Code Playgroud)
检查第3个组件的标志.如果是正数,A是"低于"B; 如果它是负的,A是"高于"B - 只要两个矢量位于y轴右侧的两个象限中.显然,如果它们都位于y轴左侧的两个象限中,则反之亦然.
你需要考虑你的"上方"和"下方"的直观概念.如果A在第一象限(0 <=θ<= 90)且B在第二象限(90 <=θ<= 180),该怎么办?"上方"和"下方"失去了意义.
然后该线从其起始位置旋转,我需要计算从其起始位置到当前位置的角度.例如,如果它顺时针旋转,则为正旋转; 如果逆时针,则为负.(或相反亦然.)
这正是跨产品的用途.第三个分量的符号对于逆时针是正的而对于顺时针是负的(当你向下看旋转的平面时).