我想在Java / Android中开发一种财富之轮。当用户触摸屏幕时,我检测到了移动,并且对于每个变化,我计算旧压力和最新压力之间的角度(函数onScroll)。我有一个问题,因为我不记得我如何计算3点之间的角度...
我开发了3个函数,但每个函数给出了不同的结果:
public class Test {
public static void main(String[] args) {
Test test = new Test();
Point center = new Point(2.26f, 2.26f);
Point current = new Point(2.54f, 3.64f);
Point previous = new Point(2.25f, 3.73f);
System.out.println("1) Angle is "
+ test.function1(center, current, previous));
System.out.println("2) Angle is "
+ test.function2(center, current, previous));
System.out.println("3) Angle is "
+ test.function3(center, current, previous));
System.out.println("################################");
center = new Point(2.26f, 2.26f);
previous = new Point(3.29f, 1.04f);
current = new Point(0.98f, 2.25f);
System.out.println("1) Angle is "
+ test.function1(center, current, previous));
System.out.println("2) Angle is "
+ test.function2(center, current, previous));
System.out.println("3) Angle is "
+ test.function3(center, current, previous));
System.out.println("################################");
center = new Point(226.0f, 226.0f);
previous = new Point(225.21994f, 373.3158f);
current = new Point(254.31085f, 364.05264f);
System.out.println("1) Angle is "
+ test.function1(center, current, previous));
System.out.println("2) Angle is "
+ test.function2(center, current, previous));
System.out.println("3) Angle is "
+ test.function3(center, current, previous));
System.out.println("################################");
}
public double function1(Point center, Point current, Point previous) {
double ang1 = Math.atan((previous.getdY() - center.getdY())
/ (previous.getdX() - center.getdX()));
double ang2 = Math.atan((current.getdY() - center.getdY())
/ (current.getdX() - center.getdX()));
double rslt = ang1 - ang2;
return Math.toDegrees(rslt) * -1;
}
private double function2(Point center, Point current, Point previous) {
float dx = current.getdX() - center.getdX();
float dy = current.getdY() - center.getdY();
double a = Math.atan2(dy, dx);
float dpx = previous.getdX() - center.getdX();
float dpy = previous.getdY() - center.getdY();
double b = Math.atan2(dpy, dpx);
double diff = a - b;
double degres = Math.toDegrees(diff);
return degres;
}
public double function3(Point center, Point current, Point previous) {
Point p1 = new Point(current.getdX() - center.getdX(), current.getdY()
- center.getdY());
Point p2 = new Point(previous.getdX() - center.getdX(),
previous.getdY() - previous.getdY());
double angle = Math.atan2(p1.getdY() - p2.getdY(),
p1.getdX() - p2.getdX());
return Math.toDegrees(angle);
}
}
我在网上发现了这个功能,但我不知道哪个是最好的。
你能帮助我吗?
答案 0 :(得分:9)
private double angleBetween(Point center, Point current, Point previous) {
return Math.toDegrees(Math.atan2(current.x - center.x,current.y - center.y)-
Math.atan2(previous.x- center.x,previous.y- center.y));
}
这首先计算中心 - >当前和中心 - >先前与x轴的角度并取2之间的差值
这类似于function2
答案 1 :(得分:1)
看看这里:http://www.euclideanspace.com/maths/algebra/vectors/angleBetween/index.htm
就function2
:
private double function2(Point center, Point current, Point previous) {
float v1x = current.getdX() - center.getdX();
float v1y = current.getdY() - center.getdY();
//need to normalize:
float l1 = Math.sqrt(v1x * v1x + v1y * v1y);
v1x /= l1;
v1y /= l1;
float v2x = previous.getdX() - center.getdX();
float v2y = previous.getdY() - center.getdY();
//need to normalize:
float l2 = Math.sqrt(v2x * v2x + v2y * v2y);
v2x /= l2;
v2y /= l2;
double rad = Math.acos( v1x * v2x + v1y * v2y );
double degres = Math.toDegrees(rad);
return degres;
}
修改:对于签名值,请使用Math.atan2(...)
。
从链接页面引用:
如果我们想要一个+或 - 值来指示哪个向量在前面,那么我们可能需要使用atan2函数(如本页所述)。使用:
角度2相对于1 = atan2(v2.y,v2.x) - atan2(v1.y,v1.x)
因此,将double rad = Math.acos( v1x * v2x + v1y * v2y );
替换为double rad = Math.atan2( v2y,v2x) - Math.atan2(v1y,v1x);
,您应该没问题。
答案 2 :(得分:0)
从点中创建两个向量并使用dot product。