The Polygon ADT is an example of a mutable ordered sequence. An ordered sequence is a container in which the elements are arranged in linear order from front to back. When the elements of the sequence are accessible by position, as is the case with the Polygon ADT, it is normally referred to as an indexed ordered sequence or simply an indexed sequence. Throughout the text, we assume that access to the individual elements of an indexed sequence is based on their position within the linear order, which is provided using the subscript operator.
Since a polygon is defined by an arbitrary number of vertices () we will need a way to store the vertices within an instance of the Polygon
class. The obvious choice is to represent each vertex using a Point
storage object as we did in Section 1.10 for the second implementation of the line segment
class Point :
def __init__(self, x, y) :
self.xCoord = x
self.yCoord = y
and to store the objects within a list. For example, suppose we want to create the following polygon
then we will need to store a collection of Point
objects within a list structure as shown below
Unlike the Bag ADT introduced earlier in the chapter, the elements contained in a polygon must be stored or arranged in a specific order. Given the list of points that define the vertices, edges of the polygon are defined between successive points with the last edge formed between the last entry in the list and the first. In addition, we must be able to access the individual vertices by position or index. This is easily done, since the elements of a list structure can themselves be accessed by position.
The Constructor
To implement the Polygon
class, we begin with the constructor. The constructor takes six arguments, two for each of the three pairs of vertex coordinates. The vertices will be stored in Point
objects within a list. The order in which the vertices are added to the list is important, they must follow the order provided in the argument list.
class Polygon :
def __init__(self, x0, y0, x1, y1, x2, y2) :
self._vertexList = list(Point(x0, y0), Point(x1, y1), Point(x2, y2))
A sample instance of the Polygon
class is illustrated below
Number of Vertices
Since we are using a list to store the Point
objects, one for each vertex, the number of vertices that define the polygon can be obtained from the length of the list.
def __len__(self) :
return len(self._vertexList)
Finding a Vertex
Accessing the vertex at a given index position is simply a matter of accessing the corresponding element in the list. Of course, we have to check the precondition before attempting to element the list element:
def getVertex(self, index) :
assert index >=0 and index < len(self), "Index out of range."
return self._vertexList[index]
The findVertex
method is suppose to find and return the index position for a given vertex. While Python's list container includes an index
method for just this purpose, we can not use it since the vertices are stored in the list using Point
objects. Instead, we have to implement our own search:
def findVertex(self, x, y) :
for i in range(len(self._vertexList)) :
vertex = self._vertexList[i]
if vertex.xCoord == x and vertex.yCoord == y :
return i
return -1
Inserting a Vertex
The insertVertex
method allows us to modify a polygon by inserting a new vertex at any position between two existing vertices. For example, suppose we want to insert a new vertex into our sample polygon at index position 2, which is between vertices and .
Then we would supply the statement
poly.insertVertex(2, 27, 20)
To accomplish this, the method should create a Point
object for the new vertex and insert it at the given index position using the insert
method on the list. If the index is equal to the number of vertices in the list, then we can simply append it to the end of the list.
vertex = Point(x, y)
if index == len(self) :
self._vertexList.append(vertex)
else :
self._vertexList.insert(index, vertex)
The resulting list after inserting the new vertex would look as follows:
The insertVertex
method has two preconditions that must be checked before the new vertex can be added to the list: the index must be within range and the new vertex can not be identical to an existing vertex:
assert index >= 0 and index <= len(self), "Index out of range."
assert self.findVertex(x, y) == -1, "The vertex must be unique."
The full implementation of the insertVertex
method follows:
def insertVertex(self, index, x, y) :
assert index >= 0 and index <= len(self), "Index out of range."
assert self.findVertex(x, y) == -1, "The vertex must be unique."
vertex = Point(x, y)
if index == len(self) :
self._vertexList.append(vertex)
else :
self._vertexList.insert(index, vertex)
The complete implementation of the Polygon
class is provided in the source listing below. The implementation of the remaining methods are left as an exercise.
Program Listing
# Implement of the Polygon ADT container using a list.
class Polygon :
# Creates a 3-sided polygon defined by the given vertices.
def __init__(self, x0, y0, x1, y1, x2, y2) :
self._vertexList = list(Point(x0, y0), Point(x1, y1), Point(x2, y2))
# Returns the number of vertices that comprise the polygon.
def __len__(self) :
return len(self._vertexList)
# Finds the index of the given vertex or returns -1.
def findVertex(self, x, y) :
for i in range(len(self._vertexList)) :
vertex = self._vertexList[i]
if vertex.xCoord == x and vertex.yCoord == y :
return i
return -1
# Returns the coordinates of the vertex as the index position.
def getVertex(self, index) :
assert index >=0 and index < len(self), "Index out of range."
return self._vertexList[index]
# Appends a new vertex after the last defined vertex.
def appendVertex(self, x, y) :
......
# Inserts a new vertex at the given index position.
def insertVertex(self, index, x, y) :
assert index >= 0 and index <= len(self), "Index out of range."
assert self.findVertex(x, y) == -1, "The vertex must be unique."
vertex = Point(x, y)
if index == len(self) :
self._vertexList.append(vertex)
else :
self._vertexList.insert(index, vertex)
# Removes the vertex at the given index position.
def deleteVertex(self, index) :
......
# Returns the total length of the polygon's perimeter.
def perimeter(self) :
......
# Private storage class for representing a 2-D point.
class Point :
def __init__(self, x, y) :
self.xCoord = x
self.yCoord = y
|