在函数中实现脚本.有什么建议吗?
首先,我是Python(编程领域)的新手,但我希望学习和转换由 jwpat7开发的函数.给定一组从凸包得到的点
first of all, i am quite new in Python (an programming area) but i wish to learn and convert a function developed by jwpat7. Given a set of points derived from a convex hull
hull= [(560023.44957588764,6362057.3904932579),
(560023.44957588764,6362060.3904932579),
(560024.44957588764,6362063.3904932579),
(560026.94957588764,6362068.3904932579),
(560028.44957588764,6362069.8904932579),
(560034.94957588764,6362071.8904932579),
(560036.44957588764,6362071.8904932579),
(560037.44957588764,6362070.3904932579),
(560037.44957588764,6362064.8904932579),
(560036.44957588764,6362063.3904932579),
(560034.94957588764,6362061.3904932579),
(560026.94957588764,6362057.8904932579),
(560025.44957588764,6362057.3904932579),
(560023.44957588764,6362057.3904932579)]
this script return a print of all possible area following this post problem. The code develop by jwpat7 is:
import math
def mostfar(j, n, s, c, mx, my): # advance j to extreme point
xn, yn = hull[j][0], hull[j][1]
rx, ry = xn*c - yn*s, xn*s + yn*c
best = mx*rx + my*ry
while True:
x, y = rx, ry
xn, yn = hull[(j+1)%n][0], hull[(j+1)%n][1]
rx, ry = xn*c - yn*s, xn*s + yn*c
if mx*rx + my*ry >= best:
j = (j+1)%n
best = mx*rx + my*ry
else:
return (x, y, j)
n = len(hull)
iL = iR = iP = 1 # indexes left, right, opposite
pi = 4*math.atan(1)
for i in range(n-1):
dx = hull[i+1][0] - hull[i][0]
dy = hull[i+1][1] - hull[i][1]
theta = pi-math.atan2(dy, dx)
s, c = math.sin(theta), math.cos(theta)
yC = hull[i][0]*s + hull[i][1]*c
xP, yP, iP = mostfar(iP, n, s, c, 0, 1)
if i==0: iR = iP
xR, yR, iR = mostfar(iR, n, s, c, 1, 0)
xL, yL, iL = mostfar(iL, n, s, c, -1, 0)
area = (yP-yC)*(xR-xL)
print ' {:2d} {:2d} {:2d} {:2d} {:9.3f}'.format(i, iL, iP, iR, area)
结果是:
i iL iP iR Area
0 6 8 0 203.000
1 6 8 0 211.875
2 6 8 0 205.800
3 6 10 0 206.250
4 7 12 0 190.362
5 8 0 1 203.000
6 10 0 4 201.385
7 0 1 6 203.000
8 0 3 6 205.827
9 0 3 6 205.640
10 0 4 7 187.451
11 0 4 7 189.750
12 1 6 8 203.000
我希望创建一个单个函数,并返回最小矩形的Length,Width和Area.例如:
i wish to create a single function with the return of Length, Width, and Area of the smallest rectangle. Ex:
Length, Width, Area = get_minimum_area_rectangle(hull)
print Length, Width, Area
18.036, 10.392, 187.451
我的问题是:
- 我需要创建一个功能还是两个功能.例如:def 最远和get_minimum_area_rectangle
- hull是值列表.这是最好的格式吗?
- do i need to create a single function or two function. ex: def mostfar and get_minimum_area_rectangle
- hull is a list of value. Is it the best format?
- 遵循一种功能方法,我在大多数情况下都无法集成
预先感谢
1)解决方案:一种功能 按照Scott Hunter提出的第一个解决方案,我在将mostfar()集成到get_minimum_area_rectangle()中时遇到了一个问题.任何建议或帮助都非常感激,因为我可以学习.
1) solution: one function following the first solution suggest by Scott Hunter, i have a problem to integrate mostfar() inside get_minimum_area_rectangle(). Any suggestion or help are really appreciate because i can learn.
#!/usr/bin/python
import math
def get_minimum_area_rectangle(hull):
# get pi greek
pi = 4*math.atan(1)
# number of points
n = len(hull)
# indexes left, right, opposite
iL = iR = iP = 1
# work clockwise direction
for i in range(n-1):
# distance on x axis
dx = hull[i+1][0] - hull[i][0]
# distance on y axis
dy = hull[i+1][1] - hull[i][1]
# get orientation angle of the edge
theta = pi-math.atan2(dy, dx)
s, c = math.sin(theta), math.cos(theta)
yC = hull[i][0]*s + hull[i][1]*c
从这里跟随jwpat7的上述示例,我需要使用mostfar().我有一个问题要了解在这一点上大部分时候是如何整合的(对不起这个词,对不起)
from here following the above example of jwpat7 i need to use mostfar(). I have a problem to understand how integrate (sorry for the not right term) mostfar in this point
下面是一个示例,说明如何从代码中将其变为 functor 对象并使用它-并对其中的一些更改我觉得其他一些事情值得.函子是充当功能的实体,但可以像对象一样对其进行操作.
Here's an example of how to make it a functor object out of your code and use it -- along with a few changes to some other things I felt were worthwhile. A functor is an entity that serves the role of a function but can be operated upon like an object.
在Python中,由于函数已经是单例对象,因此两者之间的区别较少,但是有时为一个对象创建专用类很有用.在这种情况下,它允许将辅助函数制成私有类方法,而不是您似乎反对这样做的全局或嵌套方法.
In Python there's less of a distinction between the two since functions are already singleton objects, but sometimes it's useful to create an specialized class for one. In this case it allows the helper function to be made into a private class method instead of it being global or nested which you seem to object to doing.
from math import atan2, cos, pi, sin
class GetMinimumAreaRectangle(object):
""" functor to find length, width, and area of the smallest rectangular
area of the given convex hull """
def __call__(self, hull):
self.hull = hull
mostfar = self._mostfar # local reference
n = len(hull)
min_area = 10**100 # huge value
iL = iR = iP = 1 # indexes left, right, opposite
# print ' {:>2s} {:>2s} {:>2s} {:>2s} {:>9s}'.format(
# 'i', 'iL', 'iP', 'iR', 'area')
for i in xrange(n-1):
dx = hull[i+1][0] - hull[i][0] # distance on x axis
dy = hull[i+1][1] - hull[i][1] # distance on y axis
theta = pi-atan2(dy, dx) # get orientation angle of the edge
s, c = sin(theta), cos(theta)
yC = hull[i][0]*s + hull[i][1]*c
xP, yP, iP = mostfar(iP, n, s, c, 0, 1)
if i==0: iR = iP
xR, yR, iR = mostfar(iR, n, s, c, 1, 0)
xL, yL, iL = mostfar(iL, n, s, c, -1, 0)
l, w = (yP-yC), (xR-xL)
area = l*w
# print ' {:2d} {:2d} {:2d} {:2d} {:9.3f}'.format(i, iL, iP, iR, area)
if area < min_area:
min_area, min_length, min_width = area, l, w
return (min_length, min_width, min_area)
def _mostfar(self, j, n, s, c, mx, my):
""" advance j to extreme point """
hull = self.hull # local reference
xn, yn = hull[j][0], hull[j][1]
rx, ry = xn*c - yn*s, xn*s + yn*c
best = mx*rx + my*ry
while True:
x, y = rx, ry
xn, yn = hull[(j+1)%n][0], hull[(j+1)%n][1]
rx, ry = xn*c - yn*s, xn*s + yn*c
if mx*rx + my*ry >= best:
j = (j+1)%n
best = mx*rx + my*ry
else:
return (x, y, j)
if __name__ == '__main__':
hull= [(560023.44957588764, 6362057.3904932579),
(560023.44957588764, 6362060.3904932579),
(560024.44957588764, 6362063.3904932579),
(560026.94957588764, 6362068.3904932579),
(560028.44957588764, 6362069.8904932579),
(560034.94957588764, 6362071.8904932579),
(560036.44957588764, 6362071.8904932579),
(560037.44957588764, 6362070.3904932579),
(560037.44957588764, 6362064.8904932579),
(560036.44957588764, 6362063.3904932579),
(560034.94957588764, 6362061.3904932579),
(560026.94957588764, 6362057.8904932579),
(560025.44957588764, 6362057.3904932579),
(560023.44957588764, 6362057.3904932579)]
gmar = GetMinimumAreaRectangle() # create functor object
print "dimensions and area of smallest enclosing rectangular area:"
print " {:.3f}(L) x {:.3f}(W) = {:.3f} area".format(*gmar(hull)) # use it
输出:
dimensions and area of smallest enclosing rectangular area:
10.393(L) x 18.037(W) = 187.451 area