核心概念
坐标系
- 笛卡尔坐标系:点用
(x, y)
表示 - 极坐标系:点用
(r, θ)
表示(r
=距离,θ
=角度)
- 笛卡尔坐标系:点用
角度与弧度
- Java 的
Math
类使用弧度制(Radians) - 转换公式:
double radians = Math.toRadians(degrees); // 角度 → 弧度 double degrees = Math.toDegrees(radians); // 弧度 → 角度
- Java 的
操作步骤详解
1. 距离计算
两点间欧氏距离
double distance(double x1, double y1, double x2, double y2) { double dx = x2 - x1; double dy = y2 - y1; return Math.sqrt(dx * dx + dy * dy); // 或 Math.hypot(dx, dy) }
点到直线的距离
直线方程:Ax + By + C = 0
double pointToLineDistance(double x, double y, double A, double B, double C) { return Math.abs(A * x + B * y + C) / Math.sqrt(A * A + B * B); }
2. 角度计算
向量夹角(0°~360°)
double angleBetweenPoints(double x1, double y1, double x2, double y2) { double dx = x2 - x1; double dy = y2 - y1; double angleRad = Math.atan2(dy, dx); // [-π, π] double angleDeg = Math.toDegrees(angleRad); return (angleDeg < 0) ? angleDeg + 360 : angleDeg; // 转 [0°, 360°) }
两向量夹角(锐角/钝角)
double angleBetweenVectors(double ux, double uy, double vx, double vy) { double dot = ux * vx + uy * vy; double magU = Math.hypot(ux, uy); double magV = Math.hypot(vx, vy); return Math.toDegrees(Math.acos(dot / (magU * magV))); }
3. 坐标转换
笛卡尔坐标 → 极坐标
double[] toPolar(double x, double y) { double r = Math.hypot(x, y); double theta = Math.toDegrees(Math.atan2(y, x)); return new double[]{r, theta}; }
极坐标 → 笛卡尔坐标
double[] toCartesian(double r, double theta) { double rad = Math.toRadians(theta); double x = r * Math.cos(rad); double y = r * Math.sin(rad); return new double[]{x, y}; }
点绕原点旋转
double[] rotatePoint(double x, double y, double angleDeg) { double rad = Math.toRadians(angleDeg); double cos = Math.cos(rad); double sin = Math.sin(rad); double newX = x * cos - y * sin; double newY = x * sin + y * cos; return new double[]{newX, newY}; }
点绕任意点旋转
double[] rotateAroundPoint(double x, double y, double cx, double cy, double angleDeg) { // 平移到旋转中心 double translatedX = x - cx; double translatedY = y - cy; // 旋转 double[] rotated = rotatePoint(translatedX, translatedY, angleDeg); // 平移回原坐标系 return new double[]{ rotated[0] + cx, rotated[1] + cy }; }
常见错误与解决方案
角度/弧度混淆
- 错误:直接使用角度调用
Math.sin(30)
(应为弧度) - 修复:
double sinValue = Math.sin(Math.toRadians(30));
- 错误:直接使用角度调用
浮点数精度问题
- 错误:
if (distance == 0)
(浮点数不能直接比较) - 修复:
if (Math.abs(distance) < 1e-6) // 使用误差容限
- 错误:
象限处理错误
- 错误:用
Math.atan(dy/dx)
计算角度(丢失象限信息) - 修复:使用
Math.atan2(dy, dx)
自动处理象限。
- 错误:用
注意事项
坐标系方向
- 屏幕坐标系中 Y 轴向下为正,数学坐标系中 Y 轴向上为正,需注意转换。
性能敏感场景
- 避免重复计算三角函数:
// 低效 for (int i = 0; i < n; i++) { x = r * Math.cos(Math.toRadians(angle)); } // 高效 double rad = Math.toRadians(angle); double cos = Math.cos(rad); for (int i = 0; i < n; i++) { x = r * cos; }
- 避免重复计算三角函数:
大数计算溢出
- 使用
Math.hypot(x, y)
替代Math.sqrt(x*x + y*y)
避免中间结果溢出。
- 使用
使用技巧
标准化向量
double[] normalize(double x, double y) { double mag = Math.hypot(x, y); return new double[]{x / mag, y / mag}; // 单位向量 }
角度差值(最小旋转角)
double angleDiff(double a, double b) { double diff = (b - a + 360) % 360; return diff > 180 ? diff - 360 : diff; }
使用
Point2D
类简化代码import java.awt.geom.Point2D; Point2D p1 = new Point2D.Double(3, 4); double dist = p1.distance(0, 0); // 计算到原点的距离
最佳实践与性能优化
减少对象创建
- 在循环中避免创建新对象(如
new Point2D
),改用基本类型变量。
- 在循环中避免创建新对象(如
查表法优化三角函数
- 对固定角度步长(如游戏开发):
double[] cosTable = new double[360]; for (int deg = 0; deg < 360; deg++) { cosTable[deg] = Math.cos(Math.toRadians(deg)); }
- 对固定角度步长(如游戏开发):
空间换时间
- 预计算常用值(如
Math.PI/180
):static final double DEG_TO_RAD = Math.PI / 180.0;
- 预计算常用值(如
第三方库
- 复杂场景使用专业库:
- Apache Commons Geometry:提供向量、旋转等高级功能。
- JTS Topology Suite:处理地理空间计算。
- 复杂场景使用专业库:
总结示例
// 计算两点距离与角度
Point2D p1 = new Point2D.Double(1, 1);
Point2D p2 = new Point2D.Double(4, 5);
double dist = p1.distance(p2); // 5.0
double angle = Math.toDegrees(Math.atan2(
p2.getY() - p1.getY(),
p2.getX() - p1.getX()
)); // 53.13°
// 将p2绕p1旋转90度
Point2D rotated = new Point2D.Double();
rotated.setLocation(
p1.getX() + (p2.getX()-p1.getX())*Math.cos(Math.PI/2)
- (p2.getY()-p1.getY())*Math.sin(Math.PI/2),
p1.getY() + (p2.getX()-p1.getX())*Math.sin(Math.PI/2)
+ (p2.getY()-p1.getY())*Math.cos(Math.PI/2)
); // 结果: (1, 5)
通过结合标准库函数与数学原理,可高效实现几何计算。重点注意坐标系转换、弧度角度转换和浮点精度处理,复杂场景推荐使用专业几何库。