今日はグラフの幾何学的特性などに触れます。以下の一部をコードを書いて作図します。
孤立最近接対(Reciprocal Pair):RP
最近傍グラフ(Nearest Neighbor Graph) :NNG
最小木(Minimum Spanning Tree):MST
相対近傍グラフ(Relative Neghborhood Graph):RNG
ガブリエルグラフ(Gabriel Graph):GG
ドローネ網(Delaunay Triangle):DT
以下 Rhino-Python (editpythonscript) でのコード
指定範囲内(x: 0~100, t: 0~100)にランダムな点を生成
import rhinoscriptsyntax as rs
import Rhino.Geometry as rg
import math
import random
import sys
pts = []
for i in range(100):
    x = random.uniform(0,100)
    y = random.uniform(0,100)
    pos = rg.Point3d(x,y,0)
    pt = rs.AddPoint(pos)
    pts.append(pt)
全グラフ(配列ブラケットアクセス)
objs = [] for i in range(len(pts)-1): for j in range(i+1,len(pts)): if pts[i] != pts[j]: l = rs.AddLine(pts[i], pts[j]) objs.append(l)
全グラフ(配列ラムダ文)
for p in pts:
    for q in pts:
        if p != q:
            rs.AddLine(p,q)
rs.Command('_seldup')
rs.Command('_delete')
Nearest Neighbor Graph NNG
もっとも近い点同士を結ぶ
objs = [] for p1 in pts: nearlestdist = sys.float_info.max nearlest = None for p2 in pts: if p1 != p2: dist = rs.Distance(p1, p2) if dist < nearlestdist: nearlestdist = dist nearlest = p2 if(nearlest!=None): l = rs.AddLine(p1, nearlest) objs.append(l)
Minimum Spanning Tree: MST (最小木)
全ての点(ノード)を最小限のエッジで接続する。全ての点(ノード)が参加しているグラフ(ネットワーク)で、エッジの総長さがもっとも短いもの。下記はプリム法(グラフに接続済みのノードグループと未接続のノードグループに分け、2つのグループ間のもっとも近いノード同士を接続していく)
objs = [] #Minimum Spanning Tree: MST ptsA = [] ptsB = list(pts) ptsA.append(pts[0]) ptsB.remove(pts[0]) while 1: shortestlen = sys.float_info.max stA = None stB = None for p1 in ptsA: for p2 in ptsB: dist = rs.Distance(p1,p2) if shortestlen > dist: shortestlen = dist stA = p1 stB = p2 if shortestlen > 0: l = rs.AddLine(stA,stB) objs.append(l) ptsA.append(stB) ptsB.remove(stB) if len(ptsB) == 0: break
Relative Neighborhood Graph RNG
点群から2点を取り出し、その2点間の距離を半径とする円を2点それぞれから描画し、その両方の円に他の点が一つも無い場合、その2点を結ぶ
objs = [] for p1 in pts: for p2 in pts: if p1 != p2: dist0 = rs.Distance(p1,p2) nopoints = True for p3 in pts: if p3 != p1 and p3 != p1: dist1 = rs.Distance(p1,p3) dist2 = rs.Distance(p2,p3) if dist1 < dist0 and dist2 < dist0: nopoints = False break if nopoints: l = rs.AddLine(p1,p2) objs.append(l)
Gabriel Graph GG
点群から2点を取り出し、その2点間の距離を直径とする円を2点の中点に描画し、その円内に他の点が一つも無い場合、その2点を結ぶ
objs = [] #Gabriel Graph:GG for p1 in pts: for p2 in pts: if p1 != p2: mp = (rs.PointCoordinates(p1)+rs.PointCoordinates(p2)) / 2. r = rs.Distance(p1,p2) / 2. if r > 0: nopoints = True for p3 in pts: if p3 != p1 and p3 != p2: dist = rs.Distance(p3,mp) if dist < r : nopoints = False break if nopoints and r > 0: l = rs.AddLine(p1,p2) objs.append(l)
Delaunay Triangle: DT
ドローネ網、3点(ノード)を取り出し、その3点(ノード)を通る円内にその3点以外の点(ノード)が存在しないときにその3点(ノード)を3つのエッジでつなぐ
ボロノイ・ダイアグラムと双対関係
objs = [] for i in range(0,len(pts) - 2): p1 = pts[i] for j in range(i+1,len(pts) - 1): p2 = pts[j] for k in range(j+1,len(pts) - 0): p3 = pts[k] pos1 = rs.PointCoordinates(p1) pos2 = rs.PointCoordinates(p2) pos3 = rs.PointCoordinates(p3) c = rg.Circle(pos1,pos2,pos3) cp = c.Center r = c.Radius if r > 0: nopoint = True for p4 in pts: if p4 != p1 and p4 != p2 and p4 != p3: dist = rs.Distance(cp,p4) if dist < r: nopoint = False break if nopoint == True: l = rs.AddLine(p1,p2) objs.append(l) l = rs.AddLine(p1,p3) objs.append(l) l = rs.AddLine(p2,p3) objs.append(l)
下記はghpythonlibを使った簡易な描き方(Delaunay Triangle: DT)
import ghpythonlib.components as ghp
result = ghp.DelaunayEdges(pts)
edges = result[1]
for e in edges:
    if e.Length &gt; 0:
        rs.AddLine(e.From,e.To)
			
Comments are closed.