RS_Vector RS_EntityContainer::getNearestPointOnEntity(const RS_Vector& coord, bool onEntity, double* dist, RS_Entity** entity) { RS_Vector point(false); RS_Entity* en = getNearestEntity(coord, dist, RS2::ResolveNone); if (en!=NULL ) { if ( en->isVisible() && en->getParent()->rtti() != RS2::EntityInsert /**Insert*/ //&& en->rtti() != RS2::EntityPoint /**Point*/ && en->getParent()->rtti() != RS2::EntitySpline && en->getParent()->rtti() != RS2::EntityText /**< Text 15*/ && en->getParent()->rtti() != RS2::EntityDimAligned /**< Aligned Dimension */ && en->getParent()->rtti() != RS2::EntityDimLinear /**< Linear Dimension */ && en->getParent()->rtti() != RS2::EntityDimRadial /**< Radial Dimension */ && en->getParent()->rtti() != RS2::EntityDimDiametric /**< Diametric Dimension */ && en->getParent()->rtti() != RS2::EntityDimAngular /**< Angular Dimension */ && en->getParent()->rtti() != RS2::EntityDimLeader /**< Leader Dimension */ ){//no middle point for Spline, Insert, text, Dim point = en->getNearestPointOnEntity(coord, onEntity, dist, entity); } } return point; }
RS_Vector RS_EntityContainer::getNearestPointOnEntity(const RS_Vector& coord, bool onEntity, double* dist, RS_Entity** entity) { RS_Vector point(false); RS_Entity* e = getNearestEntity(coord, dist, RS2::ResolveNone); if (e!=NULL && e->isVisible()) { point = e->getNearestPointOnEntity(coord, onEntity, dist, entity); } return point; }
RS_Vector RS_EntityContainer::getNearestDist(double distance, const RS_Vector& coord, double* dist) const{ RS_Vector point(false); RS_Entity* closestEntity; closestEntity = getNearestEntity(coord, nullptr, RS2::ResolveNone); if (closestEntity) { point = closestEntity->getNearestDist(distance, coord, dist); } return point; }
RS_Vector RS_EntityContainer::getNearestPointOnEntity(const RS_Vector& coord, bool onEntity, double* dist, RS_Entity** entity)const { RS_Vector point(false); RS_Entity* en = getNearestEntity(coord, dist, RS2::ResolveNone); if (en && en->isVisible() && !en->getParent()->ignoredOnModification() ){ point = en->getNearestPointOnEntity(coord, onEntity, dist, entity); } return point; }
RS_Vector RS_EntityContainer::getNearestCenter(const RS_Vector& coord, double* dist) { RS_Vector point(false); RS_Entity* closestEntity; //closestEntity = getNearestEntity(coord, NULL, RS2::ResolveAll); closestEntity = getNearestEntity(coord, NULL, RS2::ResolveNone); if (closestEntity!=NULL) { point = closestEntity->getNearestCenter(coord, dist); } return point; }
RS_Vector RS_EntityContainer::getNearestPointOnEntity(const RS_Vector& coord, bool onEntity, double* dist, RS_Entity** entity)const { RS_Vector point(false); RS_Entity* en = getNearestEntity(coord, dist, RS2::ResolveNone); if (en) { if ( en->isVisible() && !en->getParent()->ignoredOnModification() ){//no middle point for Spline, Insert, text, Dim point = en->getNearestPointOnEntity(coord, onEntity, dist, entity); } } return point; }
/** * @return The intersection which is closest to 'coord' */ RS_Vector RS_EntityContainer::getNearestIntersection(const RS_Vector& coord, double* dist) { double minDist = RS_MAXDOUBLE; // minimum measured distance double curDist; // currently measured distance RS_Vector closestPoint(false); // closest found endpoint RS_Vector point; // endpoint found RS_VectorSolutions sol; RS_Entity* closestEntity; closestEntity = getNearestEntity(coord, NULL, RS2::ResolveAll); if (closestEntity!=NULL) { for (RS_Entity* en = firstEntity(RS2::ResolveAll); en != NULL; en = nextEntity(RS2::ResolveAll)) { if (en->isVisible() && en!=closestEntity) { sol = RS_Information::getIntersection(closestEntity, en, true); for (int i=0; i<4; i++) { point = sol.get(i); if (point.valid) { curDist = coord.distanceTo(point); if (curDist<minDist) { closestPoint = point; minDist = curDist; if (dist!=NULL) { *dist = curDist; } } } } } } //} } return closestPoint; }
/** * @return The intersection which is closest to 'coord' */ RS_Vector RS_EntityContainer::getNearestIntersection(const RS_Vector& coord, double* dist) { double minDist = RS_MAXDOUBLE; // minimum measured distance double curDist = RS_MAXDOUBLE; // currently measured distance RS_Vector closestPoint(false); // closest found endpoint RS_Vector point; // endpoint found RS_VectorSolutions sol; RS_Entity* closestEntity; closestEntity = getNearestEntity(coord, nullptr, RS2::ResolveAllButTextImage); if (closestEntity) { for (RS_Entity* en = firstEntity(RS2::ResolveAllButTextImage); en; en = nextEntity(RS2::ResolveAllButTextImage)) { if ( !en->isVisible() || en->getParent()->ignoredOnModification() ){ continue; } sol = RS_Information::getIntersection(closestEntity, en, true); point=sol.getClosest(coord,&curDist,nullptr); if(sol.getNumber()>0 && curDist<minDist){ closestPoint=point; minDist=curDist; } } } if(dist && closestPoint.valid) { *dist = minDist; } return closestPoint; }
RS_Vector RS_EntityContainer::getNearestMiddle(const RS_Vector& coord, double* dist) { RS_Vector point(false); RS_Entity* closestEntity; closestEntity = getNearestEntity(coord, NULL, RS2::ResolveNone); if (closestEntity!=NULL) { point = closestEntity->getNearestMiddle(coord, dist); } return point; /* double minDist = RS_MAXDOUBLE; // minimum measured distance double curDist; // currently measured distance RS_Vector closestPoint; // closest found endpoint RS_Vector point; // endpoint found for (RS_Entity* en = firstEntity(); en != NULL; en = nextEntity()) { if (en->isVisible()) { point = en->getNearestMiddle(coord, &curDist); if (curDist<minDist) { closestPoint = point; minDist = curDist; if (dist!=NULL) { *dist = curDist; } } } } return closestPoint; */ }
/** * this should handle modifyOffset *@ coord, indicate direction of offset *@ distance of offset * *@Author, Dongxu Li */ bool RS_Polyline::offset(const RS_Vector& coord, const double& distance){ double dist; //find the nearest one int length=count(); std::vector<RS_Vector> intersections(length); if(length>1){//sort the polyline entity start/end point order int i(0); double d0,d1; RS_Entity* en0(entityAt(0)); RS_Entity* en1(entityAt(1)); RS_Vector vStart(en0->getStartpoint()); RS_Vector vEnd(en0->getEndpoint()); en1->getNearestEndpoint(vStart,&d0); en1->getNearestEndpoint(vEnd,&d1); if(d0<d1) en0->revertDirection(); for(i=1;i<length;en0=en1){ //linked to head-tail chain en1=entityAt(i); vStart=en1->getStartpoint(); vEnd=en1->getEndpoint(); en0->getNearestEndpoint(vStart,&d0); en0->getNearestEndpoint(vEnd,&d1); if(d0>d1) en1->revertDirection(); intersections[i-1]=(en0->getEndpoint()+en1->getStartpoint())*0.5; i++; } } RS_Entity* en(getNearestEntity(coord, &dist, RS2::ResolveNone)); if(en==NULL) return false; int indexNearest=findEntity(en); // RS_Vector vp(en->getNearestPointOnEntity(coord,false)); // RS_Vector direction(en->getTangentDirection(vp)); // RS_Vector vp1(-direction.y,direction.x);//normal direction // double a2(vp1.squared()); // if(a2<RS_TOLERANCE2) return false; // vp1 *= distance/sqrt(a2); // move(vp1); // return true; RS_Polyline* pnew= static_cast<RS_Polyline*>(clone()); int i; i=indexNearest; int previousIndex(i); pnew->entityAt(i)->offset(coord,distance); RS_Vector vp; //offset all //fixme, this is too ugly for(i=indexNearest-1;i>=0;i--){ RS_VectorSolutions sol0=RS_Information::getIntersection(pnew->entityAt(previousIndex),entityAt(i),true); // RS_VectorSolutions sol1; double dmax(RS_TOLERANCE15); RS_Vector trimP(false); for(const RS_Vector& vp: sol0){ double d0( (vp - pnew->entityAt(previousIndex)->getStartpoint()).squared());//potential bug, need to trim better if(d0>dmax) { dmax=d0; trimP=vp; } } if(trimP.valid){ static_cast<RS_AtomicEntity*>(pnew->entityAt(previousIndex))->trimStartpoint(trimP); static_cast<RS_AtomicEntity*>(pnew->entityAt(i))->trimEndpoint(trimP); vp=pnew->entityAt(previousIndex)->getMiddlePoint(); }else{ vp=pnew->entityAt(previousIndex)->getStartpoint(); vp.rotate(entityAt(previousIndex)->getStartpoint(),entityAt(i)->getDirection2()-entityAt(previousIndex)->getDirection1()+M_PI); } pnew->entityAt(i)->offset(vp,distance); previousIndex=i; } previousIndex=indexNearest; for(i=indexNearest+1;i<length;i++){ RS_VectorSolutions sol0=RS_Information::getIntersection(pnew->entityAt(previousIndex),entityAt(i),true); // RS_VectorSolutions sol1; double dmax(RS_TOLERANCE15); RS_Vector trimP(false); for(const RS_Vector& vp: sol0){ double d0( (vp - pnew->entityAt(previousIndex)->getEndpoint()).squared());//potential bug, need to trim better if(d0>dmax) { dmax=d0; trimP=vp; } } if(trimP.valid){ static_cast<RS_AtomicEntity*>(pnew->entityAt(previousIndex))->trimEndpoint(trimP); static_cast<RS_AtomicEntity*>(pnew->entityAt(i))->trimStartpoint(trimP); vp=pnew->entityAt(previousIndex)->getMiddlePoint(); }else{ vp=pnew->entityAt(previousIndex)->getEndpoint(); vp.rotate(entityAt(previousIndex)->getEndpoint(),entityAt(i)->getDirection1()-entityAt(previousIndex)->getDirection2()+M_PI); } pnew->entityAt(i)->offset(vp,distance); previousIndex=i; } //trim //connect and trim RS_Modification m(*container, graphicView); for(i=0;i<length-1;i++){ RS_VectorSolutions sol0=RS_Information::getIntersection(pnew->entityAt(i),pnew->entityAt(i+1),true); if(sol0.getNumber()==0) { sol0=RS_Information::getIntersection(pnew->entityAt(i),pnew->entityAt(i+1)); // RS_Vector vp0(pnew->entityAt(i)->getEndpoint()); // RS_Vector vp1(pnew->entityAt(i+1)->getStartpoint()); // double a0(intersections.at(i).angleTo(vp0)); // double a1(intersections.at(i).angleTo(vp1)); RS_VectorSolutions sol1; for(const RS_Vector& vp: sol0){ if(RS_Math::isAngleBetween(intersections.at(i).angleTo(vp), pnew->entityAt(i)->getDirection2(), pnew->entityAt(i+1)->getDirection1(), false)==false){ sol1.push_back(vp); } } if(sol1.getNumber()==0) continue; RS_Vector trimP(sol1.getClosest(intersections.at(i))); static_cast<RS_AtomicEntity*>(pnew->entityAt(i))->trimEndpoint(trimP); static_cast<RS_AtomicEntity*>(pnew->entityAt(i+1))->trimStartpoint(trimP); }else{ RS_Vector trimP(sol0.getClosest(pnew->entityAt(i)->getStartpoint())); static_cast<RS_AtomicEntity*>(pnew->entityAt(i))->trimEndpoint(trimP); static_cast<RS_AtomicEntity*>(pnew->entityAt(i+1))->trimStartpoint(trimP); } } *this = *pnew; return true; }