@@ -66,8 +66,6 @@ using namespace ctlio;
6666#define MIN (a ,b ) ((a) < (b) ? (a) : (b))
6767
6868// forward declarations of prism-related routines, at the bottom of this file
69- static vector3 prism_vector_p2c (prism * prsm , vector3 vp );
70- static vector3 prism_vector_c2p (prism * prsm , vector3 vc );
7169static void get_prism_bounding_box (prism * prsm , geom_box * box );
7270static double intersect_line_segment_with_prism (prism * prsm , vector3 p , vector3 d , double a , double b );
7371static boolean point_in_polygon (double px , double py , vector3 * vertices , int num_vertices );
@@ -139,8 +137,14 @@ void geom_fix_object(geometric_object o)
139137 }
140138 case GEOM PRISM :
141139 {
140+ // recompute centroid of prism floor polygon from prism center,
141+ // which may have shifted since prism was initialized
142+ prism * prsm = o .subclass .prism_data ;
143+ vector3 zhat = prsm -> m_p2c .c2 ;
144+ double height = prsm -> height ;
145+ prsm -> centroid = vector3_plus (o .center , vector3_scale (-0.5 * height ,zhat ));
146+ break ;
142147 }
143- break ;
144148 case GEOM COMPOUND_GEOMETRIC_OBJECT :
145149 {
146150 int i ;
@@ -2462,36 +2466,6 @@ double min_distance_to_prism_roof_or_ceiling(vector3 p,
24622466 return sqrt (s * s + d * d );
24632467}
24642468
2465- /* utility routines for writing points, lines, quadrilaterals */
2466- /* to text files for viewing in e.g. gnuplot */
2467- void GPPoint (FILE * f , vector3 v , prism * prsm )
2468- { if (prsm )
2469- v = prism_coordinate_p2c (prsm , v );
2470- fprintf (f ,"%e %e %e \n\n\n" ,v .x ,v .y ,v .z ); }
2471-
2472- void GPLine (FILE * f , vector3 v , vector3 l , prism * prsm )
2473- { if (prsm )
2474- { v = prism_coordinate_p2c (prsm , v );
2475- l = prism_vector_p2c (prsm , l );
2476- }
2477- fprintf (f ,"%e %e %e \n" ,v .x ,v .y ,v .z );
2478- fprintf (f ,"%e %e %e \n\n\n" ,v .x + l .x ,v .y + l .y ,v .z + l .z );
2479- }
2480-
2481- void GPQuad (FILE * f , vector3 v , vector3 l1 , vector3 l2 , prism * prsm )
2482- {
2483- if (prsm )
2484- { v = prism_coordinate_p2c (prsm , v );
2485- l1 = prism_vector_p2c (prsm , l1 );
2486- l2 = prism_vector_p2c (prsm , l2 );
2487- }
2488- fprintf (f ,"%e %e %e \n" ,v .x ,v .y ,v .z );
2489- fprintf (f ,"%e %e %e \n" ,v .x + l1 .x ,v .y + l1 .y ,v .z + l1 .z );
2490- fprintf (f ,"%e %e %e \n" ,v .x + l1 .x + l2 .x ,v .y + l1 .y + l2 .y ,v .z + l1 .z + l2 .z );
2491- fprintf (f ,"%e %e %e \n" ,v .x + l2 .x ,v .y + l2 .y ,v .z + l2 .z );
2492- fprintf (f ,"%e %e %e \n\n\n" ,v .x ,v .y ,v .z );
2493- }
2494-
24952469/***************************************************************/
24962470/* find the face of the prism for which the normal distance */
24972471/* from x to the plane of that face is the shortest, then */
@@ -2600,13 +2574,13 @@ geometric_object make_prism(material_type material,
26002574
26012575 // make sure all vertices lie in a plane normal to the given axis
26022576 vector3 zhat = unit_vector3 (axis );
2603- double tolerance = 1.0e-6 ;
2577+ double tol = 1.0e-6 ;
26042578 for (nv = 0 ; nv < num_vertices ; nv ++ )
26052579 { int nvp1 = (nv + 1 ) % num_vertices ;
26062580 vector3 zhatp = triangle_normal (centroid ,vertices [nv ],vertices [nvp1 ]);
26072581 boolean axis_normal
2608- = ( vector3_nearly_equal (zhat , zhatp , tolerance )
2609- || vector3_nearly_equal (zhat , vector3_scale (-1.0 ,zhatp ), tolerance )
2582+ = ( vector3_nearly_equal (zhat , zhatp , tol )
2583+ || vector3_nearly_equal (zhat , vector3_scale (-1.0 ,zhatp ), tol )
26102584 );
26112585 CHECK (axis_normal , "axis not normal to vertex plane in make_prism" );
26122586 }
@@ -2615,14 +2589,21 @@ geometric_object make_prism(material_type material,
26152589 // to yield the coordinates of the same point in the prism coordinate system.
26162590 // the prism coordinate system is a right-handed coordinate system
26172591 // in which the prism lies in the xy plane (extrusion axis is the positive z-axis)
2618- // with centroid at the origin and the first edge lying on the positive x-axis .
2592+ // with centroid at the origin.
26192593 // note: the prism *centroid* is the center of mass of the planar vertex polygon,
26202594 // i.e. it is a point lying on the bottom surface of the prism.
26212595 // This is the origin of coordinates in the prism system.
26222596 // The *center* of the geometric object is the center of mass of the
26232597 // 3D prism. So center = centroid + 0.5*zHat.
2624- vector3 xhat = unit_vector3 (vector3_minus (vertices [1 ],vertices [0 ]));
2625- vector3 yhat = unit_vector3 (vector3_cross (zhat ,xhat ));
2598+ vector3 x0hat = {1.0 ,0.0 ,0.0 }, y0hat = {0.0 ,1.0 ,0.0 }, z0hat = {0.0 ,0.0 ,1.0 };
2599+ vector3 xhat , yhat ;
2600+ if (vector3_nearly_equal (zhat , x0hat , tol )) { xhat = y0hat ; yhat = z0hat ; }
2601+ else if (vector3_nearly_equal (zhat , y0hat , tol )) { xhat = z0hat ; yhat = x0hat ; }
2602+ else if (vector3_nearly_equal (zhat , z0hat , tol )) { xhat = x0hat ; yhat = y0hat ; }
2603+ else
2604+ { xhat = unit_vector3 (vector3_minus (vertices [1 ],vertices [0 ]));
2605+ yhat = unit_vector3 (vector3_cross (zhat ,xhat ));
2606+ }
26262607 matrix3x3 m_p2c = {xhat , yhat , zhat };
26272608 matrix3x3 m_c2p = matrix3x3_inverse (m_p2c );
26282609
0 commit comments