/* $NoKeywords: $ */ /* // // Copyright (c) 1993-2012 Robert McNeel & Associates. All rights reserved. // OpenNURBS, Rhinoceros, and Rhino3D are registered trademarks of Robert // McNeel & Associates. // // THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY. // ALL IMPLIED WARRANTIES OF FITNESS FOR ANY PARTICULAR PURPOSE AND OF // MERCHANTABILITY ARE HEREBY DISCLAIMED. // // For complete openNURBS copyright information see . // //////////////////////////////////////////////////////////////// */ #if !defined(ON_CONVEX_POLY_INC_) #define ON_CONVEX_POLY_INC_ // A Simplex in 3d class ON_CLASS ON_3dSimplex { public: ON_3dSimplex(); // An empty simplex explicit ON_3dSimplex(const ON_3dPoint& a); // 0-simplex in 3d ON_3dSimplex(const ON_3dPoint& a, const ON_3dPoint& b); // 1-simplex ON_3dSimplex(const ON_3dPoint& a, const ON_3dPoint& b, const ON_3dPoint& c); // 2-simplex ON_3dSimplex(const ON_3dPoint& a, const ON_3dPoint& b, const ON_3dPoint& c, const ON_3dPoint& d); // 3-simplex ON_3dSimplex(const ON_3dSimplex& rhs) = default; ON_3dSimplex& operator=(const ON_3dSimplex& rhs) = default; ~ON_3dSimplex() = default; int Count() const; // Number of Verticies <=4 bool IsValid(double eps) const; // true if the Verticies are affinely independent /* Description: Evaluate a point in a Simplex from a barycentric coordinate b. Returns: The point b[0] * Vertex[0] + ... + b[Count()-1] * Vertex[Count()-1] Notes: If b[0] + ... + b[Count()-1] = 1 and b[i]>=0 for i=0 to Count()-1 then the returned point is on the simplex */ ON_3dPoint Evaluate(const double* b) const; ON_3dPoint Evaluate(const ON_4dPoint& b) const; /* Description: Find Closest Point to this simplex from a base point P0 or the Origin. If true is retuned then Evaluate(Bary) is the closest point on the Simplex. maximum_distance - optional upperbound on closest point. If maximum_distance>=0 is specified and Dist(P0, Simplex)>maximum_distance then false is returned. */ bool GetClosestPoint(const ON_3dPoint& P0, ON_4dPoint& Bary, double maximum_distance = ON_DBL_MAX) const; bool GetClosestPointToOrigin(ON_4dPoint& Bary) const; /* Count() Volume() returns 0 0.0 1 0.0 2 length >=0 3 area >=0 4 volume >=0 */ double Volume() const; double SignedVolume() const; // returns ON_UNSET_VALUE if Count()<4 else the signed volume /* FaceNormal(noti) is the oriented face normal obtained by omitting vertex noti. FaceNormal returns ON_UNSET_VALUE if Count()<3 or Count()==4 noti not 0,1,2 or 3. FaceUnitNormal returns ON_UNSET_VALUE if Count()<3 or Count()==4 noti not 0,1,2 or 3 or if FaceNormal(noti)=Zero_Vector */ ON_3dVector FaceNormal(int noti = 0) const; ON_3dVector FaceUnitNormal(int noti = 0) const; /* Edge vector from Vertex(e0) to Vertex(e1) */ ON_3dVector Edge(int e0, int e1)const; /* If 0<=i=0 */ virtual int Count() const = 0; /* Returns: Vertex[i] for i=0,...,Count()-1 */ virtual ON_3dVector Vertex(int i) const = 0; /* Description: Let K be this ON_ConvexPoly then for a non-zero vector W the support Support(W) is a point x in K that maximizes min arg x * W x \in K i0 is an optional initial index seed value. It may provide a performance enhancement toward finding a minimizer. */ ON_3dPoint Support(ON_3dVector W, int i0 =0) const { return Vertex(SupportIndex(W, i0)); } /* Description: For any vector W there is a vetex that is Support(W) SupportIndex( W, i0) returns a vertex index for a vertex that is the support. Veretx( K.SupportIndex( W )) = K.Support(W ); */ virtual int SupportIndex(ON_3dVector W, int i0=0) const = 0; /* Description: Points in a Convex Polytope are parameterized , not necessaily uniquely, by an ON_4dex of vertex indicies and a 4d barycentric point B Evaluate(Ind, B ) = Sum_{i=0,..,3} Vertex(Ind[i])*B[i], where the sum is taken over i such that Ind[i]>=0 If B is a barycentric coordinte B[i]>=0 and B[0] + B[1] + B[2] + B[3] = 1.0 then Evaluate( Ind, B) is a point in the convex polytope */ ON_3dPoint Evaluate(ON_4dex dex, ON_4dPoint B)const { ON_3dVector v(0, 0, 0); if (dex.i >= 0) v = B[0] * Vertex(dex.i); if (dex.j >= 0) v += B[1] * Vertex(dex.j); if (dex.k >= 0) v += B[2] * Vertex(dex.k); if (dex.l >= 0) v += B[3] * Vertex(dex.l); return v; }; /* Description: This is a bound on the collection of verticies. Vertex(i).MaximumCoordinate()<= MaximumCoordinate() for all i */ virtual double MaximumCoordinate() const = 0; /* Description: A point represented by a ON_4dex D and a barycentric coordinate B can be put in a standard form so that non-negative elements of D are unique and corresponding coordinates are positive. Furthemore, the non-negative indicies are all listed before the unset ( neagative ) values */ static bool Standardize(ON_4dex& D, ON_4dPoint& B); /* Returns: true if d[i] n) return false; } return true; } bool IsValid4Dex(const ON_4dex& D) const { return IsValid4DexN(D, Count()); }; virtual ~ON_ConvexPoly() {}; }; // 3d convex hull defined by an explicit collection of points called verticies. // Note: verticies need not be extreme points // WARNING: Points are referenced not stored for optimal performance in' // some applications. // The list of points must remain alive and in there initial location // For the duration of this object. class ON_CLASS ON_ConvexHullRef : public ON_ConvexPoly { public: ON_ConvexHullRef() { m_n = 0; m_is_rat = false; m_stride = 3; }; ON_ConvexHullRef(const ON_3dVector* V0, int count); // a 3d point array ON_ConvexHullRef(const ON_3dPoint* V0, int count); // a 3d point array ON_ConvexHullRef(const ON_4dPoint* V0, int count); // a array of homogeneous points ON_ConvexHullRef(const double* v0, bool is_rat, int n); // v0 is an array of 3dpoints or homo 4d points ON_ConvexHullRef(const double* v0, bool is_rat, int n, int stride); // v0 is an array of 3dpoints or homo 4d points void Initialize(const ON_3dVector* V0, int count); void Initialize(const ON_4dPoint* V0, int count); void Initialize(const double* V0, ON::point_style style, int count); // style must be either not_rational or homogeneous_rational = 2, int Count() const override { return m_n; } ON_3dVector Vertex(int j) const override; // Support map O( Vertes.Count virtual int SupportIndex(ON_3dVector W, int i0) const override; virtual double MaximumCoordinate() const override; virtual ~ON_ConvexHullRef() override {}; private: int m_n = 0; bool m_is_rat= false; const double* m_v = nullptr; int m_stride=3; }; // 3d convex hull defined by an explicit collection of points called verticies. // Note: verticies need not be extreme points class ON_CLASS ON_ConvexHullPoint2 : public ON_ConvexPoly { public: ON_ConvexHullPoint2() = default; ON_ConvexHullPoint2(int init_capacity) : m_Vert(init_capacity) {}; virtual int Count() const override { return m_Vert.Count(); } virtual ON_3dVector Vertex(int j) const override { return m_Vert[j]; } // Support map virtual int SupportIndex(ON_3dVector W, int i0) const override { return Ref.SupportIndex(W, i0); }; virtual double MaximumCoordinate() const override; virtual ~ON_ConvexHullPoint2() override {}; int AppendVertex(const ON_3dPoint& P); // return index of new vertex. must set Adjacent Indicies. void Empty(); bool SetCapacity(int vcnt) { m_Vert.SetCapacity(vcnt); return true; }; private: ON_ConvexHullRef Ref; ON_SimpleArray m_Vert; }; /* Computes a closest point between convex polytopes AHull and BHull. Returns true if a closest point is found and it is within optional maximum_distance bound; Specifically, when true is returned parameters (Adex, ABbary) on AHull and (Bdex, ABbary) on BHull are found such that: if a* = AHull.Evaluate(Adex,ABbary), and b* = BHull.Evaluate(Bdex,ABbary), then d = dist(a*, b*) <= maximum_distance, and for any a in AHull and b in BHull dist(a,b) => d. Setting maximum_distance = tol can speedup the calculation in cases where d>tol On input Adex and Bdex are used to define an intial simplex use Adex = Bdex = ON_4dex::Unset if you have no good initial guess Notice the result is indepentent of the initial guess. */ ON_DECL bool ClosestPoint(const ON_ConvexPoly& AHull, const ON_ConvexPoly& BHull, ON_4dex& Adex, ON_4dex& Bdex, ON_4dPoint& ABbary, double maximum_distance = ON_DBL_MAX); ON_DECL bool ClosestPoint(const ON_3dPoint P0, const ON_ConvexPoly& poly, ON_4dex& dex, ON_4dPoint& Bary, double maximum_distance = ON_DBL_MAX); /* Compute Convex hull of 2d points Parameters: Pnt - array of points, this is array of working data. The points are sorted in place as part of the algorithm HUll - the sequence Hull[0], HUll[1]... ,*Hull.Last() == Hull[0] defines the convex hull with a positive orientation retuns 2. PntInd - otional array to be filled in so that Hull[i] = Pnt[ PntInd[i]] where Pnt is the original input point Returns dimension of the convex hull 2 - Hull is 2 dimensional 1 - Hull is a line segments 0 - hull is a point <0 error */ ON_DECL int ON_ConvexHull2d(const ON_SimpleArray& Pnt, ON_SimpleArray& Hull, ON_SimpleArray< int>* PntInd = nullptr); #endif