From afa201cf5008ab7fc91c60248b87cf09444a9701 Mon Sep 17 00:00:00 2001 From: Dongxu Li Date: Tue, 17 Mar 2015 11:43:39 -0400 Subject: [PATCH] ellipse inscribed: using intersections to form quadrilateral --- librecad/src/lib/engine/rs_ellipse.cpp | 71 +++++------------ .../src/lib/information/rs_information.cpp | 76 +++++++++++++++++++ librecad/src/lib/information/rs_information.h | 1 + 3 files changed, 94 insertions(+), 54 deletions(-) diff --git a/librecad/src/lib/engine/rs_ellipse.cpp b/librecad/src/lib/engine/rs_ellipse.cpp index 7b2bc4763d..a413ec6600 100644 --- a/librecad/src/lib/engine/rs_ellipse.cpp +++ b/librecad/src/lib/engine/rs_ellipse.cpp @@ -730,62 +730,25 @@ bool RS_Ellipse::createFromQuadratic(const QVector& dn){ bool RS_Ellipse::createInscribeQuadrilateral(const std::vector& lines) { if(lines.size() != 4) return false; //only do 4 lines - RS_EntityContainer container(NULL, false); - QVector quad; - for(RS_Line* p: lines){//copy the line pointers - if(p->getLength() quad; + { //form quadrilateral from intersections + RS_EntityContainer c0(NULL, false); + for(RS_Line*const p: lines){//copy the line pointers + c0.addEntity(p); + } + RS_VectorSolutions s0=RS_Information::createQuadrilateral(c0); + if(s0.size()!=4) return false; + for(size_t i=0; i<4; ++i){ + RS_Line*const pl=new RS_Line(&container, RS_LineData(s0[i], s0[(i+1)%4])); + quad.push_back(pl); + container.addEntity(pl); + } + } QVector ip; - for(int i=1;i<4;++i){//find intersections - //(0,i) - // std::cout<<"(0,"<getStartpoint(), quad[1]->getEndpoint()))); + ip.push_back(RS_Line(NULL, RS_LineData(quad[1]->getStartpoint(), quad[2]->getEndpoint()))); RS_VectorSolutions sol=RS_Information::getIntersectionLineLine( & ip[0],& ip[1]); if(sol.getNumber()==0) {//this should not happen // RS_DEBUG->print(RS_Debug::D_WARNING, "RS_Ellipse::createInscribeQuadrilateral(): can not locate projection Center"); diff --git a/librecad/src/lib/information/rs_information.cpp b/librecad/src/lib/information/rs_information.cpp index cd3ec7fabe..20fb075c81 100644 --- a/librecad/src/lib/information/rs_information.cpp +++ b/librecad/src/lib/information/rs_information.cpp @@ -25,6 +25,8 @@ ** **********************************************************************/ +#include +#include #include "rs_information.h" #include "rs_arc.h" @@ -921,3 +923,77 @@ bool RS_Information::isPointInsideContour(const RS_Vector& point, return ((counter%2)==1); } + +RS_VectorSolutions RS_Information::createQuadrilateral(const RS_EntityContainer& container) +{ + RS_VectorSolutions ret; + if(container.count()!=4) return ret; + RS_EntityContainer c(container); + std::vector lines; + for (RS_Entity* e=c.firstEntity(RS2::ResolveNone); + e!=NULL; + e=c.nextEntity(RS2::ResolveNone)) { + if(e->rtti()!=RS2::EntityLine) return ret; + lines.push_back(static_cast(e)); + } + if(lines.size()!=4) return ret; + + //neigbours; + std::vector vertices; + for(unsigned i=0; i<3; ++i){ + for(unsigned j=i+1; j<4; ++j){ + RS_VectorSolutions&& sol=RS_Information::getIntersectionLineLine(lines[i], lines[j]); + if(sol.size()){ + vertices.push_back(sol.at(0)); + } + } + } + +// std::cout<<"vertices.size()="<getDirection1(); + std::vector::iterator> left; + std::vector::iterator> right; + for(auto it=vertices.begin(); it != vertices.end(); ++it){ + RS_Vector&& dir=*it - pl->getNearestPointOnEntity(*it, false); + if(dir.squared()