見出し画像

複数のオブジェクトにランダムにクラスを割り当てるマリオネット

外壁のパターンを作成するために、ランダムにクラスを割り当てるマリオネットを作ってみました。(マリオネットと言ってもほとんどコード直打ちですが)

乱数の代わりに以前使った間欠カオス法を使っています。

パラメーターとしては

・グループ名
CalssSet - Group というレコードフォーマットを作成して、クラスを割り当てたいすべてのオブジェクトに同じ名前を割り当てておきます。実行時には同じ名前のオブジェクトに対してクラスが割り当てられます。
「南面」「北面」など異なる名前をつけておけば、それぞれ別にマリオネットを実行させられます。

・初期値
1~9999の初期値に対して他の設定が同じなら、毎回同じ結果が帰るようにしているので、結果を再現できます。気に入った結果はマリオネットオブジェクト自体を複製して残しておくことも可能。(random.seedで乱数を初期化しています。)
ここを0にした場合は初期値がランダムで選ばれます。(選ばれた初期値はメッセージダイアログで表示されるので再現も可能)

乱数カット
0~50で設定。値が貼り付きをどれだけ抑えるかの値です。50の場合は間欠カオス(疑似1/fゆらぎ)ではなく、完全なランダムになります。(なるはず)

クラス
割当てるクラスと確率(確率は上からの合計)を最大5組まで設定できます。(確率が100以降のクラスは選ばれません)

マリオネットの構成はこんな感じ。

#Revised 12/21/15 MFarrell
 #Modified by MFarrell May 2017
@Marionette.NodeDefinition

class Params(metaclass = Marionette.OrderedClass):
 #APPEARANCE 	 #Name 	this = Marionette.Node( "ClassSet" )
	this.SetDescription( "クラス割当" )

	 #Input Ports
	group = Marionette.PortIn( "", 'sGroup' )
	syoki = Marionette.PortIn( 0, 'iSyoki' )
	cut = Marionette.PortIn( 0.2, 'iCut' )
	cls1 = Marionette.PortIn( "", 'sClass1' )
	k1 = Marionette.PortIn( 0, 'iK1' )
	cls2 = Marionette.PortIn( "", 'sClass2' )
	k2 = Marionette.PortIn( 0, 'iK2' )
	cls3 = Marionette.PortIn( "", 'sClass3' )
	k3 = Marionette.PortIn( 0, 'iK3' )
	cls4 = Marionette.PortIn( "", 'sClass4' )
	k4 = Marionette.PortIn( 0, 'iK4' )
	cls5 = Marionette.PortIn( "", 'sClass5' )

		
	
	 #OIP Controls

	 #Output Ports
	
 #BEHAVIOR 	this.SetLinksObjects()
	
def RunNode(self):
	 #inputs 	group = self.Params.group.value
	syoki = self.Params.syoki.value / 10000
	cut = self.Params.cut.value
	cls1 = self.Params.cls1.value
	cls2 = self.Params.cls2.value
	cls3 = self.Params.cls3.value
	cls4 = self.Params.cls4.value
	cls5 = self.Params.cls5.value
	k1 = self.Params.k1.value
	k2 = self.Params.k2.value
	k3 = self.Params.k3.value
	k4 = self.Params.k4.value
	
	#----------------------------------------------------------
	#script-----------------------------------------------------
	#----------------------------------------------------------
	import random as r
	import math
	
	def ichaos( a , min , max , step , cut ): #間欠カオス関数
		b = int ( a* ( max - min + step ) / step ) * step + min
		if a < 0.5:
			a = a+2*a*a
		else:
			a = a-2*(1-a)*(1-a)
		if a < cut or a > (1-cut):
			a = r.random()
		return (a,b)

	def henkan(cH):
		nonlocal r1,cut,cls1,cls2,cls3,cls4,cls5,k1,k2,k3,k4
		(r1,w1) = ichaos(r1,0,99,1,cut/100) 
		if w1<k1:
			cls = cls1
		elif w1<k2:
			cls =cls2
		elif w1<k3:
			cls =cls3
		elif w1<k4:
			cls =cls4
		else :
			cls =cls5
		vs.SetClass( cH, cls )
		return

	r0 = 0
	if syoki == 0:
		r0 = r.randrange(1,9999,1)
		syoki = r0/10000
	r1 = syoki
	r.seed(int(r1*10000))
	vs.ForEachObject(henkan, "(('ClassSet'.'Group'='"+group+"'))")
		
	if r0>0:
		vs.Message(r0)
		

	#----------------------------------------------------------
	#end script--------------------------------------------------
	#----------------------------------------------------------
	
	 #outputs 	

で、実際はこんな感じで動作します。

サンプルも置いておきます。(v2017で動作チェックはしてません。)


この記事が気に入ったらサポートをしてみませんか?