面積算定(三斜)Vectorworks
三斜の面積計算はよくわからないですが、見よう見まねで三斜のスクリプトを作成しました。
調べてみると、多角形は形状によって処理が難しく、全ての形状での自動化まではできてません。
スクリプトとレコードとワークシート
多角形を選択して、スクリプトを実行します。「三角形の面積の合計」と「多角形の面積」の合計と差をそれぞれダイアログで出します。
三角形の作成と合わせて、レコードを設定して、ワークシートで面積表も作成します。
円や楕円も三斜で計算してみる
スクリプトで円や楕円を多角形化もできますが、分岐が面倒だったのでメニューから多角形かを行います。メニューから行うと、60位に分割されるようです。
凹型多角形
180度以上の角度がある多角形を「凹型多角形」というようで、ベクトルで180度以上を認識させるのがちょっと大変。他にも多角形に穴が空いたり、自己交差があると、スクリプトで分割するのは大変です。
完全自動化は大変そうなので、結果に差があるときにはわかるようにダイアログでアナウンス。
手動で分割して凹型を解消すれば、正しく分割されます。
スクリプト
やってることは以下の通りで、本来はもう少し条件分けたりワークシート作ったりした方が良いですが。
1)多角形の頂点の数を認識
2)順番に三角形を作成
3)一番大きな角度を底面として、底面と高さの寸法を入力
4)作成した三角形にレコードを付与
5)準備していたワークシートを計算
import vs
import math
polyHd = vs.FSActLayer()
def createDim(pa,pb,pc,line):
vs.LinearDim(pa, pb, 0, 4, 1, 1, 10)
vs.SetObjectVariableInt(vs.LNewObj(),41,0)
teihen = vs.GetDimText(vs.LNewObj())
vs.ResetObject(vs.LNewObj())
vs.Locus(pc)
pt1,pt2,touch = vs.ClosestPoints(vs.LNewObj(), line)
vs.LinearDim(pt1, pt2, 0, 4, 1, 1, 10)
vs.SetObjectVariableInt(vs.LNewObj(),41,0)
takasa = vs.GetDimText(vs.LNewObj())
vs.ResetObject(vs.LNewObj())
teihen = vs.Str2Num(teihen)
takasa = vs.Str2Num(takasa)
vs.SetRecord(triangle, '三斜')
vs.SetRField(triangle, '三斜', '番号',str(i+1) )
vs.SetRField(triangle, '三斜', '底辺',vs.Str2Num(teihen))
vs.SetRField(triangle, '三斜', '高さ',vs.Str2Num(takasa))
return teihen , takasa
if vs.GetTypeN(polyHd) == 3:
polyHd = vs.ConvertToPolygon(polyHd,0)
elif vs.GetTypeN(polyHd) == 5:
count = vs.GetVertNum(polyHd)
area = 0
pointlist = []
linelist = []
vs.NewField('三斜', '用途', '', 4, 0)
vs.NewField('三斜', '番号', '', 4, 0)
vs.NewField('三斜', '底辺', 0, 3, 0)
vs.NewField('三斜', '高さ', 0, 3, 0)
for i in range(count):
p, vertexType, arcRadius = vs.GetPolylineVertex(polyHd, i+1)
pointlist.append(p)
for i in range(count-2):#0,1,2,3
trianglePt = []
vs.BeginPoly()
p1 = pointlist[0]
p2 = pointlist[i+1]
p3 = pointlist[i+2]
vs.AddPoint(p1)
vs.AddPoint(p2)
vs.AddPoint(p3)
vs.AddPoint(p1)
vs.EndPoly()
triangle = vs.LNewObj()
trianglePt = [p1,p2,p3]
vs.MoveTo(p1)
vs.LineTo(p2)
line1 = vs.LNewObj()
len1 = vs.HLength(line1)
vs.MoveTo(p2)
vs.LineTo(p3)
line2 = vs.LNewObj()
len2 = vs.HLength(line2)
vs.MoveTo(p3)
vs.LineTo(p1)
line3 = vs.LNewObj()
len3 = vs.HLength(line3)
lenlist = [len1,len2,len3]
lenMax = max(lenlist)
if lenMax == len1:
teihen , takasa = createDim(p1,p2,p3,line1)
elif lenMax == len2:
teihen , takasa = createDim(p2,p3,p1,line2)
elif lenMax == len3:
teihen , takasa = createDim(p3,p1,p2,line3)
boo,x,y = vs.Centroid(triangle)
center = x,y
vs.MoveTo(center)
vs.CreateText('(' + str(i+1) + ')')
vs.DelObject(line1)
vs.DelObject(line2)
vs.DelObject(line3)
triangArea = (teihen * takasa)/(2*1000000)
area += triangArea
kekka = area - (vs.HAreaN(polyHd)/1000000)
polyArea = '多角形の面積は' + str(vs.HAreaN(polyHd)/1000000)
area = '三角形の面積の合計は' + str(area)
if abs(kekka) <= 0.1:
kekka = 'その差は0.1m2以下です'
else:
kekka = '0.1m2以上の差があります。' + vs.Chr(13) + '多角形に穴がある場合や180度を超える角度がある場合は、' + vs.Chr(13)+'分割してください。'
vs.AlrtDialog(polyArea + vs.Chr(13) + area + vs.Chr(13) + kekka)
vs.DSelectAll()
else:
vs.AlrtDialog('多角形に変換してください。')