面積算定(三斜)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('多角形に変換してください。')

Follow me!

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です