I have created a bunch of simple 2d-geometry classes (point, line, polygon) and some functions for these, and while my test code does execute there are a couple things that are not working.
Questions:
Why isn’t the rotate functions executed on the Line2d objects and the Point2d objects?
Why does my polygon end up empty?
Are my repr and str functions appropiate? (I know they aren’t really needed - but I thought it was a good idea to get into a habit of creating these functions for any future custom classes I make)
What would be a appropiate repr and str functions for the Polygon2d class?
(code runs)
## CLASSES
# 2D Point
class Point2d:
def __init__(self, u, v):
""" Create a Point2d object using UV coords
Example: p = Point2d(1,-2) """
self.u = u
self.v = v
def __repr__(self):
return "Point2d(%s, %s)" % (self.u, self.v)
def __str__(self):
return "%s, %s" % (self.u, self.v)
def rotate(self, other, angle):
""" Rotates a Point2d object around another Point2d object.
Example: self.rotate(other, 45)
Dependencies: python.math """
print("ran rotate on point")
# Short notation
oX = other.x
oY = other.y
pX = self.x
pY = self.y
# Calculate
angle = angle * math.pi / 180.0 # Radians
self.x = math.cos(angle) * (pX-oX) - math.sin(angle) * (pY-oY) + oX
self.y = math.sin(angle) * (pX-oX) + math.cos(angle) * (pY-oY) + oY
# 2D Line
class Line2d:
def __init__(self, pointA, pointB):
""" Create a Line2d object using two Point2d objects
Example: l = Line2d(pointA, pointB) """
self.pointA = pointA
self.pointB = pointB
def __repr__(self):
return "Line2d(Point2d(%s, %s), Point2d(%s, %s))" % (self.pointA.u, self.pointA.u, self.pointB.u, self.pointB.v)
def __str__(self):
return "(%s, %s), (%s, s%)" % (self.pointA.u, self.pointA.v, self.pointB.u, self.pointB.v)
# Get angle using arctan
def getAngle(self):
""" Gets the arctan angle between the Line2d's two Point2d objects
Example: angle = self.getAngle()
Dependencies: python.math
Returns: float """
# Short notation
pA = self.Point2d
pB = self.Point2d
# Get distances
if pA.u >= pB.u:
distX = (pA.u - pB.u)
distY = (pA.v - pB.v)
else:
distX = (pB.u - pA.u)
distY = (pB.v - pA.v)
# Calculate arctan angle and return it
return math.degrees(math.atan2(distY, distX))
# Rotate the line
def rotate(self, other, angle):
""" Rotates a Line2d object around a Point2d object.
Example: self.rotate(other, 45)
Dependencies: python.math """
print("ran rotate on line")
self.pointA.rotate(other, angle)
self.pointB.rotate(other, angle)
# 2D polygon
class Polygon2d:
def __init__(self, lineList):
""" Create a Polygon2D object using a list of Line2d objects
Example: l = Polygon2D(list) """
self.lineList = lineList
self.pos = len(lineList)
def __repr__(self): ## WARN: PLACEHOLDER - INCORRECT - DO NOT USE
return lolk
def __str__(self): ## WARN: PLACEHOLDER - INCORRECT - DO NOT USE
return "Polygon2d(%s, %s)" % (self.lineList)
def __iter__(self):
return self
def next(self):
if self.pos <= 0:
raise StopIteration
self.pos = self.pos - 1
return self.lineList[self.pos]
# Rotate the hull
def rotate(self, other, angle):
""" Rotates a Polygon2d object around a Point2d object
Example: self.rotate(other, 45)
Dependencies: python.math """
print("ran rotate on polygon")
for Line2d in self:
print Line2d
Line2d.rotate(other, angle)
# Calculate the area of the bounding box
def getBoundsArea(self):
""" Gets the MAR (minimum-area rectangle) of the polygon
Example: area = self.getBoundsArea()
Returns: float """
# Get max/min bounds
xMax, xMin, yMax, yMin = (0.0,)*4
for Line2d in self:
for Point2d in Line2d:
if Point2d.u > xMax:
xMax = Point2d.u
if Point2d.u < xMin:
xMin = Point2d.u
if Point2d.v > yMax:
yMax = Point2d.v
if Point2d.v < yMin:
yMin = Point2d.v
# Calculate and return area
return (abs(xMax-xMin) * abs(yMax-yMin))
# Get the coords of all Point2d objects in the polygon
def getCoords(self):
""" Gets all the coordinates for the Point2d objects in the polygon
Example: coordList = self.getCoords()
Returns: tuple list of floats """
# Loop through all Point2d objects and get the coords, then append to list
coordList = []
for Line2d in self:
for Point2d in Line2d:
coordList.append((Point2d.u, Point2d.v))
# Remove duplicates and return list
return list(set(coordList))
## TEST
if __name__ == "__main__":
# Create points
p1 = Point2d(0.0, 0.0)
p2 = Point2d(1.0, 0.0)
p3 = Point2d(1.0, 1.0)
p4 = Point2d(0.0, 1.0)
# Create lines
l1 = (p1, p2)
l2 = (p2, p3)
l3 = (p3, p4)
l4 = (p4, p1)
# Create polygon
poly = Polygon2d([l1, l2, l3, l4])
# Write polygon coords
print("coords before are %s") % poly.getCoords()
# Rotate polygon
origin = Point2d(0.0, 0.0)
poly.rotate(origin, 90)
# Write polygon coords
print("coords after are %s") % poly.getCoords()