bool ON_PlaneSurface::CreatePseudoInfinitePlane( const ON_Plane& plane, int point_count, const ON_3dPoint* point_list, double padding ) { if ( !plane.IsValid() ) return false; if ( point_count < 1 ) return false; if ( 0 == point_list ) return false; if ( !ON_IsValid(padding) || padding < 0.0 ) return false; ON_Interval plane_domain[2]; double s, t; s = ON_UNSET_VALUE; t = ON_UNSET_VALUE; if ( !plane.ClosestPointTo( point_list[0], &s, &t ) || !ON_IsValid(s) || !ON_IsValid(t) ) return 0; plane_domain[0].m_t[1] = plane_domain[0].m_t[0] = s; plane_domain[1].m_t[1] = plane_domain[1].m_t[0] = t; for ( int i = 1; i < point_count; i++ ) { s = ON_UNSET_VALUE; t = ON_UNSET_VALUE; if ( !plane.ClosestPointTo( point_list[i], &s, &t ) || !ON_IsValid(s) || !ON_IsValid(t) ) return 0; if ( s < plane_domain[0].m_t[0] ) plane_domain[0].m_t[0] = s; else if ( s > plane_domain[0].m_t[1] ) plane_domain[0].m_t[1] = s; if ( t < plane_domain[1].m_t[0] ) plane_domain[1].m_t[0] = t; else if ( t > plane_domain[1].m_t[1] ) plane_domain[1].m_t[1] = t; } s = padding*plane_domain[0].Length() + padding; if ( !(s > 0.0) && !plane_domain[0].IsIncreasing() ) s = 1.0; plane_domain[0].m_t[0] -= s; plane_domain[0].m_t[1] += s; t = padding*plane_domain[1].Length() + padding; if ( !(t > 0.0) && !plane_domain[1].IsIncreasing() ) t = 1.0; plane_domain[1].m_t[0] -= t; plane_domain[1].m_t[1] += t; m_plane = plane; m_domain[0] = plane_domain[0]; m_domain[1] = plane_domain[1]; m_extents[0] = plane_domain[0]; m_extents[1] = plane_domain[1]; return IsValid()?true:false; }
ON_BOOL32 ON_Surface::FrameAt( double u, double v, ON_Plane& frame) const { ON_BOOL32 rc = false; ON_3dPoint origin; ON_3dVector udir, vdir, normal; if( EvNormal( u, v, origin, udir, vdir, normal)) { if ( udir.Unitize() ) vdir = ON_CrossProduct( normal, udir); else if ( vdir.Unitize() ) udir = ON_CrossProduct( vdir, normal); frame.CreateFromFrame( origin, udir, vdir); rc = frame.IsValid(); } return rc; }
CRhinoCommand::result CCommandSampleOrientOnCrv::GetBasePlane( ON_Plane& base_plane ) { CRhinoGetPoint get; get.SetCommandPrompt( L"Base point" ); get.AcceptNothing(); get.GetPoint(); CRhinoCommand::result rc = get.CommandResult(); if( rc == CRhinoCommand::success ) { base_plane = get.View()->Viewport().ConstructionPlane().m_plane; base_plane.origin = get.Point(); base_plane.UpdateEquation(); if( !base_plane.IsValid() ) rc = CRhinoCommand::cancel; } return rc; }
bool ON_Quaternion::GetRotation(ON_Plane& plane) const { plane.xaxis.x = a*a + b*b - c*c - d*d; plane.xaxis.y = 2.0*(a*d + b*c); plane.xaxis.z = 2.0*(b*d - a*c); plane.yaxis.x = 2.0*(b*c - a*d); plane.yaxis.y = a*a - b*b + c*c - d*d; plane.yaxis.z = 2.0*(a*b + c*d); plane.zaxis.x = 2.0*(a*c + b*d); plane.zaxis.y = 2.0*(c*d - a*b); plane.zaxis.z = a*a - b*b - c*c + d*d; plane.xaxis.Unitize(); plane.yaxis.Unitize(); plane.zaxis.Unitize(); plane.origin.Set(0.0,0.0,0.0); plane.UpdateEquation(); return plane.IsValid(); }
int ON_ArePointsOnPlane( // returns 0=no, 1 = yes, 2 = pointset is (to tolerance) a single point on the line int dim, // 2 or 3 int is_rat, int count, int stride, const double* point, const ON_BoundingBox& bbox, // if needed, use ON_GetBoundingBox(dim,is_rat,count,stride,point) const ON_Plane& plane, // line to test double tolerance ) { double w; int i, j, k; if ( count < 1 ) return 0; if ( !plane.IsValid() ) { ON_ERROR("plane parameter is not valid"); return 0; } if ( !bbox.IsValid() ) { ON_ERROR("bbox parameter is not valid"); return 0; } if ( !ON_IsValid(tolerance) || tolerance < 0.0 ) { ON_ERROR("tolerance must be >= 0.0"); return 0; } if ( dim < 2 || dim > 3 ) { ON_ERROR("dim must be 2 or 3"); return 0; } if ( stride < (is_rat?(dim+1):dim) ) { ON_ERROR("stride parameter is too small"); return 0; } if ( 0 == point ) { ON_ERROR("point parameter is null"); return 0; } int rc = 0; if ( tolerance == 0.0 ) { tolerance = bbox.Tolerance(); } ON_3dPoint Q; // test bounding box to quickly detect the common coordinate axis cases rc = (count == 1 || bbox.Diagonal().Length() <= tolerance) ? 2 : 1; for ( i = 0; rc && i < 2; i++ ) { Q.x = bbox[i].x; for ( j = 0; rc && j < 2; j++) { Q.y = bbox[j].y; for ( k = 0; rc && k < 2; k++) { Q.z = bbox[k].z; if ( Q.DistanceTo( plane.ClosestPointTo( Q ) ) > tolerance ) rc = 0; } } } if ( !rc ) { // test points one by one Q.Zero(); rc = (count == 1 || bbox.Diagonal().Length() <= tolerance) ? 2 : 1; if ( is_rat ) { for ( i = 0; i < count; i++ ) { w = point[dim]; if ( w == 0.0 ) { ON_ERROR("rational point has zero weight"); return 0; } ON_ArrayScale( dim, 1.0/w, point, &Q.x ); if ( Q.DistanceTo( plane.ClosestPointTo( Q ) ) > tolerance ) { rc = 0; break; } point += stride; } } else { for ( i = 0; i < count; i++ ) { memcpy( &Q.x, point, dim*sizeof(Q.x) ); if ( Q.DistanceTo( plane.ClosestPointTo( Q ) ) > tolerance ) { rc = 0; break; } point += stride; } } } return rc; }
bool ON_Plane::Morph( const ON_SpaceMorph& morph ) { ON_Plane mp; double s = sqrt( fabs(origin.MaximumCoordinate())*ON_SQRT_EPSILON + ON_ZERO_TOLERANCE ); mp.xaxis = morph.MorphVector(origin,s*xaxis); mp.yaxis = morph.MorphVector(origin,s*yaxis); mp.zaxis = morph.MorphVector(origin,s*zaxis); origin = morph.MorphPoint(origin); UpdateEquation(); bool bx = mp.xaxis.Unitize(); bool by = mp.yaxis.Unitize(); bool bz = mp.zaxis.Unitize(); if (!bx) { mp.xaxis = ON_CrossProduct(mp.yaxis,mp.zaxis); bx = mp.xaxis.Unitize(); } if (!by) { mp.yaxis = ON_CrossProduct(mp.zaxis,mp.xaxis); by = mp.yaxis.Unitize(); } if (!bz) { mp.zaxis = ON_CrossProduct(mp.xaxis,mp.yaxis); bz = mp.zaxis.Unitize(); } mp.origin.Set(0.0,0.0,0.0); mp.UpdateEquation(); bool rc = mp.IsValid(); ON_3dVector x, y, z; if ( rc ) { x = mp.xaxis; y = mp.yaxis; z = mp.zaxis; } else { x = ON_CrossProduct(mp.yaxis,mp.zaxis); y = ON_CrossProduct(mp.zaxis,mp.xaxis); z = ON_CrossProduct(mp.xaxis,mp.yaxis); x.Unitize(); y.Unitize(); z.Unitize(); x = mp.xaxis + x; y = mp.yaxis + y; z = mp.zaxis + z; x.Unitize(); y.Unitize(); z.Unitize(); rc = mp.CreateFromFrame(ON_origin,x,y); if (rc) { x = mp.xaxis; y = mp.yaxis; z = mp.zaxis; } else { rc = mp.CreateFromFrame(ON_origin,y,z); if ( rc ) { y = mp.xaxis; z = mp.yaxis; x = mp.zaxis; } else { rc = mp.CreateFromFrame(ON_origin,z,x); if (rc) { z = mp.xaxis; x = mp.yaxis; y = mp.zaxis; } else { rc = mp.CreateFromNormal(ON_origin,z); if (rc) { x = mp.xaxis; y = mp.yaxis; z = mp.zaxis; } } } } } if (rc) { xaxis = x; yaxis = y; zaxis = z; UpdateEquation(); } return rc; }