aUCBLogo Demos and Tests / create_organic_molecules3


setCaseIgnored false

be create_organic_molecules3
   
molecules=Table
   
[   water      [H H]
      
methan   [H H H H]
      
ethan      [H H H
               
[H H H]]
      
propan   [H H H
               
[H H
               
[H H H]]]
      
butan      [H H H
               
[H H
               
[H H
               
[H H H]]]]
      
pentan   [H H H
               
[H H
               
[H H
               
[H H
               
[H H H]]]]]
      
hexan      [H H H
               
[H H
               
[H H
               
[H H
               
[H H
               
[H H H]]]]]]
      
methanol   [[H]H H H]
      
ethanol   [[H]H H
               
[H H H]]
      
propanol   [[H]H H
               
[H H
               
[H H H]]]
      
isopropanol   
               
[[H]H
               
[H H
               
[H H[H]]]]
      
glycerol   [H[H]H
               
[[H]H
               
[H H[H]]]]
      
sorbitol   [H[H]H
               
[C[H]H
               
[H[H]
               
[C[H]H 
               
[C[H]H
               
[C[H]H H]]]]]]
      
benzol   [Cbenz H
               
[Cbenz H
               
[Cbenz H
               
[Cbenz H
               
[Cbenz H
               
[Cbenz H
               
[Cbenz0]]]]]]]
      
salol      [Cbenz H
               
[Cbenz H
               
[Cbenz H
               
[Cbenz H
               
[Cbenz H
               
[Cbenz [O 
                  
[Ccarboxyl O2
                  
[Cbenz
                  
[Cbenz [H]
                  
[Cbenz H
                  
[Cbenz H
                  
[Cbenz H
                  
[Cbenz H
                  
[Cbenz ]]]]]]]]]
               
[Cbenz0]]]]]]]
   
]
   
bindings=
   
[   C            C            154
      
C            Cbenz         154
      
Cbenz       Cbenz         139
      
Cbenz       Cbenz0       139
      
Cbenz       H            108
      
Cbenz       O            143
      
Cbenz       0            154
      
Ccarboxyl   Cbenz         154   ;?
      
Ccarboxyl   O2            140   ;?
      
C            H            107
      
C            O            143
      
C            O2            140   ;?
      
O            H             96
      
O            C            143
      
O            Ccarboxyl   143   ;?
   
]
   
masses=Table
   
[   C            12.011
      
Cbenz         12.011
      
Cbenz0      12.011
      
Ccarboxyl   12.011
      
O            15.999
      
O2            15.999
      
H            1.0079
   
]
   
radi=Table 
   
[   C            77.2
      
Cbenz         77.2
      
Cbenz0       0
      
Ccarboxyl   77.2
      
O            60.4
      
O2            60.4
      
H            37.3
   
]
   
cols=Table 
   
[   C            grey
      
Cbenz       grey
      
Cbenz0       black
      
Ccarboxyl   grey
      
O            red
      
O2            red
      
H            white
   
]
   
elng=Table
   
[   C            2.55
      
Cbenz         2.55   ;?
      
Cbenz0      0
      
Ccarboxyl   2.55   ;?
      
O            3.44
      
O2            3.44   ;?
      
H            2.2
   
]
   
rfactor=0.5
   
drfactor=1.02
   
rrandom=1
   
dt=0.0001
   
damping=0.99
   
   
bind=generateBindings
   
charges=computeChargesTable
   
tau=109.47
   
tau1=180-tau
   
molarray=Array toList :molecules
   
molnames=firsts molarray
   
   
perspective
;   setScreenColor "black
   
setScreenColor RGB 0 0 .2
   
WindowMode
   
enableCylinderLines
   
disableShadows
;   enableShadows
   
clearShadows
   
setShadowColor "black
   
setLightSpecular RGB .6 .6 .6
   
setMaterialSpecular "grey
   
setMaterialShininess 100
   
setUpdateGraph false
   
setProcessIdleInterleaving intmax
   
myframe=(Frame [][ChemFrame] 
      
wxdefault_frame_style+wxstay_on_top+wxframe_tool_window
      
[0 650][300 300])
   
mylistbox=(ListBox myframe [Chem Demos][]
      
[   odemoNr=demoNr
         
demoNr=(first ListBoxSelections)+1
         
OnMouseLeftDown []
         
OnMouseLeftUp []
         
OnMouseMotion []
         
ConsoleSetFocus
         
throw "nextDemo
      
])
      
   
video=false
   
bvideo=(CheckBox myframe [&Video]
   
[   ifelse video
      
[   VideoEnd 
         
video=false
      
][   (VideoStart Word molnames.demoNr ".divx 25)
         
video=true
      
]
      
ConsoleSetFocus
   
])
   
   
applyE_Field=true
   
bapplyE_Field=(CheckBox myframe [&Apply E Field]
   
[   applyE_Field=not applyE_Field
      
ConsoleSetFocus
      
throw "nextDemo
   
])
   
CheckBoxSet bapplyE_Field applyE_Field

   
showDipol=true
   
bshowDipol=(CheckBox myframe [&Show Dipol]
   
[   showDipol=not showDipol
      
ConsoleSetFocus
      
throw "nextDemo
   
])
   
CheckBoxSet bshowDipol showDipol

   
showTensor=true
   
bshowTensor=(CheckBox myframe [&Show Tensor]
   
[   showTensor=not showTensor
      
ConsoleSetFocus
      
throw "nextDemo
   
])
   
CheckBoxSet bshowTensor showTensor
   
   
showBox=true
   
bshowBox=(CheckBox myframe [&Show Box]
   
[   showBox=not showBox
      
ConsoleSetFocus
      
throw "nextDemo
   
])
   
CheckBoxSet bshowBox showBox
   
   
showAxes=false
   
bshowAxes=(CheckBox myframe [&Show Axes]
   
[   showAxes=not showAxes
      
ConsoleSetFocus
      
throw "nextDemo
   
])
   
CheckBoxSet bshowAxes showAxes
   
   
showGrid=false
   
bshowGrid=(CheckBox myframe [&Show Grid]
   
[   showGrid=not showGrid
      
ConsoleSetFocus
      
throw "nextDemo
   
])
   
CheckBoxSet bshowGrid showGrid
   
   
shadows=false
   
ifelse shadows [enableShadows][clearShadows disableShadows]
   
bshadows=(CheckBox myframe [&Draw Shadows]
   
[   shadows=not shadows
      
ifelse shadows [enableShadows][clearShadows disableShadows]
      
ConsoleSetFocus
      
throw "nextDemo
   
])
   
CheckBoxSet bshadows shadows
   
   
slrfactor=(Slider myframe [R factor]
      
Int rfactor*100 100 
      
[   rfactor=SliderValue/100
         
broken=true
         
ConsoleSetFocus
      
wxhorizontal)

   
transparency=0
   
sltrans=(Slider myframe [Transparency]
      
Int transparency*100 100 
      
[   transparency=SliderValue/100
         
broken=true
         
ConsoleSetFocus
      
wxhorizontal)

   
w1=0
   
w2=0
   
w3=0
   
W_1=toMatrix 
   
(list
      
(list   cos w1    -sin w1   0)
      
(list   sin w1     cos w1   0)
      
(list   0          0         1)
   
)
   
W_2=toMatrix 
   
(list
      
(list   1   0         0     )
      
(list   0   cos w2 -sin w2)
      
(list   0   sin w2  cos w2)
   
)
   
W_3=toMatrix 
   
(list
      
(list    cos w3     sin w3)
      
(list    0          1 0      )
      
(list -sin w3     cos w3)
   
)
   
W=W_1*W_2*W_3
   
slw1=(Slider myframe [w1] -10 Int w1*2 10 
   
[   w1=SliderValue/2
      
W_1=toMatrix 
      
(list
         
(list   cos w1    -sin w1   0)
         
(list   sin w1     cos w1   0)
         
(list   0          0         1)
      
)
      
W=W_1*W_2*W_3
      
ConsoleSetFocus
   
wxhorizontal)

   
slw2=(Slider myframe [w2] -10 Int w2*2 10 
   
[   w2=SliderValue/2
      
W_2=toMatrix 
      
(list
         
(list   1   0         0     )
         
(list   0   cos w2 -sin w2)
         
(list   0   sin w2  cos w2)
      
)
      
W=W_1*W_2*W_3
      
ConsoleSetFocus
   
wxhorizontal)

   
slw3=(Slider myframe [w3] -10 Int w3*2 10 
   
[   w3=SliderValue/2
      
W_3=toMatrix 
      
(list
         
(list    cos w3     sin w3)
         
(list    0          1 0      )
         
(list -sin w3     cos w3)
      
)
      
W=W_1*W_2*W_3
      
ConsoleSetFocus
   
wxhorizontal)

   
slowdown=false
   
bslowdown=(Button myframe [&Break]
   
[   slowdown=true
      
ConsoleSetFocus
   
])
   
bquit=(Button myframe [&Quit][throw "stopping])
   
bsh=BoxSizer wxhorizontal
   
bsv=StaticBoxSizer wxvertical myframe [Options]
   
BoxSizerAdd bsh mylistbox 100 wxexpand 0
   
BoxSizerAdd bsv bvideo 100 wxexpand 0
   
BoxSizerAdd bsv bapplyE_Field 100 wxexpand 0
   
BoxSizerAdd bsv bshowDipol 100 wxexpand 0
   
BoxSizerAdd bsv bshowTensor 100 wxexpand 0
   
BoxSizerAdd bsv bshowBox 100 wxexpand 0
   
BoxSizerAdd bsv bshowAxes 100 wxexpand 0
   
BoxSizerAdd bsv bshowGrid 100 wxexpand 0
   
BoxSizerAdd bsv bshadows 100 wxexpand 0
   
BoxSizerAdd bsv bslowdown 100 wxexpand 0
   
BoxSizerAdd bsv bquit 100 wxexpand 0
   
BoxSizerAdd bsh bsv 100 0 0
   
bsw=StaticBoxSizer wxvertical myframe [Parameters]
   
BoxSizerAdd bsw slrfactor 150 wxexpand 0
   
BoxSizerAdd bsw sltrans 150 wxexpand 0
   
BoxSizerAdd bsw slw1 150 wxexpand 0
   
BoxSizerAdd bsw slw2 150 wxexpand 0
   
BoxSizerAdd bsw slw3 150 wxexpand 0
   
BoxSizerAdd bsh bsw 100 0 0
   
FrameSetSizer myframe bsh
   
FrameSetClientSize myframe 300 300
   
foreach molnames
   
[   ListBoxAppend mylistbox ?
   
]
   
ConsoleSetFocus
   
pplus=FloatArray {0 0 0}
   
pminus=FloatArray {0 0 0}
   
qplus=0
   
qminus=0
   
mtotal=0
   
dipolmoment=0
   
Mm=FloatArray {0 0 0}
   
ow1=0
   
ow2=0
   
ow3=0
   
dw1=0
   
dw2=0
   
dw3=0
   
demoNr=1
   
odemoNr=0
   
mat=ModelviewMatrix
   
mcenter=FloatArray last mat
   
R=toMatrix butLast mat

   
running=true
   
broken=false
   
catch "stopping
   
[   while [running]
      
[   ready=false
         
catch "nextDemo
         
[   clearScreen
            
grOutside=Graphic
            
[   if shadows [clearShadows]
               
if showBox [drawBox]
               
if showAxes [drawAxes]
               
if showGrid [drawGrid]
               
setPenSize 7
               
enableBlend
               
setLightModelTwoSide 1
               
Home
            
]
            
if (demoNr != odemoNror2 broken
            
[   pmass=FloatArray {0 0 0}
               
positions=(list FloatArray pmass)
               
charge=(list 0)
               
mass=(list 0)
               
penAlwaysUp=true
               
construct (molarray.(Int demoNr)).2 
                  
&positions &charge &mass 0
               
penAlwaysUp=false
               
qs=[]
               
ps=[]
               
ms=[]
               
flatten charge &qs positions &ps mass &ms
               
qs=Array qs
               
ps=Array ps
               
ms=Array ms
               
computeMassCenter ms ps
               
pmass0=pmass
            
]
            
Home
            
grMolecule=Graphic
            
[   PenUp setPosXYZ -pmass0 PenDown
               
positions=(list FloatArray {0 0 0})
               
charge=(list 0)
               
mass=(list 0)
               
construct (molarray.(Int demoNr)).2 
                  
&positions &charge &mass 0
               
qs=[]
               
ps=[]
               
ms=[]
               
flatten charge &qs positions &ps mass &ms
               
qs=Array qs
               
ps=Array ps
               
ms=Array ms
               
if showDipol
               
[   computeChargeCenters qs ps
                  
drawDipol
               
]
               
computeMassCenter ms ps
               
computeInertialTensor ms ps
               
m=toMatrix I_tensor
               
I_eigenvecs=Eigenvectors m
               
v=Array Eigenvalues m
               
v=FloatArray Array (list v.(1).1 v.(2).2 v.(3).3)
               
I_eigenvals=v
;pr I_eigenvals
;pr I_eigenvecs
               
if showTensor
               
[   drawMassCenter
               
]
            
]
            
if shadows [castShadows]
            
broken=false
            
ready=true
            
T1=I_eigenvecs
            
T=invertMatrix I_eigenvecs
            
rotatescene3
         
]
      
]
   
]
   
setUpdateGraph true
   
FrameDestroy myframe
   
updateGraph
   
OnMouseLeftDown []
   
OnMouseLeftUp []
   
OnMouseMotion []
   
ConsoleSetFocus

be construct mol &positions &charge &mass prev
   
local [p0 o0 p cb q m c]
   
p0=FloatArray PosXYZ
   
p=(list p0)
   
cb=-chargebind prev mol.1
   
ifelse cb != []
   
[   q=(list cb)
   
][   q=(list 0)
   
]
;(pr q prev mol.1)
;if q==[[]] [pause]
   
if (count charge) > and2 (prev != 0)
   
[   charge.1=charge.1-q.1
;(show charge.1 prev mol.1)
   
]
   
m=masses.(mol.1)
   
if empty? [m=pr 5]
   
m=(list m)
   
setPenColor cols.(mol.1)
   
if transparency != 0
   
[   c=reRGBA PenColor
      
c.4=c.4*(1-transparency)
      
setPenColor c
   
]
;   disableDepthTest
   
if not penAlwaysUp
   
[   Sphere radi.(mol.1)*rfactor
   
]
;   (Sphere radi.(mol.1) 10 10)
;   enableDepthTest
   
setPenColor "white
   
if not List? mol 
   
[   positions=lput p positions
      
charge=lput q charge
      
mass=lput m mass
      
stop
   
]
   
ifelse mol.1=="C
   
[   if (count mol) > 1
      
[   mol=butFirst mol
         
rightRoll 180 
         
store
         
leftRoll 60 
         
downPitch tau1 fd binding "C mol.1
            
construct mol.1 &&&"C
         
restore
         
if (count mol) > 1
         
[   rightRoll 60
            
downPitch tau1 fd binding "C mol.2
               
construct mol.2 &&&"C
            
restore
            
if (count mol) > 2
            
[   upPitch tau1 fd binding "C mol.3 
                  
construct mol.3 &&&"C
               
restore
               
if (count mol) > 3
               
[   right 180 rightRoll tau fd binding "C mol.4
                     
construct mol.4 &&&"C
                  
restore
               
]
            
]
         
]
      
]
   
][
   
ifelse mol.1=="Cbenz
   
[   if (count mol) > 1
      
[   mol=butFirst mol
         
store
         
left 60 fd binding "Cbenz mol.1
            
construct mol.1 &&&"Cbenz
         
restore
         
if (count mol) > 1
         
[   right 60 fd binding "Cbenz mol.2
               
construct mol.2 &&&"Cbenz
            
restore
            
if (count mol) > 2
            
[   right 180 fd binding "Cbenz mol.3 
                  
construct mol.3 &&&"Cbenz
               
restore
            
]
         
]
      
]
   
][
   
ifelse mol.1=="Ccarboxyl
   
[   if (count mol) > 1
      
[   mol=butFirst mol
         
store
         
left 60 fd binding "Ccarboxyl mol.1 rightRoll 90
            
construct mol.1 &&&"Ccarboxyl
         
restore
         
if (count mol) > 1
         
[   right 60 fd binding "Ccarboxyl mol.2 rightRoll 90
               
construct mol.2 &&&"Ccarboxyl
            
restore
            
if (count mol) > 2
            
[   right 180 fd binding "Ccarboxyl mol.3 rightRoll 90
                  
construct mol.3 &&&"Ccarboxyl
               
restore
            
]
         
]
      
]
   
][
   
ifelse mol.1=="O2
   
[][
   
ifelse mol.1=="O
   
[
      
if (count mol) > 1
      
[   mol=butFirst mol
         
store
         
downPitch tau1 fd binding "O mol.1
            
construct mol.1 &&&"O
         
restore
         
if (count mol) > 1
         
[   store
            
upPitch tau1 fd binding "O mol.1
               
construct mol.1 &&&"O
            
restore
         
]
      
]
   
][
   
ifelse mol.1=="Cbenz0
   
[   stop
   
][]]]]]]
   
positions=lput p positions
   
charge=lput q charge
   
mass=lput m mass

   
be store
      
p0=PosXYZ
      
o0=Orientation
   
end

   
be restore
      
PenUp setPosXYZ p0 setOrientation o0 
      
if not penAlwaysUp [PenDown]
   
end
end

be binding a b
   
while [List? a][a=a.1]
   
while [List? b][b=b.1]
   
local [w]
   
w=(word "_ b)
;pr w
   
output bind.w
end

be chargebind a b
   
while [List? a][a=a.1]
   
while [List? b][b=b.1]
   
local [w c]
   
w=(word "_ b)
   
c=charges.w
;(pr w c)
   
output c
end

be generateBindings
   
local [l b]
   
l=bindings
   
b=Table 31
   
while [not empty? l]
   
[   setItem (word l.1 "_ l.2b l.3
      
setItem (word l.2 "_ l.1b l.3
      
l=bf bf bf l
   
]
   
output b
end

be computeChargesTable
   
local [l b]
   
l=bindings
   
c=Table 31
   
while [not empty? l]
   
[   ifelse (last l.2)==0
      
[   setItem (word l.1 "_ l.20
         
setItem (word l.2 "_ l.10
      
][   setItem (word l.1 "_ l.2c elng.(l.2)-elng.(l.1)
         
setItem (word l.2 "_ l.1c elng.(l.1)-elng.(l.2)
      
]
      
l=bf bf bf l
   
]
   
output c
end

be flatten &out l2 &out2 l3 &out3
   
ifelse list? l
   
[   while [not empty? l]
      
[   flatten l.1 &out l2.1 &out2 l3.1 &out3
         
l=bf l
         
l2=bf l2
         
l3=bf l3
      
]
   
][   out=lput l out
      
out2=lput l2 out2
      
out3=lput l3 out3
   
]
end

be computeMassCenter ms ps
   
pmass=FloatArray {0 0 0}
   
mtotal=0
   
repeat count ms
   
[   i=repCount
      
mtotal=mtotal+ms.i
      
pmass=pmass+ps.i*ms.i
   
]
   
pmass=pmass/mtotal
end

be delta i j
   
ifelse i==[output 1][output 0]
end

be computeInertialTensor ms ps
   
I=Array 3
   
I.1=FloatArray {0 0 0}
   
I.2=FloatArray {0 0 0}
   
I.3=FloatArray {0 0 0}
   
repeat count ms
   
[   j=repCount
      
m=ms.j
      
r=ps.j-pmass
      
for [1 3]
      
[   for [1 3]
         
[   I.k.l=I.k.l-m*(r.k*r.l)
         
]
         
I.k.k=I.k.k+m*(0+r*r)
      
]
   
]
;pr I
   
I_tensor=I
end

be drawMassCenter
;   local [evals evecs]
   
evecs=Array I_eigenvecs
   
evals=I_eigenvals/(Norm I_eigenvals)
   
setPenColor "lightgreen
;   Arrow pmass pmass+evecs.1
;   Arrow pmass pmass+evecs.2
;   Arrow pmass pmass+evecs.3
   
PenUp   Home PenDown setPosXYZ evecs.1*200
   
PenUp   Home PenDown setPosXYZ evecs.2*200
   
PenUp   Home PenDown setPosXYZ evecs.3*200
   
setPenColor "blue
   
setPenSize 2
;   PenUp   Home PenDown setPosXYZ evecs.1/evals.1
;   PenUp   Home PenDown setPosXYZ evecs.2/evals.2
;   PenUp   Home PenDown setPosXYZ evecs.3/evals.2
   
PenUp Home setPosXYZ pmass Sphere 3
   
setTowardsXYZup pmass+evecs.1 evecs.3
   
PenDown
   
setPenColor HSBA 120 0.6 0.2 0.5
   
;   Home
;   setPosXYZ pmass
;   disableDepthTest
   
(Ellipsoid 
      
50/((abs evals.2)+0.01) 
      
50/((abs evals.1)+0.01) 
      
50/((abs evals.3)+0.01))
;   enableDepthTest
end

be computeChargeCenters qs ps
   
pplus=FloatArray {0 0 0}
   
pminus=FloatArray {0 0 0}
   
qplus=0
   
qminus=0
   
repeat count qs
   
[   i=repCount
      
if qs.0
      
[   qplus=qplus+qs.i
         
pplus=pplus+ps.i*qs.i
      
]
      
if qs.0
      
[   qminus=qminus+qs.i
         
pminus=pminus+ps.i*qs.i
      
]
   
]
   
pplus=pplus/qplus
   
pminus=pminus/qminus
   
dipolmoment=(pplus-pminus)*(qplus-qminus)
end

be drawDipol
   
setPenColor "lightblue
   
if (Norm pplus-pminus) > 1
   
[   Arrow pminus pplus
      
Wire pminus pplus
   
]
   
PenDown
end

be Arrow a b
   
local [l lSpitze p ori]
   
PenUp
   
setPosXYZ a
   
setOrientation towardsXYZ b
   
l=Norm b-a
   
lSpitze=l/3
   
p=PosXYZ
   
ori=Orientation
   
PD fd l-lSpitze*0.8
   
PU back lSpitze*0.2   
   
(Cylinder lSpitze PenSize.1 0)
   
setPosXYZ p
   
setOrientation ori
end

be Wire a b
   
local [l p ori ps]
   
PenUp
   
setPosXYZ a
   
setOrientation towardsXYZ b
   
l=Norm b-a
   
p=PosXYZ
   
ori=Orientation
   
ps=PenSize
   
setPenSize 4
   
back l*4
   
PenDown forward l*9
   
PenUp
   
setPenSize ps
   
setPosXYZ p
   
setOrientation ori
end

be drawBox
   
local [size]
   
size=3000
   
pu setY -size
   
setPenColor RGB 0 0 0.2
   
PolyStart
   
setX -size pd setZ size setX size setZ -size setX -size pu
   
PolyEnd
   
setPenColor RGB 0.2 0 0
   
PolyStart
   
pd setY size setZ size setY -size setZ -size pu
   
PolyEnd
   
setPenColor RGB 0 0.2 0
   
PolyStart
   
setY -size pd setX size setY size setX -size setY -size pu
   
PolyEnd
   
setX size
   
setPenColor RGB 0.2 0.2 0
   
PolyStart
   
pd setY size setZ size setY -size setZ -size pu
   
PolyEnd
   
setY size
   
setPenColor RGB 0 0.2 0.2
   
PolyStart
   
setX -size pd setZ size setX size setZ -size setX -size pu
   
PolyEnd
   
Home
end

be drawAxes
   
local [ps size]
   
size=2000
   
ps=PenSize
   
setPenSize 2
   
pu   setX -size pd setX size 
   
pu setXY -size pd setY size
   
pu setXYZ 0 0 -size pd setZ size
   
pu
   
setPenSize ps
   
Home
end

be drawGrid
   
if showGrid
   
[   local [ps gridcolor size z]
      
ps=PenSize
      
setPenSize 2
      
gridcolor=RGB 0.5 0.5 0.5
      
size=300
      
z=size
      
for [-size size 100]
      
[   for [-size size 100]
         
[   PenUp
            
setXYZ x y -z
            
PenDown
            
setXYZ x y  z
            
PenUp
            
setXYZ -z y
            
PenDown
            
setXYZ x  z y
            
PenUp
            
setXYZ -z x y
            
PenDown
            
setXYZ  z x y
         
]
      
]
      
pu
      
setPenSize ps
      
Home
   
]
end

be rotatescene3
;   local [eye r dr ddphi theta center upvector]
   
singleshot=Name? "framenr
   
if singleshot [phi=framenr*10]
   
if not Name? "ddphi
   
[   eye=array 3
      
light=array 3
      
eyecenter=500
      
phi=10
      
dphi=;0.5
      
ddphi=0.2
      
theta=30
      
dtheta=0
      
ddtheta=0.2
      
dpsi=0
      
ddpsi=0.2
      
l=eyecenter ;200
      
deyecenter=1
      
ddeyecenter=1.003
      
dcenterx=0
      
dcentery=0
      
dcenterz=0
      
dx=1
      
ophi=phi
      
otheta=theta
      
oldeyecenter=eyecenter
      
center=FloatArray {0 0 0}
      
upvector=FloatArray {0 1 0}
      
upv=upvector
      
slowdown=false
      
slower=0.9
      
mind=0.005
      
PenUp
      
Home
      
down 90
      
center=FloatArray PosXYZ
      
ori=Orientation
   
]
;comment[
   
mouseActive=false
   
p0=MouseWindowPos
   
mp=MouseWindowPos-p0
   
dispatchMessages
   
OnMouseLeftDown 
   
[   if not mouseActive
      
[   p0=MouseWindowPos
         
mouseActive=true
      
]
      
ConsoleSetFocus
   
]
   
OnMouseMotion
   
[   if mouseActive
      
[   mp=MouseWindowPos-p0
         
dphi=0
         
dtheta=0
         
if mp.1 [dphi=-mp.1/100]
         
if mp.1 <-[dphi=-mp.1/100]
         
if mp.2 [dtheta=mp.2/100]
         
if mp.2 <-[dtheta=mp.2/100]
      
]
   
]
   
OnMouseLeftUp
   
[   mp=MouseWindowPos-p0
      
dphi=0
      
dtheta=0
      
if mp.1 [dphi=-mp.1/100]
      
if mp.1 <-[dphi=-mp.1/100]
      
if mp.2 [dtheta=mp.2/100]
      
if mp.2 <-[dtheta=mp.2/100]
      
mouseActive=false
   
]
   
WindowOnLeaveWindow GraphCurrent [mouseActive=false]
   
   
forever
   
[   PenUp
      
setPosXYZ center
      
setOrientation ori
      
back eyecenter
      
eye=FloatArray PosXYZ
      
up 90
      
forward 1
      
upv=(FloatArray PosXYZ)-eye
      
back 1
      
down 90
      
forward eyecenter
      
setEye eye center upv
      
left dphi
      
downPitch dtheta
      
leftRoll dpsi
      
forward dcenterz
      
up 90
      
forward dcentery
      
down 90
      
right 90
      
forward dcenterx
      
left 90
      
center=FloatArray PosXYZ
      
ori=Orientation
;      setLightPos light
;      redraw
      
clearScreen
      
drawGraphic grOutside

      
MM=ModelviewMatrix
      
M=toMatrix butlast MM
      
M1=invertMatrix M
      
mcenter=FloatArray last MM
      
pushMatrix
      
R=T1*W*T*R
      
(setModelviewMatrix R*M mcenter)
      
drawGraphic grMolecule
      
popMatrix
   
      
if applyE_Field
      
[
;         for [j 1 1]
;         [
            
oM=Mm
            
MI=transposeMatrix toMatrix (list tolist dipolmoment)
            
Mm=Array T1*MI
            
Mm=cross Mm.1 FloatArray {0 1 0}
            
dM=(Mm-oM)/dt
            
            
I=I_eigenvals/200000
            
dw1=(Mm.1+(I.2-I.3)*w2*w3)/I.1
            
dw2=(Mm.2+(I.3-I.1)*w3*w1)/I.2
            
dw3=(Mm.3+(I.1-I.2)*w1*w2)/I.3
            
ddw1=(dM.1+(I.2-I.3)*(dw2*w3+w2*dw3))/I.1
            
ddw2=(dM.2+(I.3-I.1)*(dw3*w1+w3*dw1))/I.2
            
ddw3=(dM.3+(I.1-I.2)*(dw1*w2+w1*dw2))/I.3
      
;      ow1=w1
      ;      ow2=w2
      ;      ow3=w3
            
w1=(w1+dw1*dt+ddw1/2*sqr dt)*damping
            
w2=(w2+dw2*dt+ddw2/2*sqr dt)*damping
            
w3=(w3+dw3*dt+ddw3/2*sqr dt)*damping
      
;      dw1=(w1-ow1)/dt
      ;      dw2=(w2-ow2)/dt
      ;      dw3=(w3-ow3)/dt   
            
W_1=toMatrix 
            
(list
               
(list   cos w1    -sin w1   0)
               
(list   sin w1     cos w1   0)
               
(list   0          0         1)
            
)
            
W_2=toMatrix 
            
(list
               
(list   1   0         0     )
               
(list   0   cos w2 -sin w2)
               
(list   0   sin w2  cos w2)
            
)
            
W_3=toMatrix 
            
(list
               
(list    cos w3     sin w3)
               
(list    0          1 0      )
               
(list -sin w3     cos w3)
            
)
            
W=W_1*W_2*W_3
;            R=T1*W*T*R
;         ]
      
]
   
      
updateGraph
      
if video [VideoFrame]
      
if singleshot [break]
      
eyecenter=eyecenter*deyecenter
;      while [(and dphi==0 dpsi==0 dtheta==0 deyecenter==1 (not Key?)
;         dcenterx==0 dcentery==0 dcenterz==0)]
;      [   dispatchMessages
;         waitMS 20
;      ]
      
dispatchMessages
      
ophi=phi
      
otheta=theta
      
oldeyecenter=eyecenter
      
if slowdown
      
[   dphi=dphi*slower
         
dtheta=dtheta*slower
         
dpsi=dpsi*slower
         
dcenterx=dcenterx*slower
         
dcentery=dcentery*slower
         
dcenterz=dcenterz*slower
         
deyecenter=(deyecenter-1)*slower+1
         
if (abs dphi) < mind [dphi=0]
         
if (abs dtheta) < mind [dtheta=0]
         
if (abs dpsi) < mind [dpsi=0]
         
if (abs dcenterx) < mind [dcenterx=0]
         
if (abs dcentery) < mind [dcentery=0]
         
if (abs dcenterz) < mind [dcenterz=0]
         
if (abs deyecenter-1) < mind [deyecenter=1]
      
]
      
if key? 
      
[   slowdown=false
         
local [ch]
         
ch=readChar
         
ifelse ch>=char 255
         
[   ch=readCharExt
            
ifElse (BitAnd MouseButtons 16)==16
            
[   if ch==wxk_right [dcenterx=dcenterx+dx]
               
if ch==wxk_left  [dcenterx=dcenterx-dx]
               
if ch==wxk_up    [dcentery=dcentery+dx]
               
if ch==wxk_down  [dcentery=dcentery-dx]
               
if ch==wxk_prior [dcenterz=dcenterz+dx]
               
if ch==wxk_next  [dcenterz=dcenterz-dx]
            
][
               
if ch==wxk_right [dphi=dphi+ddphi]
               
if ch==wxk_left  [dphi=dphi-ddphi]
               
if ch==wxk_up    [dtheta=dtheta+ddtheta]
               
if ch==wxk_down  [dtheta=dtheta-ddtheta]
               
if ch==wxk_prior [deyecenter=deyecenter/ddeyecenter]
               
if ch==wxk_next  [deyecenter=deyecenter*ddeyecenter]
            
]
         
][
            
if ch==char 27 
            
[   OnMouseLeftDown []
               
OnMouseLeftUp []
               
OnMouseMotion []
               
throw "stopping
            
]
            
if ch=="x [dpsi=dpsi+ddpsi]
            
if ch=="y [dpsi=dpsi-ddpsi]
            
if ch=="+ 
            
[   if demoNr count molnames 
               
[   demoNr=demoNr+1 
                  
ListBoxSetSelections mylistbox (list demoNr-1)
                  
throw "nextDemo
               
]
            
]
            
if ch=="- 
            
[   if demoNr 1              
               
[   demoNr=demoNr-1
                  
ListBoxSetSelections mylistbox (list demoNr-1)
                  
throw "nextDemo
               
]
            
]
            
if ch=="   
            
[   slowdown=true
            
]
            
if ch=="r 
            
[   rfactor=rfactor/drfactor
               
throw "nextDemo
            
]
            
if ch=="R
            
[   rfactor=rfactor*drfactor
               
throw "nextDemo
            
]
            
if ch=="t 
            
[   if transparency >= 0.05 
               
[   transparency=transparency-0.05
               
]
               
throw "nextDemo
            
]
            
if ch=="T 
            
[   if transparency <= 1-0.05 
               
[   transparency=transparency+0.05
               
]
               
throw "nextDemo
            
]
         
]
      
]
      
yield
      
if broken [stop]
   
]
end

end