stepaside_1.wrl source
#VRML V2.0 utf8

Viewpoint {
position -.3 -7.8 6.25
orientation 1 0 0 .9
description "initial"
}
NavigationInfo {
type "EXAMINE"
}
# Inline { url "getvp.wrl" }

# 青円柱
DEF Blue-Tf Transform {
translation 0 0 0
children [
Transform {
rotation 1 0 0 1.5708
children [
Shape {
appearance Appearance {
material Material {
diffuseColor 0 0 1
}
}
geometry DEF Cyl Cylinder {
radius 0.5
height 0.5
}
}
]
}
DEF PlS PlaneSensor {}
]
}

ROUTE PlS.translation_changed TO Blue-Tf.translation

# 赤円柱
DEF Red-Tf Transform {
translation -2 0 0
children [
Transform {
rotation 1 0 0 1.5708
children [
Shape {
appearance Appearance {
material Material {
diffuseColor 1 0 0
}
}
geometry USE Cyl
}
]
}
]
}

# 緑円柱
DEF Green-Tf Transform {
translation 2 0 0
children [
Transform {
rotation 1 0 0 1.5708
children [
Shape {
appearance Appearance {
material Material {
diffuseColor 0 1 0
}
}
geometry USE Cyl
}
]
}
]
}

# スクリプト
DEF Sc Script {
eventIn SFVec3f translationBlue
field SFNode Red USE Red-Tf
field SFNode Green USE Green-Tf
directOutput TRUE
url "javascript:
function translationBlue (bluePos) {

// 赤と緑の位置を得る。
var redPos = Red.translation;
var greenPos = Green.translation;

// 緑から赤、青から赤、青から緑のベクトルを得る。
var vecG2R = redPos.subtract(greenPos);
var vecB2R = redPos.subtract(bluePos);
var vecB2G = greenPos.subtract(bluePos);

// 緑を青から1(円柱の直径)離れた場所に置く。
greenPos = vecB2G.normalize().add(bluePos);

// 緑と赤、青と赤の距離が短いならば、赤を遠ざける。
if ( vecG2R.length() < 1.1 ) redPos = vecG2R.normalize().multiply(1.15).add(greenPos);
if ( vecB2R.length() < 1.1 ) redPos = vecB2R.normalize().multiply(1.15).add(bluePos);

// 赤をz軸方向に動かさないようにする。(偶に青と赤が重なると、赤がZ軸方向に動くため。)
redPos.z = 0;

// 赤と緑の新しい位置をセットする。
Red.translation = redPos;
Green.translation = greenPos;

}
"
}

ROUTE Blue-Tf.translation TO Sc.translationBlue