void scale_along_normal( CGEOMptr &obj, CWpt &scale_cent, CWpt &down_pt, CWvec &down_norm, CXYpt &cur ) { Wtransf xf (obj->xform()); Wpt dpt (xf * down_pt); Wpt spt (xf * scale_cent); Wvec upv ((xf * down_norm).normalized()); if (upv * (dpt - spt) < 0) upv = -upv; if ((cur - XYpt(dpt)).length() < 0.01) return; Wpt npt(Wline(dpt,upv).intersect(cur)); Wpt ctr(xf * scale_cent); double sval(((npt-dpt) * upv) / (dpt-ctr).length()); if ((npt-ctr) * (dpt-ctr) < 0) return; Wvec dnorm (fabs(down_norm[0]),fabs(down_norm[1]), fabs(down_norm[2])); ((GEOMptr)obj)->set_xform(xf * Wtransf::scaling(scale_cent, (dnorm*sval+Wvec(1,1,1)))); }
RAYhit & LINE3D::intersect( RAYhit &ray, CWtransf&, int ) const { // Find the intersection point, its distance, and some kind of normal double distance = -1, d_2d = -1; Wvec surf_norm; Wpt nearpt; for (int i=0; i<num()-1; i++) { // Find the nearest point on the ray to the segment. Wpt ray_pt = ray.line().intersect(Wline(point(i), point(i+1))); // Accept only if ray_pt is in front of the ray if ((ray_pt - ray.point()) * ray.vec() > 0 ) { // Ok if the ray passes within 10 pixels of the segment const double PIX_THRESH = 10.0; Wpt hit_pt = nearest_pt_to_line_seg(ray_pt, point(i), point(i+1)); double screen_dist = PIXEL(hit_pt).dist(ray_pt); if ((screen_dist < PIX_THRESH) && (d_2d < 0 || screen_dist < d_2d)) { d_2d = screen_dist; distance = ray.point().dist(ray_pt); nearpt = hit_pt; // XXX - What should be the "normal"? For now, // just the vector pointing back to the camera. surf_norm = -ray.vec().normalized(); } } } // Then call ray.check() passing it all this stuff if (distance >= 0) ray.check(distance, 1, 0, (GEL*)this, surf_norm, nearpt, nearpt, 0, XYpt()); return ray; }