Reputation: 19
I am trying to read the description of a polygon from a file and compute the area of the polygon according to the description.
So far my approach:
#Function for computing area of a polygen
def polygonArea(A):
n = len(A) # of corners
area = 0.0
j = n - 1
for i in range(n):
area += (A[0][j] + A[0][i]) * (A[1][j] - A[1][i])
area = abs(area) / 2.0
#reading from the file and connecting the polygen in a vector array in terms of X and Y coordinates
file = input('Enter file name:')
with open(file, 'r') as f:
file = f.read()
fileContent =file
A = [[],[]] #trying to create an vector of x and y ordinates
xa = 0.0
yb = 0.0
data = ""
if fileContent > data and data == "(":
data.join(fileContent)
if data == "N":
data.join(fileContent)
if data != ",":
print("Description is wrong!")
if file>temp:
yb += temp
A[1].append(yb) #Storing the value in y co ordinate of vector A
A[0].append(xa) #Storing the value in x co ordinate of vector A
if data == "W":
data.join(fileContent)
if data != ",":
print("Description is wrong!")
if file > temp:
xa -= temp
A[1].append(yb)
A[0].append(xa)
if data == "E":
data.join(fileContent)
if data != ",":
print("Description is wrong!")
if file > temp:
xa += temp
A[1].append(yb)
A[0].append(xa)
if data == "S":
data.join(fileContent)
if data != ",":
print("Description is wrong!")
if file > temp:
xa -= temp
A[1].append(yb)
A[0].append(xa)
#If polygon is complete A CONDITION on completeion of polygen in c++ if(x.back()==0 && y.back()==0)
p= polygonArea(A)
print ("area = ",p)
Upvotes: 0
Views: 1960
Reputation: 24232
Here is a complete solution. First, we parse the data using a regex, finding the cardinal direction and step inside each pair of parentheses.
Then, we build the list of vertices. We start from [0, 0]
. For each move, we calculate the coordinates of the new point by adding step * the direction vector corresponding to the cardinal direction. The last vertex should also be [0, 0]
.
To calculate the area, we zip the list of vertices with itself offset by one vertex to get pairs of adjacent vertices, and apply the traditionnal formula from there.
To recreate your sample data file:
data = '(N, 17.5), (E, 20.4), (S, 25), (E, 7.6), (S, 10), (W, 56), (N, 17.5), (E, 28)'
with open('data.txt', 'w') as f:
f.write(data)
import re
def vertices_from_data(data):
directions = {'N': [0, 1], 'E': [1, 0], 'S': [0, -1], 'W': [-1, 0]}
moves = re.findall(r'\(([NSEW]), ([\d.]+)\)', data)
vertices = [[0, 0]]
for card, step in moves:
direction = directions[card]
step = float(step)
prev = vertices[-1]
new = [prev[i] + step*direction[i] for i in [0, 1]]
vertices.append(new)
return vertices
def polygon_area(vertices):
return 0.5 * abs(sum(v1[0]*v2[1]-v1[1]*v2[0] for v1, v2 in zip(vertices[1:], vertices[:-1])))
filename = 'data.txt'
with open(filename) as f:
data = f.read()
vertices = vertices_from_data(data)
area = polygon_area(vertices)
print(area)
# 1280
Upvotes: 1
Reputation: 821
This could get you started; this shows the reading of the elements from the file. You should be able to fill in the rest, with regard to processing the list 'each'. Here, we are splitting the input based on the ")" character, and then splitting each of those into a format that you can use; you need N-S-E-W, and a value, correct? Might want to use a .upper or other tweak so that you don't have to worry about case ('e' vs 'E')...
Note that you were looking at the length of A, which was 2, not the number of points len(A[0])-1; you need to duplicate the first point for the formula to work:
https://www.mathopenref.com/coordpolygonarea.html
You also didn't have a return statement in your function.
#Function for computing area of a polygen
def polygonArea(A):
n = len(A[0])-1 # of corners; added a point at end for calc
print("corners in A = ", n)
area = 0.0
for i in range(0,n):
x1=A[0][i]
y1=A[1][i]
x2=A[0][i+1]
y2=A[1][i+1]
print(i, "..." , x1,y1," ", x2,y2)
da=(x1*y2-y1*x2)
print(da)
area=area+da
print(area)
area = abs(area) / 2.0
return(area)
#reading from the file and connecting the polygen in a vector array in terms of X and Y coordinates
# file = input('Enter file name:')
file = 'data2.txt'
with open(file, 'r') as f:
file = f.read()
fileContent =file
A = [[],[]] #trying to create an vector of x and y ordinates
xa = 0.0
yb = 0.0
data = ""
points = fileContent.split(')')
for idx, each in enumerate(points):
found_left=each.find("(")
if(found_left > 0):
coordinate = each[found_left+1:].split(",")
direction=coordinate[0]
value=coordinate[1]
print(idx, "dir = ", direction, " val = " , value)
if direction == "N":
yb += float(value)
A[1].append(yb) #Storing the value in y co ordinate of vector A
A[0].append(xa) #Storing the value in x co ordinate of vector A
elif direction == "W":
xa -= float(value)
A[1].append(yb)
A[0].append(xa)
elif direction == "E":
xa += float(value)
A[1].append(yb)
A[0].append(xa)
elif direction == "S":
yb -= float(value)
A[1].append(yb)
A[0].append(xa)
else:
print("error")
# last point is first point, needed for calculation
A[0].append(A[0][0])
A[1].append(A[1][0])
print("done reading.")
#If polygon is complete A CONDITION on completeion of polygen in c++ if(x.back()==0 && y.back()==0)
p= polygonArea(A)
print ("area = ",p)
Upvotes: 1
Reputation: 27567
Here, I defined a function that will take in the lengths of the polygon, starting at the line at the vertical line of length 17.5, and progressing clockwise:
def cord(lst):
lst2 = [[0,0]] # First coordinate is at (0,0)
d = 'up' # The lines go either up of right (down and left will be negative numbers)
c = [0,0]
for n in lst:
if d == 'up': # if the direction is up, we add the value to the y cor
c[1]+=n
lst2.append(c.copy())
d = 'right' # After up, we go right
else: # if the direction is right, we add the value to the x cor
c[0]+=n
lst2.append(c.copy())
d = 'up' # After right, we go up
return lst2
With the coordinates of each point, we can use this function I defined to find the area:
def polygon(lst2):
area = 0
for v in range(len(lst2)):
if v+1 == len(lst2):
i = 0
else:
i = v+1
area += (lst2[v][0]*lst2[i][1]-lst2[v][1]*lst2[i][0])
return abs(area/2)
c = cord([17.5,20.4,-25,7.6,-10,-56,17.5,28])
print(polygon(c))
Output:
1280.0
Upvotes: 1
Reputation: 27567
If you can get the coordinate of all the points going either clockwise or counter-clockwise, starting at any vertex, you can use this formula:
You can put that formula into a python program:
def polygon(x1,y1,x2,y2,x3,y3,x4,y4):
area = abs(((x1*y2-y1*x2)+(x2*y3-y2*x3)+(x3*y4-y3*x4)+(x4*y1-y4*x1))/2)
return area
print(polygon(4,4,4,0,0,0,0,4))
Output:
16.0
Upvotes: 0