从网站下载shapes.py并使用类Circle,类Polygon和方法区域扩展它。类Circle和Polygon应该从Shape继承。对于圆,在创建时必须指定半径, str 方法应返回与Line和Rectangle相同样式的字符串:对于矩形,在创建时,顶点列表必须遵循以下示例正是如此将方法区域添加到Line,Rectangle,Circle类。线的面积为零,矩形和圆的面积应计算在 通常的方式。为此,从数学中导入pi。具有顶点的非自相交多边形的区域定义为
其中每个with表示多边形的顶点(“角”),和。请注意,如果点是逆时针顺序,则凸多边形的面积为正,如果它们是顺时针顺序,则为负。 (维基百科页面采用绝对值来避免负面区域。请勿在此处执行此操作。)
以下是一些测试用例:
g = Group()
l = Line(1, 2, 5, 6); g.add(l); print(l)
Line from (1, 2) to (5, 6)
r = Rectangle(-2, -3, 2, 3); g.add(r); print(r)
Rectangle at (-2, -3), width 2, height 3
c = Circle(1, -5, 1); g.add(c); print(c)
Circle at (1, -5), radius 1
p = Polygon([(0, 0), (4, 0), (2, 2), (4, 4), (0, 4), (2, 2)]); g.add(p); print(p)
Polygon with [(0, 0), (4, 0), (2, 2), (4, 4), (0, 4), (2, 2)]
print(g); g.move(1, 1); print(g)
Group with:
Circle at (1, -5), radius 1
Rectangle at (-2, -3), width 2, height 3
Line from (1, 2) to (5, 6)
Polygon with [(0, 0), (4, 0), (2, 2), (4, 4), (0, 4), (2, 2)]
Group with:
Circle at (2, -4), radius 1
Rectangle at (-1, -2), width 2, height 3
Line from (2, 3) to (6, 7)
Polygon with [(1, 1), (5, 1), (3, 3), (5, 5), (1, 5), (3, 3)]
l.area(), r.area(), c.area(), p.area(), g.area()
(0, 6, 3.141592653589793, 8.0, 17.141592653589793)
我是Python的新手,并且不知道如何处理这个问题。任何帮助,将不胜感激!谢谢!
答案 0 :(得分:1)
我还没有完成代码。但是为你创造了一个学习和开始填充的结构。
Shape是基类,Line,Circle,Rectangle和Polygon是子类(继承)。 [假设你有OOP的想法]
class Group(object):
"""docstring for Group"""
def __init__(self):
super(Group, self).__init__()
self.shapes = list()
def add(self, shape):
self.shapes.append(shape)
def move(self, dx, dy):
for shape in self.shapes:
print "Moving %s by (%d, %d)" % (shape, dx, dy)
shape.move(dx, dy)
def __str__(self):
return "Group with: " + ", ".join((str(shape) for shape in self.shapes))
class Shape(object):
"""docstring for Shape"""
def __init__(self):
super(Shape, self).__init__()
def print_details(self):
pass
def area(self):
pass
class Line(Shape):
"""docstring for Line"""
def __init__(self, x1, y1, x2, y2):
super(Line, self).__init__()
self.x1 = x1
self.y1 = y1
self.x2 = x2
self.y2 = y2
def area(self):
return 0
def __str__(self):
return "Line from (%s, %s) to (%s, %s)" % (self.x1, self.y1, self.x2, self.y2)
class Rectangle(Shape):
"""docstring for Line"""
def __init__(self, x1, y1, x2, y2):
super(Rectangle, self).__init__()
self.x1 = x1
self.y1 = y1
self.x2 = x2
self.y2 = y2
def area(self):
return self._width * self._height
def __str__(self):
return "Rectangle at (%s, %s), width %s, height %s" % (
self.x1, self.y1, self._width(), self._height())
def _width(self):
return abs(self.x1 - self.x2)
def _height(self):
return abs(self.y1 - self.y2)
class Circle(Shape):
"""docstring for Circle"""
def __init__(self, x, y, radius):
super(Circle, self).__init__()
self.x = x
self.y = y
self.radius = radius
def area(self):
pass
def __str__(self):
return "Circle ....."
class Polygon(Shape):
"""docstring for Line"""
def __init__(self, vertices):
super(Polygon, self).__init__()
if type(vertices) is list and len(vertices) > 0 and type(vertices[0]) is tuple:
self.vertices = vertices
else:
raise Exception("Invalid syntax")
def area(self):
area = 0
for index in range(len(self.vertices) - 1):
v1 = self.vertices[index]
v2 = self.vertices[index + 1]
area += ((v1[0] * v2[1]) - (v2[0] * v1[1]))
area = 0.5 * area
return area
def __str__(self):
return "Polygon with %s" % str(self.vertices)
g = Group()
l = Line(1, 2, 5, 6)
g.add(l)
print(l) #Line from (1, 2) to (5, 6)
r = Rectangle(-2, -3, 2, 3)
g.add(r)
print(r) #Rectangle at (-2, -3), width 2, height 3
c = Circle(1, -5, 1)
g.add(c)
print(c) #Circle at (1, -5), radius 1
p = Polygon([(0, 0), (4, 0), (2, 2), (4, 4), (0, 4), (2, 2)])
g.add(p)
print(p) #Polygon with [(0, 0), (4, 0), (2, 2), (4, 4), (0, 4), (2, 2)]
print(g)
g.move(1, 1)
print(g) #Group with: Circle at (1, -5), radius 1 Rectangle at (-2, -3), width 2, height 3 Line from (1, 2) to (5, 6) Polygon with [(0, 0), (4, 0), (2, 2), (4, 4), (0, 4), (2, 2)] Group with: Circle at (2, -4), radius 1 Rectangle at (-1, -2), width 2, height 3 Line from (2, 3) to (6, 7) Polygon with [(1, 1), (5, 1), (3, 3), (5, 5), (1, 5), (3, 3)] l.area(), r.area(), c.area(), p.area(), g.area() (0, 6, 3.141592653589793, 8.0, 17.141592653589793)
如果您有疑问,请随时提出更多问题
答案 1 :(得分:-1)
这是鞋带公式(http://en.wikipedia.org/wiki/Shoelace_formula),我在http://www.cgafaq.info/wiki/Polygon_Area的python中发现了一个可能的实现。这个网站似乎已经关闭了,但我发现这个形状相似的模块命名为相同的源(https://toblerity.org/shapely/shapely.algorithms.html)
所以,如果你想在python中使用公式,这在我看来是可靠的:
def signed_area(coords):
"""Return the signed area enclosed by a ring using the linear time
algorithm at http://www.cgafaq.info/wiki/Polygon_Area. A value >= 0
indicates a counter-clockwise oriented ring.
return 0, if the ring is not closed
"""
xs, ys = map(list, zip(*coords))
xs.append(xs[1])
ys.append(ys[1])
return sum(xs[i]*(ys[i+1]-ys[i-1]) for i in range(1, len(coords)))/2.0
正如文档字符串所示,在一个闭环上,第一个坐标对等于最后一个,signed_area返回该区域。如果环未关闭,则返回值为零。如果结果为negativ,则多边形的方向为顺时针方向,如果为正方向,则多边形为逆时针方向。
如果您的多边形由多个环组成,则添加每个环的带符号区域,因为外环和内环具有不同的方向,从而产生相反的符号。