のvoronoi_finite_polygons_2d(vor, radius=None)
関数を使用していました。ポリゴン計算の範囲が一貫していません
centroid of each voronoi cellを示すように変更したいと思います。いくつかの重心が劇的に間違っているのをなぜデバッグするか(雑草の重心を指し示す緑色のアローを参照)。最初のエラーは私が特定したものです:いくつかの計算では、頂点を適切に全時計回りまたは全反時計回りに処理していないことがありました。
いくつかのポイントが正しくソートされない理由はわかりませんが、私が調査する前に別の異常を発見しました。
時計回りまたは反時計回りに移動すると、同じ領域(反対の符号が付いています)を取得する必要があります。簡単な例では、私はそうです。しかし、私が作ったランダムなポリゴンでは、私は/若干異なる結果を得ます。
import numpy as np
import matplotlib.pyplot as plt
from scipy.spatial import Voronoi
import random
import math
def measure_polygon(vertices):
xs = vertices[:,0]
ys = vertices[:,1]
xs = np.append(xs,xs[0])
ys = np.append(ys,ys[0])
#https://en.wikipedia.org/wiki/Centroid#Centroid_of_polygon
area = sum(xs[i]*(ys[i+1]-ys[i-1]) for i in range(0, len(xs)-1))/2.0
centroid_x = sum((xs[i]+xs[i+1])*(xs[i]*ys[i+1] - xs[i+1]*ys[i]) for i in range(0, len(xs)-1))/(6.0*area)
centroid_y = sum((ys[i]+ys[i+1])*(xs[i]*ys[i+1] - xs[i+1]*ys[i]) for i in range(0, len(xs)-1))/(6.0*area)
return (area, (centroid_x, centroid_y))
最初の例は、処理順序(cwまたはccw)に関係なく、同じ領域と重心を想定しています。
d = [[0.0 , 0.0], [1.0,3.0],[ 5.0,3.0],[ 4.0 , 0.0] ]
print len(d)
defects = []
defects.append([d[0], d[1], d[2], d[3]])
defects.append([d[3], d[2], d[1], d[0]])
for v in defects:
print measure_polygon(np.array(v))
簡単な平行四辺形出力:今
4
(-12.0, (2.5, 1.5))
(12.0, (2.5, 1.5))
しかし、この4角形を見て(つまり、ほとんど三角形である)
#original list of vertices
d = [[-148.35290745 , -1.95467472], [-124.93580616 , -2.09420039],[ -0.58281373, 1.32530292],[ 8.77020932 , 22.79390931] ]
print len(d)
defects = []
#cw
defects.append([d[0], d[2], d[3], d[1]])
#ccw
defects.append([d[1], d[3], d[2], d[0]])
for v in defects:
print measure_polygon(np.array(v))
は私に奇妙な出力が得られます。
4
(1280.4882517358433, (-36.609159411740798, 7.5961622623413145))
(-1278.8546083623708, (-36.655924939495335, 7.6058658049196115))
地域が異なります。そして、領域が異なる場合、重心は異なるでしょう。領域の不一致(1280対1278)は非常に大きいので、浮動小数点丸めの対象ではないと考えられます。しかし、それ以外に、私はこれがなぜ機能していないのかという仮説を使い果たしました。
===============================
私は私のリスト - ....エラーを検出しましたy-1とy + 1の表記が壊れていた(半分作業した不吉な方法で)表記を解読/索引付けすることができなくなった。正しいルーチンは、次のとおりです。
def measure_polygon(vertices):
xs = vertices[:,0]
ys = vertices[:,1]
#the first and last elements are for +1 -1 to work at end of range
xs = vertices[-1:,0]
xs = np.append(xs,vertices[:,0])
xs = np.append(xs,vertices[:1,0])
ys = vertices[-1:,1]
ys = np.append(ys,vertices[:,1])
ys = np.append(ys,vertices[:1,1])
#for i in range(1, len(xs)-1):
# print ("digesting x, y+1, y-1 points: {0}/{1}/{2}".format(xs[i], ys[i+1], ys[i-1]))
#https://en.wikipedia.org/wiki/Centroid#Centroid_of_polygon
area = sum(xs[i]*(ys[i+1]-ys[i-1]) for i in range(1, len(xs)-1))/2.0
centroid_x = sum((xs[i]+xs[i+1])*(xs[i]*ys[i+1] - xs[i+1]*ys[i]) for i in range(1, len(xs)-1))/(6.0*area)
centroid_y = sum((ys[i]+ys[i+1])*(xs[i]*ys[i+1] - xs[i+1]*ys[i]) for i in range(1, len(xs)-1))/(6.0*area)
return (area, (centroid_x, centroid_y))
だから今はNaNの例では、右の作品:最初と最後の点があるので、自己閉鎖する必要が
number of vertices: 5
(-30.0, (7.166666666666667, 7.6111111111111107))
(30.0, (7.166666666666667, 7.6111111111111107))
ありがとう、私のインデックス/リストの理解に誤りが見つかりました。 Btw、あなたが私の例を処理し、+/- 1619の領域を取得したとき、処理の順序は純粋なCCWまたはCWの順序ではないということです。私が適切なCW/CCWの順序でそれを行うと、+/- 1270.1387323316385が得られます。ポリゴンを記述したとき、+/- 1619.5827808873739 – user3556757
フィールドでジオメトリオブジェクトを扱うとき、ポリゴンは常に最初と最後のポイントが等しく、リングも含まれています。これにより、内側リングと外側リングとの間のブリードスルーが防止される。私たちは何もしなければならない、それだけです。私がマニュアルデモをしなければならないとき、それは第二の性質です。これにより、混乱も防ぎます。ポリゴンまたは閉ループポリラインを表すために4つの点が使用されます。 3つの点はポリラインを表現するだけです。私はネストされたリングであなたを探索するためにein_areaを拡張しました。外輪はCW、内輪(すなわち穴を形成する)はCCW – NaN
BTW ...他のすべての例はどこに行きましたか?これは正常ですか? – NaN