# www.contextfreeart.org/gallery/view.php?id=3732

startshape Menage_a_trois // Render to size (900*420) CF::Frame=150/360 // Save Image Ctrl-i CF::Time =[time 0 1] // Save Movie Ctrl-m CF::Size =[y -0.2 s 15 7] //————————- CF::Background=[b -1] CF::Impure=1

//————————————————— // Parametric model Complexification: Z1^3 + Z2^3 = 1 //————————————————— vector3 Param3D(i,j,k1,k2)=let(

Z = (i/16*90,j/16-2);   // ( 0<= X <=90, -2< Y <2 )
//-----  Z1=cos(Z)^(2/3)*exp(2π*i*k1/3)  ----------
Zc= (cos(Z[0])*cosh(Z[1]),-sin(Z[0])*sinh(Z[1]));
rc= (Zc[0]^2+Zc[1]^2)^(1/3);             // Abs(Z1)
ac= atan2(Zc[1],Zc[0])*(2/3)+360*k1/3;   // Arg(Z1)
Z1=(rc*cos(ac),rc*sin(ac));
//-----  Z2=sin(Z)^(2/3)*exp(2π*i*k2/3)  ----------
Zs= (sin(Z[0])*cosh(Z[1]), cos(Z[0])*sinh(Z[1]));
rs= (Zs[0]^2+Zs[1]^2)^(1/3);             // Abs(Z2)
as= atan2(Zs[1],Zs[0])*(2/3)+360*k2/3;   // Arg(Z2)
Z2=(rs*cos(as),rs*sin(as));
//-----  Projection 4D->3D and Rotation  ---------- 
Xp= Z1[0]*cos(360*frame())+Z2[0]*sin(360*frame());
(Z2[1], sqrt(1/2)*(Xp-Z1[1]), sqrt(1/2)*(Xp+Z1[1]))

)

vector2 Pcanvas(vector3 V)= // Projection to canvas

( V[0]/(1-V[2]/8), V[1]/(1-V[2]/8) )

vector3 Stereo(LR,vector3 V)=let( // Stereoscopic

C=cos(LR*3); S=sin(LR*3); // Left,Right perspective
( S*V[2]+C*V[0], V[1], C*V[2]-S*V[0] )

) //————————————————— path Quad_path(vector12 Q4, A, d){ // Draw to canvas

MOVETO(Pcanvas(Q4[0,3]))   LINETO(Pcanvas(Q4[3,3]))
LINETO(Pcanvas(Q4[6,3]))   LINETO(Pcanvas(Q4[9,3]))
CLOSEPOLY()    FILL[a A]   STROKE(0.025/d)[b -1]

}

shape Quad(LR, vector12 Q4, H,A){ // 3D-Quadrilateral

P00= Stereo(LR, Q4[0,3])  P10= Stereo(LR, Q4[3,3])
P01= Stereo(LR, Q4[9,3])  P11= Stereo(LR, Q4[6,3])
Xm = (P00[0]+P10[0]+P11[0]+P01[0])/4
Ym = (P00[1]+P10[1]+P11[2]+P01[1])/4
Zm = (P00[2]+P10[2]+P11[2]+P01[2])/4
d  = sqrt(Xm^2+Ym^2+(8-Zm)^2)   // Distance to eye
Sat= (2-d/8)*0.6          // Diminish Sat by dist.
B  = (2-d/8)              // Diminish Brightness
Q4p=(P00, P10, P11, P01)  // Quadrilat. perspective
Quad_path(Q4p, A, d)[h H sat Sat b B z -d]

}

shape Menage_a_trois{

loop k1=3 [] loop k2=3 []       // Fase patches
loop i=16 [] loop j=64 []       // Squares
if (abs(63-2*j)>= 56            // cut out Circles
    || 6<=i && i<10 ) {         //     and Bridges
  P00= Param3D(i  ,j  ,k1,k2)   // 4 vertices of
  P10= Param3D(i+1,j  ,k1,k2)   //   Quadrilateral
  P11= Param3D(i+1,j+1,k1,k2)   
  P01= Param3D(i  ,j+1,k1,k2)
  Q4 =(P00, P10, P11, P01)      // Compose vectors

  Crc= mod(2*k1+k2,3)           // Circle 0, 1, 2
  Brd= min(max(0,j-4),56)/56    // Bridge 0..1
  C  = mod(Crc+Brd,3)           // Color  0..1..2..
  Fc = (14-C*(9-C*(14-3*C)))/32 // Color shifting 
  H  = 120*Fc*C                 // Hue

  A  = if(mod(i+j,2),0,-0.5)    // Checker pattern

  Quad(-1, Q4, H, A)[x -3.5]    // Stereo Left
  Quad(+1, Q4, H, A)[x +3.5]    // Stereo Right

} }