计算多边形的面积
设多边形各顶点的坐标为:(x1, y1), (x2, y2), (x3, y3)……(xn, yn),则该多边形的面积为:
S
=
1
2
∑
n
=
1
∞
(
x
n
y
n
+
1
−
x
n
+
1
y
n
)
S
=
1
2
[
(
x
1
y
2
−
x
2
y
1
)
+
(
x
2
y
3
−
x
3
y
2
)
+
…
…
+
(
x
n
y
1
−
x
1
y
n
)
]
S=\frac 12 \sum_{n=1}^{\infty} {(x_{n}y_{n+1}-x_{n+1}y_{n})} \\ S=\frac 12 [(x_1y_2-x_2y_1)+(x_2y_3-x_3y_2)+……+(x_ny_1-x_1y_n)]
S=21n=1∑∞(xnyn+1−xn+1yn)S=21[(x1y2−x2y1)+(x2y3−x3y2)+……+(xny1−x1yn)]
多边形各顶点与原点相连,构成多个三角形,将所有三角形的面积相加或相减,得到的结果就是多边形的面积。
- 三角形的面积由两个向量的向量积的模计算得到: 1 2 ∣ ( x n y n + 1 − x n + 1 y n ) ∣ \frac 12 |(x_{n}y_{n+1}-x_{n+1}y_{n})| 21∣(xnyn+1−xn+1yn)∣
- 面积相加或相减由向量积的方向确定: 1 2 ( x n y n + 1 − x n + 1 y n ) \frac 12 (x_{n}y_{n+1}-x_{n+1}y_{n}) 21(xnyn+1−xn+1yn)
package Polygon;
import java.awt.*;
/**
* 计算多边形的面积
*/
public class PolygonArea {
public static void main(String[] args) {
Polygon polygon = new Polygon(new int[]{3,5,12,9,5}, new int[]{4,11,8,5,6}, 5);
// 计算多边形的面积
PolygonArea polygonArea = new PolygonArea();
System.out.println("多边形的面积:" + polygonArea.getArea(polygon));
}
/**
* 计算多边形的面积
*/
public double getArea(Polygon polygon) {
double Area = 0; // 多边形的面积
Integer Num = polygon.npoints; // 顶点个数
// 添加第一个顶点到末尾
polygon.addPoint(polygon.xpoints[0], polygon.ypoints[0]);
// 计算多边形的面积
for (int i = 0; i < Num; i++) {
Area += 0.5 * ((polygon.xpoints[i] * polygon.ypoints[i+1]) - (polygon.ypoints[i] * polygon.xpoints[i+1]));
}
return Math.abs(Area);
}
}
计算两个多边形相交部分的面积
给出多边形PolygonA和多边形PolygonB,求两个多边形相交部分的面积。具体步骤如下:
- 添加A位于B中的所有顶点:循环A的所有顶点,判断是否位于B中。
- 添加B位于A中的所有顶点:循环B的所有顶点,判断是否位于A中。
- 添加A与B每一条边的交点:判断边与边是否相交,相交则求交点。
- 对多边形的顶点按逆时针方向进行排序。
- 计算多边形InterPolygon的面积。
package Polygon;
import java.awt.*;
import java.awt.geom.Line2D;
import static java.lang.Math.max;
import static java.lang.Math.min;
/**
* 计算两个多边形相交部分的面积
*/
public class InterPolygonArea {
public static void main(String[] args) {
Polygon polygonA = new Polygon(new int[]{0,2,2,0}, new int[]{0,0,2,2}, 4);
Polygon polygonB = new Polygon(new int[]{1,3,3,1}, new int[]{0,0,1,1}, 4);
// 计算两个多边形相交部分的面积
InterPolygonArea interPolygonArea = new InterPolygonArea();
System.out.println("两个多边形相交部分的面积:" + interPolygonArea.getInterArea(polygonA, polygonB));
}
/**
* 计算两个多边形相交部分的面积
*/
public double getInterArea(Polygon polygon1, Polygon polygon2) {
Polygon InterPolygon = new Polygon(); // 两个多边形相交部分
Integer Num1 = polygon1.npoints; // 多边形A的顶点个数
Integer Num2 = polygon2.npoints; // 多边形B的顶点个数
// 添加A位于B中的所有顶点:循环A的所有顶点,判断是否位于B中
System.out.println("添加A位于B中的所有顶点:");
for (int i = 0; i < Num1; i++) {
if(polygon2.contains(polygon1.xpoints[i], polygon1.ypoints[i])) {
InterPolygon.addPoint(polygon1.xpoints[i], polygon1.ypoints[i]);
System.out.println("(" + polygon1.xpoints[i] + ", " + polygon1.ypoints[i] + ")");
}
}
// 添加B位于A中的所有顶点:循环B的所有顶点,判断是否位于A中
System.out.println("添加B位于A中的所有顶点:");
for (int i = 0; i < Num2; i++) {
if(polygon1.contains(polygon2.xpoints[i], polygon2.ypoints[i])) {
InterPolygon.addPoint(polygon2.xpoints[i], polygon2.ypoints[i]);
System.out.println("(" + polygon2.xpoints[i] + ", " + polygon2.ypoints[i] + ")");
}
}
// 添加第一个顶点到末尾
polygon1.addPoint(polygon1.xpoints[0], polygon1.ypoints[0]);
polygon2.addPoint(polygon2.xpoints[0], polygon2.ypoints[0]);
// 添加A与B每一条边的交点:判断边与边是否相交,相交则求交点
System.out.println("添加A与B每一条边的交点:");
boolean flag = false; // false为不相交,true为相交
for (int i = 0; i < Num1; i++) {
for (int j = 0; j < Num2; j++) {
// 判断多边形A的边(x1,y1)→(x2,y2)和多边形B的边(x3,y3)→(x4,y4)是否相交
double x1 = polygon1.xpoints[i], y1 = polygon1.ypoints[i];
double x2 = polygon1.xpoints[i+1], y2 = polygon1.ypoints[i+1];
double x3 = polygon2.xpoints[j], y3 = polygon2.ypoints[j];
double x4 = polygon2.xpoints[j+1], y4 = polygon2.ypoints[j+1];
// flag = Line2D.linesIntersect(x1, y1, x2, y2, x3, y3, x4, y4);
flag = isInterLines(x1, y1, x2, y2, x3, y3, x4, y4);
// 相交则求交点,并添加
if (flag) {
Point interSection = getInterSection(x1, y1, x2, y2, x3, y3, x4, y4);
InterPolygon.addPoint(interSection.x, interSection.y);
System.out.println("(" + interSection.x + ", " + interSection.y + ")");
}
}
}
System.out.println("两个多边形相交部分的顶点(排序前):");
for (int i = 0; i < InterPolygon.npoints; i++) {
System.out.println("(" + InterPolygon.xpoints[i] + ", " + InterPolygon.ypoints[i] + ")");
}
// 对多边形的顶点按逆时针方向进行排序
PolygonSort polygonSort = new PolygonSort();
Polygon interPolygon = polygonSort.PolygonClockwiseSort(InterPolygon);
System.out.println("对多边形的顶点按逆时针方向进行排序:");
for (int i = 0; i < interPolygon.npoints; i++) {
System.out.println("(" + interPolygon.xpoints[i] + ", " + interPolygon.ypoints[i] + ")");
}
// 计算两个多边形相交部分的面积
PolygonArea polygonArea = new PolygonArea();
return polygonArea.getArea(interPolygon);
}
/**
* 判断两个线段是否相交
*/
public boolean isInterLines(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4) {
// 快速排斥实验:判断两条线段在x以及y坐标的投影是否有重合
if (max(x3, x4) < min(x1, x2) || max(x1, x2) < min(x3, x4)
|| max(y3, y4) < min(y1, y2) || max(y1, y2) < min(y3, y4)){
return false;
}
else {
// 跨立实验(不考虑线段端点作为交点):点A和点B分别在线段CD两侧,点C和点D分别在线段AB两侧
// 满足条件:(A-B)×(B−D)∗(A−B)×(C−B)<0 && (A−D)×(C−D)∗(B−D)×(C−D)<0
if (((x2-x1)*(y4-y2) - (x4-x2)*(y2-y1)) * ((x2-x1)*(y3-y2) - (x3-x2)*(y2-y1)) < 0
&& ((x4-x1)*(y4-y3) - (x4-x3)*(y4-y1)) * ((x4-x2)*(y4-y3) - (x4-x3)*(y4-y2)) < 0) {
return true;
}
return false;
}
}
/**
* 计算两个相交线段的交点
*/
public Point getInterSection(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4) {
double b1 = (y2 - y1) * x1 + (x1 - x2) * y1;
double b2 = (y4 - y3) * x3 + (x3 - x4) * y3;
double D = (x2 - x1) * (y4 - y3) - (x4 - x3) * (y2 - y1);
double D1 = b2 * (x2 - x1) - b1 * (x4 - x3);
double D2 = b2 * (y2 - y1) - b1 * (y4 - y3);
Point point = new Point();
point.setLocation(D1 / D, D2 / D);
return point;
}
}
参考:
- https://blog.csdn.net/sfw673306004/article/details/103801376