这可能是一个非常简单的问题,但似乎我无法看到它。 我有顺时针点有序的列表,并希望根据this使用下面的函数来计算这些点的重心(凸多边形):Python如何处理复杂的计算?
和
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
使用Arcpy计算面积和centorid表明计算的ar ea通过上述函数是正确的,但质心是错误的。
Xc和Yc有什么问题,我无法修复它?
如果我以下列方式改变为循环工作原理:
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
这里是节点的列表来检查代码:
[(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)]
个人而言,我会找到我的代码*很多*更容易阅读,如果我附加了第一点的副本到的结束所以我不必在每次想参考第(i + 1)点时重新输入(正确)那个环绕测试。这就是维基百科所做的。另外,为什么不迭代我的列表长度(-1,如果你追加第一个点到最后),并始终使用我的索引?我试图从你的代码中解码你的表达式,但放弃了。 – barny
@ barny:你说得对,我可以用其他方式做,在列表末尾添加第一个点或在for循环结束后添加它。但是使用列表理解可以更容易地理解代码(可能效率更高),因为您不需要额外的步骤,只需要检查是否在代码中,考虑第一个关闭德路。 – msc87
这是您的代码,但我的0.01美元表示您的代码几乎难以辨认,难以辨认的代码难以理解,调试和维护。 “简化”for循环遍历点列表使您可以:a)编写代码来初始化,使用和维护循环计数器i,b)每次需要i + 1时必须手动将代码绕回到第一个节点 - 如果i + 1
barny