@@ -37,6 +37,8 @@ pub enum Constraint {
3737 CircleTangentToCircle ( DatumCircle , DatumCircle ) ,
3838 /// These two points should be a given distance apart.
3939 Distance ( DatumPoint , DatumPoint , f64 ) ,
40+ /// These two points should have distance equal to the given variable.
41+ DistanceVar ( DatumPoint , DatumPoint , DatumDistance ) ,
4042 /// These two points should be a given vertical distance apart.
4143 VerticalDistance ( DatumPoint , DatumPoint , f64 ) ,
4244 /// These two points should be a given horizontal distance apart.
@@ -114,6 +116,11 @@ impl Constraint {
114116 row0. extend ( p0. all_variables ( ) ) ;
115117 row0. extend ( p1. all_variables ( ) ) ;
116118 }
119+ Constraint :: DistanceVar ( p0, p1, d) => {
120+ row0. extend ( p0. all_variables ( ) ) ;
121+ row0. extend ( p1. all_variables ( ) ) ;
122+ row0. extend ( d. all_variables ( ) ) ;
123+ }
117124 Constraint :: VerticalDistance ( p0, p1, _dist) => {
118125 row0. extend ( [ p0. id_y ( ) , p1. id_y ( ) ] ) ;
119126 }
@@ -300,6 +307,15 @@ impl Constraint {
300307 let actual_distance = p0. euclidean_distance ( p1) ;
301308 * residual0 = actual_distance - expected_distance;
302309 }
310+ Constraint :: DistanceVar ( p, q, d) => {
311+ let px = current_assignments[ layout. index_of ( p. id_x ( ) ) ] ;
312+ let py = current_assignments[ layout. index_of ( p. id_y ( ) ) ] ;
313+ let qx = current_assignments[ layout. index_of ( q. id_x ( ) ) ] ;
314+ let qy = current_assignments[ layout. index_of ( q. id_y ( ) ) ] ;
315+ let d = current_assignments[ layout. index_of ( d. id ) ] ;
316+ let residual = -d + ( ( px - qx) . powi ( 2 ) + ( py - qy) . powi ( 2 ) ) . sqrt ( ) ;
317+ * residual0 = residual;
318+ }
303319 Constraint :: VerticalDistance ( p0, p1, expected_distance) => {
304320 let p0_y = current_assignments[ layout. index_of ( p0. id_y ( ) ) ] ;
305321 let p1_y = current_assignments[ layout. index_of ( p1. id_y ( ) ) ] ;
@@ -678,6 +694,7 @@ impl Constraint {
678694 Constraint :: LineTangentToCircle ( ..) => 1 ,
679695 Constraint :: CircleTangentToCircle ( ..) => 1 ,
680696 Constraint :: Distance ( ..) => 1 ,
697+ Constraint :: DistanceVar ( ..) => 1 ,
681698 Constraint :: VerticalDistance ( ..) => 1 ,
682699 Constraint :: HorizontalDistance ( ..) => 1 ,
683700 Constraint :: Vertical ( ..) => 1 ,
@@ -923,6 +940,43 @@ impl Constraint {
923940 . as_slice ( ) ,
924941 ) ;
925942 }
943+ Constraint :: DistanceVar ( p, q, d) => {
944+ let px = current_assignments[ layout. index_of ( p. id_x ( ) ) ] ;
945+ let py = current_assignments[ layout. index_of ( p. id_y ( ) ) ] ;
946+ let qx = current_assignments[ layout. index_of ( q. id_x ( ) ) ] ;
947+ let qy = current_assignments[ layout. index_of ( q. id_y ( ) ) ] ;
948+ // let d = current_assignments[layout.index_of(d.id)];
949+ let df_dpx = ( px - qx) * ( ( px - qx) . powi ( 2 ) + ( py - qy) . powi ( 2 ) ) . sqrt ( ) . recip ( ) ;
950+ let df_dpy = ( py - qy) * ( ( px - qx) . powi ( 2 ) + ( py - qy) . powi ( 2 ) ) . sqrt ( ) . recip ( ) ;
951+ let df_dqx = -( px - qx) * ( ( px - qx) . powi ( 2 ) + ( py - qy) . powi ( 2 ) ) . sqrt ( ) . recip ( ) ;
952+ let df_dqy = -( py - qy) * ( ( px - qx) . powi ( 2 ) + ( py - qy) . powi ( 2 ) ) . sqrt ( ) . recip ( ) ;
953+ let df_dd = -1.0 ;
954+ row0. extend (
955+ [
956+ JacobianVar {
957+ id : p. id_x ( ) ,
958+ partial_derivative : df_dpx,
959+ } ,
960+ JacobianVar {
961+ id : p. id_y ( ) ,
962+ partial_derivative : df_dpy,
963+ } ,
964+ JacobianVar {
965+ id : q. id_x ( ) ,
966+ partial_derivative : df_dqx,
967+ } ,
968+ JacobianVar {
969+ id : q. id_y ( ) ,
970+ partial_derivative : df_dqy,
971+ } ,
972+ JacobianVar {
973+ id : d. id ,
974+ partial_derivative : df_dd,
975+ } ,
976+ ]
977+ . as_slice ( ) ,
978+ ) ;
979+ }
926980 Constraint :: VerticalDistance ( p0, p1, _expected_distance) => {
927981 // Residual: p0y - p1y - d = 0
928982 // ∂R/∂y0 = 1
@@ -1888,6 +1942,7 @@ impl Constraint {
18881942 Constraint :: LineTangentToCircle ( ..) => "LineTangentToCircle" ,
18891943 Constraint :: CircleTangentToCircle ( ..) => "CircleTangentToCircle" ,
18901944 Constraint :: Distance ( ..) => "Distance" ,
1945+ Constraint :: DistanceVar ( ..) => "DistanceVar" ,
18911946 Constraint :: VerticalDistance ( ..) => "VerticalDistance" ,
18921947 Constraint :: HorizontalDistance ( ..) => "HorizontalDistance" ,
18931948 Constraint :: Vertical ( ..) => "Vertical" ,
0 commit comments