#
# Some examples of animated 3d bisector computations of 3-space freeform crvs.
#
#			Gershon Elber, August 1996.
#

speed = 5;
FileCount = 1000;

view_mat = view_mat * sc( 0.4 );
viewobj( view_mat );
viewstate( "DepthCue", 0 );

polesFree = function( Srf, Dpth, TMin, TMax ):
     return = nil();
polesFree = function( Srf, Dpth, TMin, TMax ): Srfs: t:
     if ( !ffpoles( Srf ),
	  return = list( Srf ),
	  if ( Dpth <= 0,
	       return = nil(),
	       t = ( TMin + TMax ) / 2:
	       Srfs = sdivide( Srf, row, t ):
	       return = polesFree( nth( Srfs, 1 ), Dpth - 1, TMin, t ) +
		        polesFree( nth( Srfs, 2 ), Dpth - 1, t, TMax ) ) );

#
# Save the sequence into files for high quality rendering.
#
comment $

save( "view", list( view_mat, prsp_mat ) );

DisplayCirc = circle( vector( 0.0, 0.0, 0.0 ), 0.015 );
DisplayCirc2 = circle( vector( 0.0, 0.0, 0.0 ), 0.025 );

display = procedure( c1, c2, BiSrf ): s1: s2: BiSrfIsos:
    attrib( BiSrf, "transp", 0.25 ):
    color( BiSrf, red ):
    BiSrfIsos = GetIsoCurveTubes( BiSrf, 15, 15, 0.005 ):
    attrib( BiSrfIsos, "u_resolution", 0.01 ):
    color( BiSrfIsos, magenta ):
    s1 = sweepsrf( DisplayCirc, c1, off ):
    s2 = sweepsrf( DisplayCirc, c2, off ):
    attrib( s1, "u_resolution", 0.2 ):
    attrib( s2, "u_resolution", 0.2 ):
    color( s1, yellow ):
    color( s2, yellow ):
    save( "c" + FileCount + ".itd.Z", list( s1, s2, BiSrf, BiSrfIsos ) ):
    FileCount = FileCount + 1;

display2 = procedure( c1, c2, BiSrf, iso, pt ):
	s1: s2: isoSrf: PtSpr: BiSrfIsos:
    attrib( BiSrf, "transp", 0.25 ):
    color( BiSrf, red ):
    BiSrfIsos = GetIsoCurveTubes( BiSrf, 15, 15, 0.005 ):
    attrib( BiSrfIsos, "u_resolution", 0.01 ):
    color( BiSrfIsos, magenta ):
    s1 = sweepsrf( DisplayCirc, c1, off ):
    s2 = sweepsrf( DisplayCirc, c2, off ):
    attrib( s1, "u_resolution", 0.2 ):
    attrib( s2, "u_resolution", 0.2 ):
    color( s1, yellow ):
    color( s2, yellow ):
    isoSrf = sweepsrf( DisplayCirc, iso, vector( 0, 0, 1 ) ):
    attrib( isoSrf, "u_resolution", 0.2 ):
    color( isoSrf, green ):
    PtSpr = sphere( coerce( pt, point_type ), 0.045 ):
    color( PtSpr, cyan ):
    save( "c" + FileCount + ".itd.Z",
          list( s1, s2, BiSrf, BiSrfIsos, isoSrf, PtSpr ) ):
    FileCount = FileCount + 1;

$

#
# Display the sequence into the current display device, real time.
#
display = procedure( c1, c2, BiSrf ):
    color( c1, white ):
    adwidth( c1, 3 ):
    color( c2, yellow ):
    adwidth( c2, 3 ):
    color( BiSrf, magenta ):
    view( list( c1, c2, BiSrf ), true );

display2 = procedure( c1, c2, BiSrf, iso, pt ):
    color( c1, white ):
    adwidth( c1, 3 ):
    color( c2, yellow ):
    adwidth( c2, 3 ):
    color( iso, red ):
    adwidth( iso, 3 ):
    color( pt, cyan ):
    adwidth( pt, 6 ):
    color( BiSrf, magenta ):
    view( list( c1, c2, BiSrf, iso, pt ), true );

#############################################################################
#
# Two linear curves
#

for ( b = 0.0, 0.01 * speed, 1.0,
    c1 = cbezier( list( ctlpt( E3,  0.0, -2.1, -b ),
		        ctlpt( E3,  0.0, -2.1,  b ) ) ):
    c2 = cbezier( list( ctlpt( E3, -b,    2.1,  0.0 ),
		        ctlpt( E3,  b,    2.1,  0.0 ) ) ):
    BisectSrf = cbisector( list( c1, c2 ), -1, 0.5, true, false ):
    display( c1, c2, BisectSrf ) );

for ( b = 2.0, -0.02 * speed, 0.0,
    c1 = cbezier( list( ctlpt( E3,  0.0, -0.1 - b, -1.0 ),
		        ctlpt( E3,  0.0, -0.1 - b,  1.0 ) ) ):
    c2 = cbezier( list( ctlpt( E3, -1.0,  0.1 + b,  0.0 ),
		        ctlpt( E3,  1.0,  0.1 + b,  0.0 ) ) ):
    BisectSrf = cbisector( list( c1, c2 ), -1, 0.5, true, false ):
    display( c1, c2, BisectSrf ) );

#############################################################################
#
# A line and a quadratic
#

for ( a = 0.0, 0.02 * speed, 2.0,
    c1 = cbezier( list( ctlpt( E3,  0.0, -0.1,     -1.0 ),
		        ctlpt( E3,  0.0, -0.1,      1.0 ) ) ):
    c2 = cbezier( list( ctlpt( E3, -1.0,  0.1,      0.0 ),
		        ctlpt( E3,  0.0,  0.1 + a,  0.0 ),
		        ctlpt( E3,  1.0,  0.1,      0.0 ) ) ):
    BisectSrf = cbisector( list( c1, c2 ), -1, 0.5, true, false ):
    display( c1, c2, BisectSrf ) );

#############################################################################
#
# Two quadratic curves
#

for ( a = 0.0, 0.02 * speed, 2.0,
    c1 = cbezier( list( ctlpt( E3,  0.0, -0.1,     -1.0 ),
		        ctlpt( E3,  0.0, -0.1 - a,  0.0 ),
		        ctlpt( E3,  0.0, -0.1,      1.0 ) ) ):
    c2 = cbezier( list( ctlpt( E3, -1.0,  0.1,      0.0 ),
		        ctlpt( E3,  0.0,  2.1,      0.0 ),
		        ctlpt( E3,  1.0,  0.1,      0.0 ) ) ):
    BisectSrf = cbisector( list( c1, c2 ), -1, 0.5, true, false ):
    display( c1, c2, BisectSrf ) );

for ( a = 2.0, -0.02 * speed, -1.0,
    c1 = cbezier( list( ctlpt( E3,  0.0, -0.1,     -1.0 ),
		        ctlpt( E3,  0.0, -0.1 - a,  0.0 ),
		        ctlpt( E3,  0.0, -0.1,      1.0 ) ) ):
    c2 = cbezier( list( ctlpt( E3, -1.0,  0.1,      0.0 ),
		        ctlpt( E3,  0.0,  2.1,      0.0 ),
		        ctlpt( E3,  1.0,  0.1,      0.0 ) ) ):
    BisectSrf = cbisector( list( c1, c2 ), -1, 0.5, true, false ):
    display( c1, c2, BisectSrf ) );

for ( a = -1.0, 0.02 * speed, 0.0,
    c1 = cbezier( list( ctlpt( E3,  0.0, -0.1,     -1.0 ),
		        ctlpt( E3,  0.0, -0.1 - a,  0.0 ),
		        ctlpt( E3,  0.0, -0.1,      1.0 ) ) ):
    c2 = cbezier( list( ctlpt( E3, -1.0,  0.1,      0.0 ),
		        ctlpt( E3,  0.0,  2.1,      0.0 ),
		        ctlpt( E3,  1.0,  0.1,      0.0 ) ) ):
    BisectSrf = cbisector( list( c1, c2 ), -1, 0.5, true, false ):
    display( c1, c2, BisectSrf ) );

#############################################################################
#
# A line and a circle
#

circ = creparam( pcircle( vector( 0.0, 0.0, 0.0 ), 1 ), 0, 1 )
	* rz( -90 ) * ry( 180 );
ffcompat( c2, circ );

for ( a = 0.0, 0.01 * speed, 1.0,
    c1 = cbezier( list( ctlpt( E3,  0.0, 0.0,     -1.0 ),
		        ctlpt( E3,  0.0, 0.0,      1.0 ) ) ):
    c2x = cmorph( c2, circ, 0, a ):
    BisectSrf = cbisector( list( c1, c2x ), -1, 0.5, true, false ):
    display( c1, c2x, BisectSrf ) );

#############################################################################
#
# A line and a circle (again)
#

circ = creparam( pcircle( vector( 0.0, 0.0, 0.0 ), 1 ), 0, 1 )
	* rz( -90 ) * ry( 180 );

for ( a = 0.0, 0.01 * speed, 0.8,
    c1 = cbezier( list( ctlpt( E3,  0.0 + a,  0.0,     -1.0 ),
		        ctlpt( E3,  0.0 + a,  0.0,      1.0 ) ) ):
    BisectSrf = cbisector( list( c1, circ ), -1, 0.5, true, false ):
    display( c1, circ, BisectSrf ) );

for ( a = 0.8, -0.01 * speed, -0.8,
    c1 = cbezier( list( ctlpt( E3,  0.0 + a,  0.0,     -1.0 ),
		        ctlpt( E3,  0.0 + a,  0.0,      1.0 ) ) ):
    BisectSrf = cbisector( list( c1, circ ), -1, 0.5, true, false ):
    display( c1, circ, BisectSrf ) );

for ( a = -0.8, 0.01 * speed, 0.8,
    c1 = cbezier( list( ctlpt( E3, -0.8,      0.0,     -1.0 ),
		        ctlpt( E3,  0.0 + a,  0.0,      1.0 ) ) ):
    BisectSrf = cbisector( list( c1, circ ), -1, 0.5, true, false ):
    display( c1, circ, BisectSrf ) );

for ( a = 0.0, 0.01 * speed, 1.0,
    c1 = cbezier( list( ctlpt( E3, -0.8 - a,  0.0,     -1.0 ),
		        ctlpt( E3,  0.8 + a,  0.0,      1.0 ) ) ):
    BisectSrf = cbisector( list( c1, circ ), -1, 0.5, true, false ):
    display( c1, circ, BisectSrf ) );


for ( a = 0.0, -0.01 * speed, -1.8,
    c1 = cbezier( list( ctlpt( E3, -1.8 - a,  0.0,     -1.0 ),
		        ctlpt( E3,  1.8 + a,  0.0,      1.0 ) ) ):
    BisectSrf = cbisector( list( c1, circ ), -1, 0.5, true, false ):
    display( c1, circ, BisectSrf ) );


for ( a = -sqrt( 0.8 ), 0.005 * speed, sqrt( 0.8 ),
    c1 = cbezier( list( ctlpt( E3, 0.0,  0.0,     -1.0 ),
		        ctlpt( E3, 0.0,  0.0,      1.0 ) ) ):
    c2 = circ * sx( a * a + 0.2 ):
    BisectSrf = cbisector( list( c1, c2 ), -1, 0.5, true, false ):
    display( c1, c2, BisectSrf ) );

#############################################################################
#
# A quadratic and a circle/rounded square
#

circ = creparam( pcircle( vector( 0.0, 0.0, 0.0 ), 1 ), 0, 1 )
	* rz( -90 ) * ry( 180 );

circSqr = coerce( creparam( pcircle( vector( 0.0, 0.0, 0.0 ), 1 ), 0, 1 )
		  * rz( -90 ) * ry( 180 ), E3 );
circSqr = ceditpt( circSqr, ctlpt( E3, -1, -1, 0 ), 1 );
circSqr = ceditpt( circSqr, ctlpt( E3, -1, -1, 0 ), 2 );
circSqr = ceditpt( circSqr, ctlpt( E3,  1, -1, 0 ), 3 );
circSqr = ceditpt( circSqr, ctlpt( E3,  1, -1, 0 ), 4 );
circSqr = ceditpt( circSqr, ctlpt( E3,  1,  1, 0 ), 5 );
circSqr = ceditpt( circSqr, ctlpt( E3,  1,  1, 0 ), 6 );
circSqr = ceditpt( circSqr, ctlpt( E3, -1,  1, 0 ), 7 );
circSqr = ceditpt( circSqr, ctlpt( E3, -1,  1, 0 ), 8 );

for ( a = 0.0, 0.01 * speed, 1.0,
    c1 = cbezier( list( ctlpt( E3,  0.0, 0.0, -1.0 ),
		        ctlpt( E3,  0.0, 0.0,  1.0 ) ) ):
    c2 = cmorph( circ, circSqr, 0, a ):
    BisectSrf = cbisector( list( c1, c2 ), -1, 0.5, true, false ):
    display( c1, c2, BisectSrf ) );

for ( a = 1.0, -0.01 * speed, 0.0,
    c1 = cbezier( list( ctlpt( E3,  0.0, 0.0, -1.0 ),
		        ctlpt( E3,  0.0, 0.0,  1.0 ) ) ):
    c2 = cmorph( circ, circSqr, 0, a ):
    BisectSrf = cbisector( list( c1, c2 ), -1, 0.5, true, false ):
    display( c1, c2, BisectSrf ) );

for ( a = 0.0, 0.01 * speed, 0.9,
    c1 = cbezier( list( ctlpt( E3,  0.0, 0.0 + a, -1.0 ),
		        ctlpt( E3,  0.0, 0.0 - a,  0.0 ),
		        ctlpt( E3,  0.0, 0.0 + a,  1.0 ) ) ):
    BisectSrf = cbisector( list( c1, circ ), -1, 0.5, true, false ):
    display( c1, circ, BisectSrf ) );

for ( a = 0.0, 2 * speed, 180,
    c1x = c1 * ty( -1 ) * rx( a ) * ty( 1 ):
    BisectSrf = cbisector( list( c1x, circ ), -1, 0.5, true, false ):
    display( c1x, circ, BisectSrf ) );

circ2 = creparam( pcircle( vector( 0.0, 0.0, 0.0 ), 1 ), 0, 1 )
	* rz( -90 ) * ry( 270 ) * ty( 1 );
ffcompat( c1x, circ2 );

for ( a = 0.0, 0.01 * speed, 1.0,
    c1 = cmorph( c1x, circ2, 0, a ):
    BisectSrf = cbisector( list( c1, circ ), -1, 0.5, true, false ):
    display( c1, circ, BisectSrf ) );

for ( a = 0.0, 0.005 * speed, 0.75,
    c1y = cregion( c1, a, 1.0 ):
    BisectSrf = cbisector( list( c1y, circ ), -1, 0.5, true, false ):
    display( c1y, circ, BisectSrf ) );

c1z = cbezier( list( ctlpt( E3,  0.0,  0.0, -1.0 ),
		     ctlpt( E3,  0.0,  0.0,  0.0 ) ) );
ffcompat( c1z, c1y );

for ( a = 0.0, 0.01 * speed, 1.0,
    c1w = cmorph( c1y, c1z, 0, a ):
    BisectSrf = cbisector( list( c1w, circ ), -1, 0.5, true, false ):
    display( c1w, circ, BisectSrf ) );

#############################################################################
#
# A circ/quadratic and a line (point - curve bisector)
#

Motion = creparam( cbspline( 3,
			     list( ctlpt( E2,  0.0,  0.0 ),
				   ctlpt( E2, -0.6,  0.0 ),
				   ctlpt( E2, -0.6, -0.6 ),
				   ctlpt( E2,  0.0, -1.8 ),
				   ctlpt( E2,  0.1, -1.8 ),
			           ctlpt( E2,  0.3,  0.0 ),
			           ctlpt( E2,  0.3,  0.3 ),
			           ctlpt( E2,  0.0,  0.0 ) ),
			     list( KV_OPEN ) ), 0, 1 );

for ( a = 0.0, 0.01 * speed, 1.0,
    Pt = ceval( Motion, a ):
    c1 = cbezier( list( ctlpt( E3,  0.0,  0.0, -1.0 ),
		        ctlpt( E3,  0.0,  0.0,  0.0 ) ) )
		* tx( coord( Pt, 1 ) ) * ty( coord( Pt, 2 ) ):
    BisectSrf = cbisector( list( c1, circ ), -1, 0.5, true, false ):

    IsoCrv = csurface( BisectSrf, col, 1.0 ):
    color( IsoCrv, green ):
    adwidth( IsoCrv, 3 ):

    Pt = ceval( c1, 1.0 ):
    color( Pt, green ):

    display2( c1, circ, BisectSrf, IsoCrv, Pt ) );


c2 = cbezier( list( ctlpt( E3, -1.0, -1.0,  0.0 ),
	            ctlpt( E3,  0.0,  2.1,  0.0 ),
		    ctlpt( E3,  1.0, -1.0,  0.0 ) ) );
ffcompat( c2, circ );

for ( a = 0.0, 0.01 * speed, 1.0,
    c2x = cmorph( circ, c2, 0, a ):
    BisectSrf = cbisector( list( c1, c2x ), -1, 0.5, true, false ):

    IsoCrv = csurface( BisectSrf, col, 1.0 ):
    color( IsoCrv, green ):
    adwidth( IsoCrv, 3 ):

    Pt = ceval( c1, 1.0 ):
    color( Pt, green ):

    display2( c1, c2x, BisectSrf, IsoCrv, Pt ) );

for ( a = 0.0, 0.01 * speed, 1.0,
    Pt = ceval( Motion, a ):
    c1 = cbezier( list( ctlpt( E3,  0.0, 0.0, -1.0 ),
		        ctlpt( E3,  0.0, 0.0,  0.0 ) ) ) *
		tx( coord( Pt, 1 ) ) * ty( coord( Pt, 2 ) ):

    BisectSrf = cbisector( list( c1, c2 ), -1, 0.5, true, false ):

    IsoCrv = csurface( BisectSrf, col, 1.0 ):
    color( IsoCrv, green ):
    adwidth( IsoCrv, 3 ):

    Pt = ceval( c1, 1.0 ):
    color( Pt, green ):

    display2( c1, c2, BisectSrf, IsoCrv, Pt ) );

#############################################################################

free( a );
free( c1 );
free( c2 );
free( BisectSrf );
free( IsoCrv );
free( Pt );
free( c1x );
free( c1y );
free( c1z );
free( c1w );
free( c2x );
free( circ );
free( circ2 );
free( circSqr );
free( Motion );
free( FileCount );
free( Speed );
