我得到了一组顶点,其范围可以从3到20,并且我需要实现一种通用方法来计算由这些顶点定义的多边形的面积[这些顶点放置在2D平面中,定义的多边形不是自相交的]
多边形的顶点为:
N //Num sides Polygon
x1 y1
x2 y2
x3 y3
...
xn yn
请记住,我打算做的是对多边形triangulation:
在此处选择一个初始顶点,然后将多边形的其余部分分成三角形(扇形三角剖分),如下所示:
不规则三角形的面积可以像this那样计算:
val s : Double = (a+b+c)/2;
val area : Double = Math.sqrt(s*(s-a)*(s-b)*(s-c));
因此,我编写了以下代码来按照这种方法计算面积:
case class Point(val x: Double, val y: Double)
import scala.collection.mutable.ListBuffer
// Method to calculate length of side between to vertices
def distance(ori: Point, des: Point): Double = {
Math.sqrt(Math.pow(ori.x - des.x, 2) + Math.pow(ori.y - des.y, 2))
}
def main(args: Array[String]) {
// Number of sides in the Polynom
val sidesPoly = scala.io.StdIn.readLine().toInt
var listPoints = new ListBuffer[Point]()
// ListBuffer with the input sides
for(i <- 1 to sidesPoly){
val tuple = scala.io.StdIn.readLine().split(" ")
val newPoint = new Point(tuple(0).toDouble, tuple(1).toDouble)
listPoints += newPoint
}
// Iterating list in Fan mode to split the polygon into triangles
var area : Double = 0
for(i <- 1 to listPoints.size-2){
var triangle = new ListBuffer[Point]()
//We divide the polygon into triangles
val side1 = distance(listPoints(0),listPoints(i))
val side2 = distance(listPoints(i),listPoints(i+1))
val side3 = distance(listPoints(i+1),listPoints(0))
// Calculating the area of the triangle
val s = (side1+side2+side3)/2
val triangleArea = Math.sqrt(s*(s-side1)*(s-side2)*(s-side3))
// Adding the area of the triangle to the total Polygon Area
area += triangleArea
}
println(area)
}
我遇到的问题是该方法不适用于concave多边形。
对于凹面多边形,有谁知道比扇形三角剖分更好的方法吗?
答案 0 :(得分:1)
找到了这个approach,它同时适用于凹面和凸面:
case class Point(val x: Double, val y: Double)
import scala.collection.mutable.ListBuffer
// Method to calculate the Area under each side of the polygon
def calculateAreaUnderSegment(A: Point , B: Point): Double = {
val averHeight = (A.y + B.y)/2
val width = (A.x - B.x)
width * averHeight
}
def main(args: Array[String]) {
// Numer of sides Polygon
val sidesPoly = scala.io.StdIn.readLine().toInt
//List of Vertices Polygon
var listPoints = new ListBuffer[Point]()
for(i <- 1 to sidesPoly){
val tuple = scala.io.StdIn.readLine().split(" ")
val newPoint = new Point(tuple(0).toDouble, tuple(1).toDouble)
listPoints += newPoint
}
// Iterating over each pair of vertex
var area : Double = 0
for(i <- 0 to listPoints.size-2){
area += calculateAreaUnderSegment(listPoints(i),listPoints(i+1))
}
// For the last segment (to come back to the original vertex)
area += calculateAreaUnderSegment(listPoints(listPoints.size-1),listPoints(0))
println(area)
}