SharedICA-solutions / revolving-sphere.ipynbOpen in CoCalc
from vpython import *
from numpy import linspace
#Unit coordinate vectors
e1=vector(1,0,0)
e2=vector(0,1,0)
e3=vector(0,0,1)
e1Arrow=arrow(axis=e1,color=color.red)
e2Arrow=arrow(axis=e2,color=color.green)
e3Arrow=arrow(axis=e3,color=color.blue)

#Two random vectors
u1=vector(random(),random(),random())
n=vector(random(),random(),random())
#Make them orthogonal by subtracting from n its projection onto u1:
n=n - n.proj(u1)
#A unit vector orthogonal to u1 and n:
u2=cross(n.hat,u1.hat)

p=vector(1,1,1)
u1Arrow=arrow(axis=u1.hat,pos=p)
#vArrow=arrow(axis=u1.hat,pos=p)
u2Arrow=arrow(axis=u2.hat,pos=p)
nArrow=arrow(axis=n.hat,pos=p,color=color.yellow)

#Two spheres:
Sphere1=sphere(pos=p, 
          radius=0.3, color=color.red)
Sphere2=sphere(pos=p+u1.hat, 
               radius=0.3, texture="https://upload.wikimedia.org/wikipedia/commons/c/c3/Uniform_tiling_63-t012.png")

#Visuals for the angle of rotation
disc=shapes.circle(radius=0.05)

#This doesn't quite work, because the extrusion
#is in a plane parallel to the e1e3 plane
torus=extrusion(pos=p,shape=disc, path=paths.arc(radius=1,angle2=2*pi),color=color.cyan)
#Could do this:
from numpy import arccos
torus.rotate(origin=p, axis=e2.cross(n), angle=arccos(e2.dot(n.hat)))

#Alternatively, define a path manually, using parametrization of the circle:
#circleInPlane=[ cos(theta)*u1.hat + sin(theta)*u2.hat for theta in linspace(0,2*pi+0.1,50) ]
#torus=extrusion(pos=p,shape=disc, path=circleInPlane)



dt = 0.01
while 1:
    rate (100)
    Sphere2.rotate(angle=dt,axis=n.hat,origin=p)
#    vArrow.rotate(angle=dt,axis=n.hat,origin=p)
(not running untrusted Javascript)(not running untrusted Javascript)(not running untrusted Javascript)(not running untrusted Javascript)(not running untrusted Javascript)(not running untrusted Javascript)
(not running untrusted Javascript)
ERROR! Session/line number was not unique in database. History logging moved to new session 210
n
<0.307926, 0.0584762, -0.0607772>
1