我已经制作了一个用Shoelace方法计算面积多边形的函数。
这完美无缺,但现在我想知道是否有更快的方法来获得相同的结果。 我想知道,因为这个函数必须能够更快地处理具有大量坐标的多边形。
我的功能:
def shoelace_formula(polygonBoundary, absoluteValue = True):
nbCoordinates = len(polygonBoundary)
nbSegment = nbCoordinates - 1
l = [(polygonBoundary[i+1][0] - polygonBoundary[i][0]) * (polygonBoundary[i+1][1] + polygonBoundary[i][1]) for i in xrange(nbSegment)]
if absoluteValue:
return abs(sum(l) / 2.)
else:
return sum(l) / 2.
我的多边形:
polygonBoundary = ((5, 0), (6, 4), (4, 5), (1, 5), (1, 0))
结果:
22.
有什么想法吗?
我和Numpy一起尝试: 它是最长的,但你必须先转换你的坐标。
import numpy as np
x, y = zip(*polygonBoundary)
def shoelace_formula_3(x, y, absoluteValue = True):
result = 0.5 * np.array(np.dot(x, np.roll(y, 1)) - np.dot(y, np.roll(x, 1)))
if absoluteValue:
return abs(result)
else:
return result
答案 0 :(得分:0)
这是一个使用1/2倍数的版本:https://stackoverflow.com/a/717367/763269
如果您需要更高的性能,可以考虑在Python C扩展中执行此操作。 C可以比Python快得多,特别是对于数学运算 - 有时是100-1000x。
答案 1 :(得分:0)
尝试最简单的方法,对三角形和多边形使用原始的鞋带公式:
def shoelace_formula(x1, y1, x2, y2, x3, y3, x4, y4, x5, y5):
return abs(0.5 * (x1*y2 + x2*y3 + x3*y4 + x4*y5 + x5*y1
- x2*y1 - x3*y2 - x4*y3 - x5*y4 - y1*y5))
print(shoelace_formula(5, 0, 6, 4, 4, 5, 1, 5, 1, 0))
答案 2 :(得分:0)
另一种有趣的方法(虽然速度较慢)
m = np.vstack([x,y])
result = 0.5 * np.abs(np.linalg.det(as_strided(m, (m.shape[1]-1, 2, 2), (m.itemsize, m.itemsize*m.shape[1], m.itemsize))).sum())
答案 3 :(得分:0)
对我来说,最快的方法是使用numpy,在这种情况下,您必须将(x,y)坐标的numpy数组作为鞋带方法的参数发送:
import numpy as np
def shoelace(x_y):
x_y = np.array(x_y)
x_y = x_y.reshape(-1,2)
x = x_y[:,0]
y = x_y[:,1]
S1 = np.sum(x*np.roll(y,-1))
S2 = np.sum(y*np.roll(x,-1))
area = .5*np.absolute(S1 - S2)
return area
答案 4 :(得分:0)
class Point //a new class for an any point a(X,Y), b(X,Y), c(X,Y), d(X,Y)
{
//private int x, y;
public int X { get; set; }
public int Y { get; set; }
}
static class Geometry
{
public static void GerArea(Point a, Point b, Point c)
{
double area = 0.5 * ( (a.X * b.Y) + (b.X * c.Y) + (c.X * a.Y) - (b.X * a.Y) - (c.X * b.Y) - (a.X * c.Y) );
Console.WriteLine(Math.Abs(area));
}
public static void GerArea(Point a, Point b, Point c, Point d)
{
double area = 0.5 * ((a.X * b.Y) + (b.X * c.Y) + (c.X * d.Y) + (d.X * a.Y) - (b.X * a.Y) - (c.X * b.Y) - (d.X * c.Y) - (a.X * d.Y ) );
Console.WriteLine(Math.Abs(area));
}
}
class Program
{
static void Main(string[] args)
{
Point a = new Point() { X = -12, Y = 12 };
Point b = new Point() { X = 15, Y = 15 };
Point c = new Point() { X = -15, Y = -16 };
Point d = new Point() { X = 16, Y = -15 };
Console.WriteLine("****Shoelace formula****\n");
Console.Write("Area of tringle: ");
Geometry.GerArea(a, b, c);
Console.Write("Area of quad: ");
Geometry.GerArea(a, b, c, d);
Console.ReadLine();
}
}
答案 5 :(得分:0)
这是一个非常简单的python中鞋带公式的实现
class Polygon:
def __init__(self,arr):
self.arr = arr
def area(self):
total=0
i = 0
while i != len(self.arr)-1:
total+=self.arr[i][0]*self.arr[i+1][1]
total-=self.arr[i+1][0]*self.arr[i][1]
i+=1
return abs(total +self.arr[-1][0]*self.arr[0][1] -self.arr[-1][-1]*self.arr[0][0])/2