0

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)
4
  • 1
    ...and it is tagged C++ because ? Commented May 31, 2020 at 19:03
  • 1
    @Abhishek because C++ is so awesome that all other languages wish to bask in its glory? Commented May 31, 2020 at 19:05
  • Can you post a demonstration of what the polygon looks like? Commented May 31, 2020 at 19:05
  • yeah you can see the photo @AnnZen Commented May 31, 2020 at 19:09

4 Answers 4

1

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
Sign up to request clarification or add additional context in comments.

2 Comments

Works, but doesn't use their particular input format. I think they were looking for help there. Good as a check, though.
I shifted the input format, so now it's more like it.
1

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)

2 Comments

Wow Thanks a lot for the help.appreciate it really. Just one thing did u ran the same data in the text file as mine or a different one as I was using (N, 17.5), (E, 20.4), (S, 25), (E, 7.6), (S, 10), (W, 56), (N, 17.5), (E, 28), .I got the answer area as 1101.5 . But which point you used at the end for the calc? @asylumax
The code I posted shows the addition of the first point, which is what you need (nicely posted by @Ann Zen - note the last term!). Once you have that, you have the correct area, which I think is 1280.
1

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

Comments

0

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: image

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

4 Comments

Thanks but I understand the math behind it but I dont know how to implement it from a file and create array for co ordinates @AnnZen
You might also want to use a construct which makes life a bit easier; points=[ ] , then, each point is [x1,y1], and use points.append([x1,y1]), etc.
Additionally, look into the split function; this will allow you to split your input; you could use the ")", and then split the strings based on that, to get an array of point, and then process the array. Are you able to at least print out the points you find? If you can do that, appending them to the list is the trivial part.
@asylumax No I couldn't print out the points how can I store the points? If I use the points=[ ] as you mentioned and split function so if it finds 17.5 do I store it in a string variable or store it straight into points.append([x1] for the x coordinate and points.append([y1] for the y coordinate. I am sorry I'm pretty new but if you could elaborate that would help a lot

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.