简体   繁体   中英

How does Python handle complicated calculations?

It might be a very simple problem but seems I am not able to see it. I have a list of point ordered clockwise and want to calculate the centroid of these point (a convex polygon) using the following function according to this :

在此输入图像描述 在此输入图像描述

and

在此输入图像描述

def calculateCentroid(raLinks,raNodes, links, nodes):  

orderedPointsOfLinks = orderClockwise(raLinks,raNodes, links, nodes)

arg1 = 0
arg2 = 0
Xc = 0
Yc = 0
i = 0
for point in orderedPointsOfLinks:
    arg1 += point.Y*(orderedPointsOfLinks[i+1 if i+1<len(orderedPointsOfLinks) else 0].X)
    arg2 += (orderedPointsOfLinks[i+1 if i+1<len(orderedPointsOfLinks) else 0].Y)*point.X
    Xc += (point.X+(orderedPointsOfLinks[i+1 if i+1<len(orderedPointsOfLinks) else 0].X))*(((orderedPointsOfLinks[i+1 if i+1<len(orderedPointsOfLinks) else 0].Y)*point.X)-(point.Y*(orderedPointsOfLinks[i+1 if i+1<len(orderedPointsOfLinks) else 0].X)))
    Yc += (point.Y+(orderedPointsOfLinks[i+1 if i+1<len(orderedPointsOfLinks) else 0].Y))*(((orderedPointsOfLinks[i+1 if i+1<len(orderedPointsOfLinks) else 0].Y)*point.X)-(point.Y*(orderedPointsOfLinks[i+1 if i+1<len(orderedPointsOfLinks) else 0].X)))    
    i+=1

area = (arg1-arg2)*0.5
print area

X = -Xc/(6*area)
Y = -Yc/(6*area)
print X , "   ", Y

calculating the area and the centorid using Arcpy shows that the calculated area by the above function is correct but the centroid is wrong.

what is the problem with Xc and Yc that I cant fix it?

If I change the for loop in the following way it works:

    for point in orderedPointsOfLinks:
        y0 = point.Y
        x0 = point.X
        x1 = orderedPointsOfLinks[i+1 if i+1<len(orderedPointsOfLinks) else 0].X
        y1 = orderedPointsOfLinks[i+1 if i+1<len(orderedPointsOfLinks) else 0].Y
        a = x0*y1 - x1*y0
        area += a
        Xc += (x0+x1)*a
        Yc += (y0+y1)*a
         i+=1
    area *= 0.5
    print area

    X = Xc/(6*area)
    Y = Yc/(6*area)
    print X , "   ", Y

here is a list of nodes to examine the code:

[(371623.876, 6159668.714),(371625.994, 6159661.094), (371624.319, 6159654.634), (371619.654, 6159649.86), (371614.194, 6159647.819), (371608.401, 6159648.449), (371601.544, 6159652.652), (371598.77, 6159658.058), (371599.318, 6159665.421), (371603.025, 6159671.805), (371611.372, 6159674.882 ), (371619.417, 6159673.065)]

source

Try:

import numpy

tp = [(371623.876, 6159668.714),(371625.994, 6159661.094), (371624.319, 6159654.634), (371619.654, 6159649.86),\
      (371614.194, 6159647.819), (371608.401, 6159648.449), (371601.544, 6159652.652), (371598.77, 6159658.058), \
      (371599.318, 6159665.421), (371603.025, 6159671.805), (371611.372, 6159674.882 ), (371619.417, 6159673.065),(371623.876, 6159668.714)]



# cx = sigma (x[i]+x[i+1])*((x[i]*y[i+1]) - (x[i+1]*y[i] ))
# cy = sigma (y[i]+y[i+1])*((x[i]*y[i+1]) - (x[i+1]*y[i] ))
cx = 0
cy = 0

p = numpy.array(tp)

x = p[:, 0]
y = p[:, 1]

a = x[:-1] * y[1:]
b = y[:-1] * x[1:]

cx = x[:-1] + x[1:]
cy = y[:-1] + y[1:]



tp = tp[:-1] #dont need repeat


def area():
    tox=0
    toy=0
    for i in range(len(tp)):
        if i+1 == len(tp):
            tox += tp[-1][0]*tp[0][1]
        else:
            tox += tp[i][0]*tp[i+1][1]

    for i in range(len(tp)):
        if i+1 == len(tp):
            toy += tp[-1][1]*tp[0][0]
        else:
            toy += tp[i][1]*tp[i+1][0]
    return abs(tox-toy)*0.5

ar = area()
Cx = abs(numpy.sum(cx * (a - b)) / (6. * ar))
Cy = abs(numpy.sum(cy * (a - b)) / (6. * ar))
print Cx,Cy

Warning !

tp[0] == tp[-1]

So: first and last coordinates are same value...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM