# # This file demonstrates the use of ffmatch with norm 4 to compute bisectors # to two curves. # # Gershon Elber, December 1995 # save_mat = view_mat; # # Functions to compute the bisector by sampling points along it and # interpolating symmetrically, to Crv1, and to Crv2. # BisectorCrv = function( Crv1, Crv2, Samples, Order, DOFs, ParamMethod ): TCrv1: TCrv2: t: dt: PtList: Pt1: Pt2: Pt12: Dist2: i: Tan1: Tan2: Nrml1: Nrml2: TCrv1 = cderive( Crv1 ): TCrv2 = cderive( Crv2 ): t = nth( pdomain( Crv1 ), 1 ): dt = ( nth( pdomain( Crv1 ), 2 ) - t ) / ( Samples - 1 + 1e-10 ): PtList = nil(): for ( i = 1, 1, Samples, Pt1 = coerce( ceval( Crv1, t ), point_type ): Pt2 = coerce( ceval( Crv2, t ), point_type ): Pt12 = Pt1 - Pt2: Dist2 = sqrt( Pt12 * Pt12 ) / 2: Pt12 = normalize( Pt12 ): Tan1 = coerce( ceval( TCrv1, t ), vector_type ): Tan2 = coerce( ceval( TCrv2, t ), vector_type ): Nrml1 = normalize( vector( coord( Tan1, 1 ), -coord( Tan1, 0 ), 1e-32 ) ): Nrml2 = normalize( vector( -coord( Tan2, 1 ), coord( Tan2, 0 ), 1e-32 ) ): Pt1 = Pt1 + Nrml1 * ( Dist2 / abs( Nrml1 * Pt12 ) ): Pt2 = Pt2 + Nrml2 * ( Dist2 / abs( Nrml2 * Pt12 ) ): snoc( coerce( ( Pt1 + Pt2 ) * 0.5, point_type ), PtList ): t = t + dt ): return = cinterp( PtList, Order, DOFs, ParamMethod, false ); BisectorCrv1 = function( Crv1, Crv2, Samples, Order, DOFs, ParamMethod ): TCrv1: TCrv2: t: dt: PtList: Pt1: Pt2: Pt12: Dist2: i: Tan1: Tan2: Nrml1: Nrml2: TCrv1 = cderive( Crv1 ): TCrv2 = cderive( Crv2 ): t = nth( pdomain( Crv1 ), 1 ): dt = ( nth( pdomain( Crv1 ), 2 ) - t ) / ( Samples - 1 + 1e-10 ): PtList = nil(): for ( i = 1, 1, Samples, Pt1 = coerce( ceval( Crv1, t ), point_type ): Pt2 = coerce( ceval( Crv2, t ), point_type ): Pt12 = Pt1 - Pt2: Dist2 = sqrt( Pt12 * Pt12 ) / 2: Pt12 = normalize( Pt12 ): Tan1 = coerce( ceval( TCrv1, t ), vector_type ): Tan2 = coerce( ceval( TCrv2, t ), vector_type ): Nrml1 = normalize( vector( coord( Tan1, 1 ), -coord( Tan1, 0 ), 0.0 ) ): Nrml2 = normalize( vector( -coord( Tan2, 1 ), coord( Tan2, 0 ), 0.0 ) ): Pt1 = Pt1 + Nrml1 * ( Dist2 / abs( Nrml1 * Pt12 ) ): Pt2 = Pt2 + Nrml2 * ( Dist2 / abs( Nrml2 * Pt12 ) ): snoc( coerce( Pt1, point_type ), PtList ): t = t + dt ): return = cinterp( PtList, Order, DOFs, ParamMethod, false ); BisectorCrv2 = function( Crv1, Crv2, Samples, Order, DOFs, ParamMethod ): TCrv1: TCrv2: t: dt: PtList: Pt1: Pt2: Pt12: Dist2: i: Tan1: Tan2: Nrml1: Nrml2: TCrv1 = cderive( Crv1 ): TCrv2 = cderive( Crv2 ): t = nth( pdomain( Crv1 ), 1 ): dt = ( nth( pdomain( Crv1 ), 2 ) - t ) / ( Samples - 1 + 1e-10 ): PtList = nil(): for ( i = 1, 1, Samples, Pt1 = coerce( ceval( Crv1, t ), point_type ): Pt2 = coerce( ceval( Crv2, t ), point_type ): Pt12 = Pt1 - Pt2: Dist2 = sqrt( Pt12 * Pt12 ) / 2: Pt12 = normalize( Pt12 ): Tan1 = coerce( ceval( TCrv1, t ), vector_type ): Tan2 = coerce( ceval( TCrv2, t ), vector_type ): Nrml1 = normalize( vector( coord( Tan1, 1 ), -coord( Tan1, 0 ), 0.0 ) ): Nrml2 = normalize( vector( -coord( Tan2, 1 ), coord( Tan2, 0 ), 0.0 ) ): Pt1 = Pt1 + Nrml1 * ( Dist2 / abs( Nrml1 * Pt12 ) ): Pt2 = Pt2 + Nrml2 * ( Dist2 / abs( Nrml2 * Pt12 ) ): snoc( coerce( Pt2, point_type ), PtList ): t = t + dt ): return = cinterp( PtList, Order, DOFs, ParamMethod, false ); ############################################################################# # a Cup's cross section. ############################################################################# view_mat = sc( 0.7 ) * tx( -0.5 ) * ty( 0.8 ); viewobj( view_mat ); PtList = nil(); for ( i = 0, 1, 7, snoc( point( cos( i * 2 * Pi / 8 ), sin( i * 2 * Pi / 8 ), 0.0 ), PtList ) ); free( i ); C1 = coerce( cbspline( 3, PtList, list( KV_PERIODIC ) ), KV_OPEN ) * rz( -22.5 ); C2 = coerce( cbspline( 2, PtList, list( KV_PERIODIC ) ), KV_OPEN ) * sc( 1.1 ); MinSize = 0.01; Body = sFromCrvs( list( C2 * sc( MinSize ), C2 * sc( 0.6 ), C2 * sc( 0.9 ) * tz( 0.05 ), C2 * tz( 0.3 ), C2 * sc( 0.8 ) * tz( 1.0 ), C2 * tz( 2.0 ), C2 * tz( 2.2 ), C1 * tz( 2.2 ), C1 * tz( 2.0 ), C1 * sc( 0.8 ) * tz( 1.0 ), C1 * tz( 0.4 ), C1 * sc( 0.8 ) * tz( 0.15 ), C1 * sc( 0.6 ) * tz( 0.1 ), C1 * sc( 0.2 ) * tz( 0.2 ), C1 * sc( MinSize ) * tz( 0.2 ) ), 3, KV_OPEN ); free( MinSize ); Cross = coerce( csurface( Body * rx( 90 ), COL, 1.0 ), e2 ); Cross1 = cregion( Cross, 0.0, 6.0 / 13.0 ); Cross1 = creparam( Cross1, 0, 1 ); color( Cross1, red ); Cross2 = -cregion( Cross, 6.0 / 13.0, 1.0 ); Cross2 = creparam( Cross2, 0, 1 ); color( Cross2, green ); Cross2b = ffmatch( Cross1, Cross2, 30, 50, 3, false, 4 ); Srf0 = ruledSrf( Cross1, Cross2b ); interact( Srf0 ); Cross2b = ffmatch( Cross1, Cross2, 30, 100, 3, false, 4 ); Srf0 = ruledSrf( Cross1, Cross2b ); interact( Srf0 ); Cross2b = ffmatch( Cross1, Cross2, 30, 200, 3, false, 4 ); Srf0 = ruledSrf( Cross1, Cross2b ); interact( Srf0 ); color( srf0, blue ); bCrv1 = BisectorCrv( Cross1, Cross2b, 100, 4, 30, PARAM_UNIFORM ); bCrv1a = BisectorCrv1( Cross1, Cross2b, 100, 4, 30, PARAM_UNIFORM ); bCrv1b = BisectorCrv2( Cross1, Cross2b, 100, 4, 30, PARAM_UNIFORM ); color( bCrv1, green ); interact( list( bCrv1, bCrv1a, bCrv1b, srf0 ) ); save( "ffmatch41", list( bCrv1, bCrv1a, bCrv1b, srf0 ) ); bCrv2 = BisectorCrv( Cross1, Cross2b, 100, 3, 10, PARAM_UNIFORM ); bCrv2a = BisectorCrv1( Cross1, Cross2b, 100, 3, 10, PARAM_UNIFORM ); bCrv2b = BisectorCrv2( Cross1, Cross2b, 100, 3, 10, PARAM_UNIFORM ); color( bCrv2, green ); interact( list( bCrv2, bCrv2a, bCrv2b, srf0 ) ); bCrv3 = BisectorCrv( Cross1, Cross2b, 100, 3, 5, PARAM_UNIFORM ); bCrv3a = BisectorCrv1( Cross1, Cross2b, 100, 3, 5, PARAM_UNIFORM ); bCrv3b = BisectorCrv2( Cross1, Cross2b, 100, 3, 5, PARAM_UNIFORM ); color( bCrv3, green ); interact( list( bCrv3, bCrv3a, bCrv3b, srf0 ) ); ############################################################################# # Another example. ############################################################################# view_mat = sc( 1.6 ) * tx( -0.8 ) * ty( 0.0 ); viewobj( view_mat ); Cross1 = cbspline( 3, list( ctlpt( e2, 0.0, 0.1 ), ctlpt( e2, 0.1, 0.15 ), ctlpt( e2, 0.9, 0.15 ), ctlpt( e2, 1.0, 0.1 ) ), list( KV_OPEN ) ); Cross2 = cbspline( 3, list( ctlpt( e2, 0.1, 0.0 ), ctlpt( e2, 0.1, 0.1 ), ctlpt( e2, 0.5, 0.0 ), ctlpt( e2, 0.9, 0.1 ), ctlpt( e2, 0.9, 0.0 ) ), list( KV_OPEN ) ); interact( list( Cross1, Cross2 ) ); Cross2b = ffmatch( Cross1, Cross2, 30, 50, 3, false, 4 ); Srf0 = ruledSrf( Cross1, Cross2b ); interact( Srf0 ); Cross2b = ffmatch( Cross1, Cross2, 30, 100, 3, false, 4 ); Srf0 = ruledSrf( Cross1, Cross2b ); interact( Srf0 ); Cross2b = ffmatch( Cross1, Cross2, 30, 200, 3, false, 4 ); Srf0 = ruledSrf( Cross1, Cross2b ); interact( Srf0 ); color( srf0, blue ); bCrv1 = BisectorCrv( Cross1, Cross2b, 100, 4, 30, PARAM_UNIFORM ); bCrv1a = BisectorCrv1( Cross1, Cross2b, 100, 4, 30, PARAM_UNIFORM ); bCrv1b = BisectorCrv2( Cross1, Cross2b, 100, 4, 30, PARAM_UNIFORM ); color( bCrv1, green ); interact( list( bCrv1, bCrv1a, bCrv1b, srf0 ) ); save( "ffmatch42", list( bCrv1, bCrv1a, bCrv1b, srf0 ) ); bCrv2 = BisectorCrv( Cross1, Cross2b, 100, 3, 10, PARAM_UNIFORM ); bCrv2a = BisectorCrv1( Cross1, Cross2b, 100, 3, 10, PARAM_UNIFORM ); bCrv2b = BisectorCrv2( Cross1, Cross2b, 100, 3, 10, PARAM_UNIFORM ); color( bCrv2, green ); interact( list( bCrv2, bCrv2a, bCrv2b, srf0 ) ); bCrv3 = BisectorCrv( Cross1, Cross2b, 100, 3, 5, PARAM_UNIFORM ); bCrv3a = BisectorCrv1( Cross1, Cross2b, 100, 3, 5, PARAM_UNIFORM ); bCrv3b = BisectorCrv2( Cross1, Cross2b, 100, 3, 5, PARAM_UNIFORM ); color( bCrv3, green ); interact( list( bCrv3, bCrv3a, bCrv3b, srf0 ) ); view_mat = save_mat; free( save_mat ); free( bCrv1 ); free( bCrv1a ); free( bCrv1b ); free( bCrv2 ); free( bCrv2a ); free( bCrv2b ); free( bCrv3 ); free( bCrv3a ); free( bCrv3b ); free( srf0 ); free( PtList ); free( Cross ); free( Cross1 ); free( Cross2 ); free( Cross2b ); free( Body ); free( C1 ); free( C2 );