/** @return the nearest of equidistant middle points of the line. */ RS_Vector RS_Line::getNearestMiddle(const RS_Vector& coord, double* dist, int middlePoints )const { // RS_DEBUG->print("RS_Line::getNearestMiddle(): begin\n"); RS_Vector dvp(getEndpoint() - getStartpoint()); double l=dvp.magnitude(); if( l<= RS_TOLERANCE) { //line too short return const_cast<RS_Line*>(this)->getNearestCenter(coord, dist); /* ?????? */ } RS_Vector vp0(getNearestPointOnEntity(coord,true,dist)); int counts=middlePoints+1; int i( static_cast<int>(vp0.distanceTo(getStartpoint())/l*counts+0.5)); if(!i) i++; // remove end points if(i==counts) i--; vp0=getStartpoint() + dvp*(double(i)/double(counts)); if(dist != NULL) { *dist=vp0.distanceTo(coord); } //std::cout << "rs_line.cpp Dist " << *dist << "\n"; // RS_DEBUG->print("RS_Line::getNearestMiddle(): end\n"); return vp0; }
/** @return the nearest of equidistant middle points of the line. */ RS_Vector RS_Line::getNearestMiddle(const RS_Vector& coord, double* dist, int middlePoints ) { RS_DEBUG->print("RS_Line::getNearestMiddle(): begin\n"); RS_Vector dvp(getEndpoint() - getStartpoint()); double l=dvp.magnitude(); if( l<= RS_TOLERANCE) { //line too short RS_Vector vp(getStartpoint() + dvp*0.5); if (dist != NULL) { *dist=vp.distanceTo(coord); } return vp; } RS_Vector vp0(getNearestPointOnEntity(coord,true,dist)); int counts=middlePoints+1; int i( static_cast<int>(vp0.distanceTo(getStartpoint())/l*counts+0.5)); if(!i) i++; // remove end points if(i==counts) i--; vp0=getStartpoint() + dvp*(double(i)/double(counts)); if(dist != NULL) { *dist=vp0.distanceTo(coord); } RS_DEBUG->print("RS_Line::getNearestMiddle(): end\n"); return vp0; }
/** * @todo Implement this. */ double RS_Ellipse::getDistanceToPoint(const RS_Vector& coord, RS_Entity** entity, RS2::ResolveLevel, double /*solidDist*/) { double dist = RS_MAXDOUBLE; getNearestPointOnEntity(coord, true, &dist, entity); return dist; }
double RS_Ellipse::getDistanceToPoint(const RS_Vector& coord, RS_Entity** entity, RS2::ResolveLevel, double /*solidDist*/) { double dToEntity = RS_MAXDOUBLE; getNearestPointOnEntity(coord, true, &dToEntity, entity); // RVT 6 Jan 2011 : Add selection by center point double dToCenter=data.center.distanceTo(coord); return std::min(dToEntity,dToCenter); }
/** * @return Distance from one of the boundry lines of this solid to given point. * */ double RS_Solid::getDistanceToPoint(const RS_Vector& coord, RS_Entity** entity, RS2::ResolveLevel /*level*/, double /*solidDist*/)const { if (entity!=nullptr) { *entity = const_cast<RS_Solid*>(this); } double ret; getNearestPointOnEntity(coord,true,&ret,entity); return ret; }
double RS_Entity::getDistanceToPoint(const RS_Vector& coord, RS_Entity** entity, RS2::ResolveLevel /*level*/, double /*solidDist*/) const { if (entity) { *entity=const_cast<RS_Entity*>(this); } double dToEntity = RS_MAXDOUBLE; (void) getNearestPointOnEntity(coord, true, &dToEntity, entity); // RVT 6 Jan 2011 : Add selection by center point if(getCenter().valid){ double dToCenter=getCenter().distanceTo(coord); return std::min(dToEntity,dToCenter); }else return dToEntity; }
/** * @brief compute middlePoints for each quadrant of a circle * * 0 middlePoints snaps to axis intersection at 0, 90, 180 and 270 degree (getNearestEndpoint) \n * 1 middlePoints snaps to 45, 135, 225 and 315 degree \n * 2 middlePoints snaps to 30, 60, 120, 150, 210, 240, 300 and 330 degree \n * and so on * * @param coord coordinates to compute, e.g. mouse cursor position * @param dist double pointer to return distance between mouse pointer and nearest entity point * @param middlePoints number of middle points to compute per quadrant (0 for endpoints) * @return the nearest of equidistant middle points of the circles quadrants. */ RS_Vector RS_Circle::getNearestMiddle(const RS_Vector& coord, double* dist /*= nullptr*/, const int middlePoints /*= 1*/) const { if( data.radius <= RS_TOLERANCE) { //circle too short if ( nullptr != dist) { *dist = RS_MAXDOUBLE; } return RS_Vector(false); } RS_Vector vPoint( getNearestPointOnEntity( coord, true, dist)); int iCounts = middlePoints + 1; double dAngleSteps = M_PI_2 / iCounts; double dAngleToPoint = data.center.angleTo(vPoint); int iStepCount = static_cast<int>((dAngleToPoint + 0.5 * dAngleSteps) / dAngleSteps); if( 0 < middlePoints) { // for nearest middle eliminate start/endpoints int iQuadrant = static_cast<int>(dAngleToPoint / 0.5 / M_PI); int iQuadrantStep = iStepCount - iQuadrant * iCounts; if( 0 == iQuadrantStep) { ++iStepCount; } else if( iCounts == iQuadrantStep) { --iStepCount; } } vPoint.setPolar( data.radius, dAngleSteps * iStepCount); vPoint.move( data.center); if(dist) { *dist = vPoint.distanceTo( coord); } return vPoint; }
bool RS_Line::isTangent(const RS_CircleData& circleData){ double d; getNearestPointOnEntity(circleData.center,false,&d); if(fabs(d-circleData.radius)<RS_TOLERANCE) return true; return false; }
double RS_Line::getDistanceToPoint(const RS_Vector& coord, RS_Entity** entity, RS2::ResolveLevel /*level*/, double /*solidDist*/)const { // RS_DEBUG->print("RS_Line::getDistanceToPoint"); if (entity!=NULL) { *entity = const_cast<RS_Line*>(this); } double ret; getNearestPointOnEntity(coord,true,&ret,entity); //std::cout<<"rs_line::getDistanceToPoint(): new algorithm dist= "<<ret<<std::endl; return ret; // // check endpoints first: // double dist = coord.distanceTo(getStartpoint()); // if (dist<1.0e-4) { // RS_DEBUG->print("RS_Line::getDistanceToPoint: OK1"); // return dist; // } // dist = coord.distanceTo(getEndpoint()); // if (dist<1.0e-4) { // RS_DEBUG->print("RS_Line::getDistanceToPoint: OK2"); // return dist; // } // // dist = RS_MAXDOUBLE; // RS_Vector ae = data.endpoint-data.startpoint; // RS_Vector ea = data.startpoint-data.endpoint; // RS_Vector ap = coord-data.startpoint; // RS_Vector ep = coord-data.endpoint; // // if (ae.magnitude()<1.0e-6 || ea.magnitude()<1.0e-6) { // RS_DEBUG->print("RS_Line::getDistanceToPoint: OK2a"); // return dist; // } // // // Orthogonal projection from both sides: // RS_Vector ba = ae * RS_Vector::dotP(ae, ap) / // RS_Math::pow(ae.magnitude(), 2); // RS_Vector be = ea * RS_Vector::dotP(ea, ep) / // RS_Math::pow(ea.magnitude(), 2); // // // Check if the projection is outside this line: // if (ba.magnitude()>ae.magnitude() || be.magnitude()>ea.magnitude()) { // // return distance to endpoint // getNearestEndpoint(coord, &dist); // RS_DEBUG->print("RS_Line::getDistanceToPoint: OK3"); // return dist; // } // //RS_DEBUG->print("ba: %f", ba.magnitude()); // //RS_DEBUG->print("ae: %f", ae.magnitude()); // // RS_Vector cp = RS_Vector::crossP(ap, ae); // dist = cp.magnitude() / ae.magnitude(); // // RS_DEBUG->print("RS_Line::getDistanceToPoint: OK4"); // std::cout<<"rs_line::getDistanceToPoint(): Old algorithm dist= "<<ret<<std::endl; // // return dist; }