RS_Vector RS_Line::prepareTrim(const RS_Vector& trimCoord, const RS_VectorSolutions& trimSol) { //prepare trimming for multiple intersections if ( ! trimSol.hasValid()) return(RS_Vector(false)); if ( trimSol.getNumber() == 1 ) return(trimSol.get(0)); auto&& vp0=trimSol.getClosest(trimCoord,NULL,0); double dr2=trimCoord.squaredTo(vp0); //the trim point found is closer to mouse location (trimCoord) than both end points, return this trim point if(dr2 < trimCoord.squaredTo(getStartpoint()) && dr2 < trimCoord.squaredTo(getEndpoint())) return vp0; //the closer endpoint to trimCoord RS_Vector vp1=(trimCoord.squaredTo(getStartpoint()) <= trimCoord.squaredTo(getEndpoint()))?getStartpoint():getEndpoint(); //searching for intersection in the direction of the closer end point auto&& dvp1=vp1 - trimCoord; RS_VectorSolutions sol1; for(size_t i=0; i<trimSol.size(); i++){ auto&& dvp2=trimSol.at(i) - trimCoord; if( RS_Vector::dotP(dvp1, dvp2) > RS_TOLERANCE) sol1.push_back(trimSol.at(i)); } //if found intersection in direction, return the closest to trimCoord from it if(sol1.size()) return sol1.getClosest(trimCoord,NULL,0); //no intersection by direction, return previously found closest intersection return vp0; }
RS_Vector RS_Line::prepareTrim(const RS_Vector& trimCoord, const RS_VectorSolutions& trimSol) { //prepare trimming for multiple intersections if ( ! trimSol.hasValid()) return(RS_Vector(false)); if ( trimSol.getNumber() == 1 ) return(trimSol.get(0)); return trimSol.getClosest(trimCoord,NULL,0); }
RS_Vector RS_Image::getNearestDist(double distance, const RS_Vector& coord, double* dist) const{ RS_VectorSolutions const& corners = getCorners(); RS_VectorSolutions points; for (size_t i = 0; i < corners.size(); ++i){ size_t const j = (i+1)%corners.size(); RS_Line const l{corners.get(i), corners.get(j)}; RS_Vector const& vp = l.getNearestDist(distance, coord, dist); points.push_back(vp); } return points.getClosest(coord, dist); }
void RS_ActionSnapIntersectionManual::mouseMoveEvent(QMouseEvent* e) { RS_DEBUG->print("RS_ActionSnapIntersectionManual::mouseMoveEvent begin"); RS_Entity* se = catchEntity(e); RS_Vector mouse = graphicView->toGraph(e->x(), e->y()); switch (getStatus()) { case ChooseEntity1: entity1 = se; break; case ChooseEntity2: { entity2 = se; coord = mouse; RS_VectorSolutions sol = RS_Information::getIntersection(entity1, entity2, false); //for (int i=0; i<sol.getNumber(); i++) { // ip = sol.get(i); // break; //} RS_Vector ip = sol.getClosest(coord); if (ip.valid) { deletePreview(); preview->addEntity( new RS_Circle(preview.get(), RS_CircleData( ip, graphicView->toGraphDX(4)))); drawPreview(); RS_DIALOGFACTORY->updateCoordinateWidget(ip, ip - graphicView->getRelativeZero()); } } break; default: break; } RS_DEBUG->print("RS_ActionSnapIntersectionManual::mouseMoveEvent end"); }
void RS_Circle::moveRef(const RS_Vector& ref, const RS_Vector& offset) { if(ref.distanceTo(data.center)<1.0e-4){ data.center += offset; return; } RS_Vector v1(data.radius, 0.0); RS_VectorSolutions sol; sol.push_back(data.center + v1); sol.push_back(data.center - v1); v1.set(0., data.radius); sol.push_back(data.center + v1); sol.push_back(data.center - v1); double dist; v1=sol.getClosest(ref,&dist); if(dist>1.0e-4) return; data.radius = data.center.distanceTo(v1 + offset); }
RS_Vector RS_Image::getNearestCenter(const RS_Vector& coord, double* dist) { RS_VectorSolutions points; RS_VectorSolutions corners = getCorners(); //bug#485, there's no clear reason to ignore snapping to center within an image // if(containsPoint(coord)){ // //if coord is within image // if(dist!=NULL) *dist=0.; // return coord; // } points.push_back((corners.get(0) + corners.get(1))/2.0); points.push_back((corners.get(1) + corners.get(2))/2.0); points.push_back((corners.get(2) + corners.get(3))/2.0); points.push_back((corners.get(3) + corners.get(0))/2.0); points.push_back((corners.get(0) + corners.get(2))/2.0); return points.getClosest(coord, dist); }
RS_Vector RS_Image::getNearestCenter(const RS_Vector& coord, double* dist) const{ RS_VectorSolutions const& corners{getCorners()}; //bug#485, there's no clear reason to ignore snapping to center within an image // if(containsPoint(coord)){ // //if coord is within image // if(dist) *dist=0.; // return coord; // } RS_VectorSolutions points; for (size_t i=0; i < corners.size(); ++i) { size_t const j = (i+1)%corners.size(); points.push_back((corners.get(i) + corners.get(j))*0.5); } points.push_back((corners.get(0) + corners.get(2))*0.5); return points.getClosest(coord, dist); }
/** * @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; }
void RS_ActionSnapIntersectionManual::trigger() { RS_DEBUG->print("RS_ActionSnapIntersectionManual::trigger()"); if (entity2!=NULL && entity2->isAtomic() && entity1!=NULL && entity1->isAtomic()) { RS_VectorSolutions sol = RS_Information::getIntersection(entity1, entity2, false); entity2 = NULL; entity1 = NULL; if (predecessor!=NULL) { RS_Vector ip = sol.getClosest(coord); if (ip.valid) { RS_CoordinateEvent e(ip); predecessor->coordinateEvent(&e); } } finish(false); } }
RS_Vector RS_Image::getNearestPointOnEntity(const RS_Vector& coord, bool onEntity, double* dist, RS_Entity** entity) const{ if (entity) { *entity = const_cast<RS_Image*>(this); } RS_VectorSolutions const& corners =getCorners(); //allow selecting image by clicking within images, bug#3464626 if(containsPoint(coord)){ //if coord is within image if(dist) *dist=0.; return coord; } RS_VectorSolutions points; for (size_t i=0; i < corners.size(); ++i){ size_t const j = (i+1)%corners.size(); RS_Line const l{corners.at(i), corners.at(j)}; RS_Vector const vp = l.getNearestPointOnEntity(coord, onEntity); points.push_back(vp); } return points.getClosest(coord, dist); }
RS_Vector RS_Image::getNearestEndpoint(const RS_Vector& coord, double* dist) const { RS_VectorSolutions corners =getCorners(); return corners.getClosest(coord, dist); }