我正在尝试编写一种方法来计算两个圆是否重叠.我想出了以下内容,我只是想知道是否有可能进一步优化.
private static boolean isCollision(Point2D p1, float r1, Point2D p2, float r2) { float a,dx, dy; a = (r1+r2) * (r1+r2); dx = (float) (p1.getX() - p2.getX()); dy = (float) (p1.getY() - p2.getY()); if (a > (dx*dx) + (dy*dy)) { return true; } return false; }
Zarkonnen.. 21
嗯.就数学而言,这看起来非常好.关于如何使Java更快更简洁的一些小问题:
如果您使用双精度而不是浮点数作为半径,则不必将双精度投射到浮点数.
如果您特别要求Point2D.Double参数,则可以使用其x和y公共字段而不是使用getter.
另外,为什么if (foo) { return true; } else { return false; }?
Just do return foo;
!
一个改进的版本,然后:
private static boolean isCollision(Point2D.Double p1, double r1, Point2D.Double p2, double r2) { final double a = r1 + r2; final double dx = p1.x - p2.x; final double dy = p1.y - p2.y; return a * a > (dx * dx + dy * dy); }
(请注意,如果您的代码完全基于浮动,则可以使用Point2D.Float
和float
s 执行相同的操作.)
嗯.就数学而言,这看起来非常好.关于如何使Java更快更简洁的一些小问题:
如果您使用双精度而不是浮点数作为半径,则不必将双精度投射到浮点数.
如果您特别要求Point2D.Double参数,则可以使用其x和y公共字段而不是使用getter.
另外,为什么if (foo) { return true; } else { return false; }?
Just do return foo;
!
一个改进的版本,然后:
private static boolean isCollision(Point2D.Double p1, double r1, Point2D.Double p2, double r2) { final double a = r1 + r2; final double dx = p1.x - p2.x; final double dy = p1.y - p2.y; return a * a > (dx * dx + dy * dy); }
(请注意,如果您的代码完全基于浮动,则可以使用Point2D.Float
和float
s 执行相同的操作.)
重叠还是交叉?
如果相交,请不要忘记圆圈不相交的情况,因为它们在彼此内部.
如果它重叠,我真的不知道你如何进一步优化; 你将点距离与半径之和进行比较,使用距离平方来避免取平方根.似乎没有任何脂肪可以修剪.
你真的需要迎合任何可能的Point2D实现吗?如果您不必,它将保存虚拟呼叫:
private static boolean isCollisionFloat (Point2D.Float p1, float r1, Point2D.Float p2, float r2) { final float r = r1+r2; final float dx = p1.x - p2.x; final float dy = p1.y - p2.y; return (r*r) > (dx*dx) + (dy*dy); }
testing 1000x1000 points: Doing nothing took 6 ms Doing isCollision passing Point2D.Float took 128 ms Doing isCollision passing Point2D.Double took 127 ms Doing isCollisionFloat took 71 ms Doing isCollisionDouble took 72 ms
如果可以,请选择其中一种,而不是同时兼顾两者.
perf问题的问题在于你真的必须测量效果,当时有人发布了相同的答案作为不支持的意见.