Пример #1
0
void UmlActivityPartition::write(FileOut & out) {
  const char * p = (parent()->kind() == aPartition)
    ? "subpartition" : "group";
  
  out.indent();
  out << "<" << p << " xmi:type=\"uml:ActivityPartition\" name=\"";
  out.quote((const char*)name());//[jasa] ambiguous call
  out << '"';
  out.id(this);
  if (isDimension())
    out << " isDimension=\"true\"";
  if (isExternal())
    out << " isExternal=\"true\"";
  if (represents() != 0)
    out.ref(represents(), "represents");
  out << ">\n";
  out.indent(+1);
  
  write_description_properties(out); 
  
  const Q3PtrVector<UmlItem> ch = children();
  unsigned n = ch.size();
  
  for (unsigned i = 0; i != n; i += 1)
    ch[i]->write(out);
  
  out.indent(-1);
  out.indent();
  out << "</" << p << ">\n";

  unload();
}
Пример #2
0
bool REntity::isComplex(const RS::EntityType type) {
    return (type==RS::EntityAttributeDefinition ||
            type==RS::EntityAttribute ||
            type==RS::EntityHatch ||
            type==RS::EntityTextBased ||
            type==RS::EntityText ||
            isDimension(type));
}
Пример #3
0
void UmlActivityPartition::html(Q3CString pfix, unsigned int rank, unsigned int level) {
  define();
  
  chapter("Activity partition", pfix, rank, "activitypartition", level);

  Q3CString s = description();
  
  if (!s.isEmpty()) {
    fw.write("<p>");
    writeq(s);
    fw.write("<br /></p>");
  }
  
  if (isDimension())
    fw.write((isExternal())
	     ? "<p>is dimension, is external</p>\n"
	     : "<p>is dimension</p>\n");
  else if (isExternal())
    fw.write("<p>is external</p>\n");
    
  if (represents() != 0) {
    fw.write("<p>represents ");
    represents()->write();
    fw.write("</p>");
  }
    
  write_dependencies();
    
  UmlDiagram * d = associatedDiagram();
  
  if (d != 0) {
    fw.write("<p>Diagram : ");
    d->write();
    fw.write("</p>\n");
  }

  write_properties();

  write_children(pfix, rank, level);

  unload(FALSE, FALSE);
}
Пример #4
0
/**
 * Calculates the intersection point(s) between two entities.
 *
 * @param onEntities true: only return intersection points which are
 *                   on both entities.
 *                   false: return all intersection points.
 *
 * @todo support more entities
 *
 * @return All intersections of the two entities. The tangent flag in
 * RS_VectorSolutions is set if one intersection is a tangent point.
 */
RS_VectorSolutions RS_Information::getIntersection(RS_Entity* e1,
        RS_Entity* e2, bool onEntities) {

    RS_VectorSolutions ret;
    double tol = 1.0e-4;

    if (e1==NULL || e2==NULL ) {
        RS_DEBUG->print("RS_Information::getIntersection() for NULL entities");
        return ret;
    }
    if (e1->getId() == e2->getId()) {
        RS_DEBUG->print("RS_Information::getIntersection() of the same entity");
        return ret;
    }

    // unsupported entities / entity combinations:
    if (
        e1->rtti()==RS2::EntityText || e2->rtti()==RS2::EntityText ||
        isDimension(e1->rtti()) || isDimension(e2->rtti())) {
        return ret;
    }
    // a little check to avoid doing unneeded intersections, an attempt to avoid O(N^2) increasing of checking two-entity information
    if (onEntities
            && (
                e1 -> getMin().x > e2 -> getMax().x
                || e1 -> getMax().x < e2 -> getMin().x
                || e1 -> getMin().y > e2 -> getMax().y
                || e1 -> getMax().y < e2 -> getMin().y
                )
            ) {
            return ret;
    }

    // one entity is an ellipse:
    if (e1->rtti()==RS2::EntityEllipse || e2->rtti()==RS2::EntityEllipse) {
        if (e2->rtti()==RS2::EntityEllipse) std::swap( e1, e2);
        if (e2->rtti()==RS2::EntityEllipse) {
            ret = getIntersectionEllipseEllipse((RS_Ellipse*)e1, (RS_Ellipse *) e2);
        }
        if (e2->rtti()==RS2::EntityCircle) {
            ret = getIntersectionCircleEllipse((RS_Circle *)e2, (RS_Ellipse *) e1);
        }
        if (e2->rtti()==RS2::EntityArc) {
            ret = getIntersectionArcEllipse((RS_Arc *)e2, (RS_Ellipse *) e1);
        }
        if (e2->rtti()==RS2::EntityLine) {
            ret = getIntersectionLineEllipse((RS_Line*)e2, (RS_Ellipse*) e1);
            tol = 1.0e-1;
        }

        // not supported:
        else {
            return ret;
        }
    } else {

        RS_Entity* te1 = e1;
        RS_Entity* te2 = e2;

        // entity copies - so we only have to deal with lines and arcs
        RS_Line l1(NULL,
                   RS_LineData(RS_Vector(0.0, 0.0), RS_Vector(0.0,0.0)));
        RS_Line l2(NULL,
                   RS_LineData(RS_Vector(0.0, 0.0), RS_Vector(0.0,0.0)));

        RS_Arc a1(NULL,
                  RS_ArcData(RS_Vector(0.0,0.0), 1.0, 0.0, 2*M_PI, false));
        RS_Arc a2(NULL,
                  RS_ArcData(RS_Vector(0.0,0.0), 1.0, 0.0, 2*M_PI, false));

        // convert construction lines to lines:
        if (e1->rtti()==RS2::EntityConstructionLine) {
            RS_ConstructionLine* cl = (RS_ConstructionLine*)e1;

            l1.setStartpoint(cl->getPoint1());
            l1.setEndpoint(cl->getPoint2());

            te1 = &l1;
        }
        if (e2->rtti()==RS2::EntityConstructionLine) {
            RS_ConstructionLine* cl = (RS_ConstructionLine*)e2;

            l2.setStartpoint(cl->getPoint1());
            l2.setEndpoint(cl->getPoint2());

            te2 = &l2;
        }


        // convert circles to arcs:
        if (e1->rtti()==RS2::EntityCircle) {
            RS_Circle* c = (RS_Circle*)e1;

            RS_ArcData data(c->getCenter(), c->getRadius(), 0.0, 2*M_PI, false);
            a1.setData(data);

            te1 = &a1;
        }
        if (e2->rtti()==RS2::EntityCircle) {
            RS_Circle* c = (RS_Circle*)e2;

            RS_ArcData data(c->getCenter(), c->getRadius(), 0.0, 2*M_PI, false);
            a2.setData(data);

            te2 = &a2;
        }


        // line / line:
        //
        //else
        if (te1->rtti()==RS2::EntityLine &&
                te2->rtti()==RS2::EntityLine) {
            RS_Line * line1=(RS_Line*) te1;
            RS_Line * line2=(RS_Line*) te2;
            /* ToDo: 24 Aug 2011, Dongxu Li, if rtti() is not defined for the parent, the following check for splines may still cause segfault */
            if ( line1->getParent() != NULL && line1->getParent() == line2->getParent()) {
                if ( line1->getParent()->rtti()==RS2::EntitySpline ) {
                    //do not calculate intersections from neighboring lines of a spline
                    if ( abs(line1->getParent()->findEntity(line1) - line1->getParent()->findEntity(line2)) <= 1 ) {
                        return ret;
                    }
                }
            }

            ret = getIntersectionLineLine(line1, line2);
        }

        // line / arc:
        //
        else if (te1->rtti()==RS2::EntityLine &&
                 te2->rtti()==RS2::EntityArc) {

            RS_Line* line = (RS_Line*)te1;
            RS_Arc* arc = (RS_Arc*)te2;

            ret = getIntersectionLineArc(line, arc);
        }

        // arc / line:
        //
        else if (te1->rtti()==RS2::EntityArc &&
                 te2->rtti()==RS2::EntityLine) {

            RS_Arc* arc = (RS_Arc*)te1;
            RS_Line* line = (RS_Line*)te2;

            ret = getIntersectionLineArc(line, arc);
        }

        // arc / arc:
        //
        else if (te1->rtti()==RS2::EntityArc &&
                 te2->rtti()==RS2::EntityArc) {

            RS_Arc* arc1 = (RS_Arc*)te1;
            RS_Arc* arc2 = (RS_Arc*)te2;

            ret = getIntersectionArcArc(arc1, arc2);
            // ellipse / ellipse
            //
        } else {
            RS_DEBUG->print("RS_Information::getIntersection:: Unsupported entity type.");
        }

    }


    // Check all intersection points for being on entities:
    //
    if (onEntities==true) {
        if (!e1->isPointOnEntity(ret.get(0), tol) ||
                !e2->isPointOnEntity(ret.get(0), tol)) {
            ret.set(0, RS_Vector(false));
        }
        if (!e1->isPointOnEntity(ret.get(1), tol) ||
                !e2->isPointOnEntity(ret.get(1), tol)) {
            ret.set(1, RS_Vector(false));
        }
        if (!e1->isPointOnEntity(ret.get(2), tol) ||
                !e2->isPointOnEntity(ret.get(2), tol)) {
            ret.set(2, RS_Vector(false));
        }
        if (!e1->isPointOnEntity(ret.get(3), tol) ||
                !e2->isPointOnEntity(ret.get(3), tol)) {
            ret.set(3, RS_Vector(false));
        }
    }

    int k=0;
    for (int i=0; i<4; ++i) {
        if (ret.get(i).valid) {
            ret.set(k, ret.get(i));
            k++;
        }
    }
    for (int i=k; i<4; ++i) {
        ret.set(i, RS_Vector(false));
    }

    return ret;
}
Пример #5
0
/**
 * Calculates the intersection point(s) between two entities.
 *
 * @param onEntities true: only return intersection points which are
 *                   on both entities.
 *                   false: return all intersection points.
 *
 * @todo support more entities
 *
 * @return All intersections of the two entities. The tangent flag in
 * RS_VectorSolutions is set if one intersection is a tangent point.
 */
RS_VectorSolutions RS_Information::getIntersection(RS_Entity const* e1,
		RS_Entity const* e2, bool onEntities) {

    RS_VectorSolutions ret;
    const double tol = 1.0e-4;

	if (!(e1 && e2) ) {
		RS_DEBUG->print("RS_Information::getIntersection() for nullptr entities");
        return ret;
    }
    if (e1->getId() == e2->getId()) {
        RS_DEBUG->print("RS_Information::getIntersection() of the same entity");
        return ret;
    }

    // unsupported entities / entity combinations:
    if (
        e1->rtti()==RS2::EntityMText || e2->rtti()==RS2::EntityMText ||
        e1->rtti()==RS2::EntityText || e2->rtti()==RS2::EntityText ||
        isDimension(e1->rtti()) || isDimension(e2->rtti())) {
        return ret;
    }

	if (onEntities && !(e1->isConstruction() || e2->isConstruction())) {
	// a little check to avoid doing unneeded intersections, an attempt to avoid O(N^2) increasing of checking two-entity information
		LC_Rect const rect1{e1->getMin(), e1->getMax()};
		LC_Rect const rect2{e2->getMin(), e2->getMax()};

		if (onEntities && !rect1.intersects(rect2, RS_TOLERANCE)) {
			return ret;
		}
	}

    //avoid intersections between line segments the same spline
    /* ToDo: 24 Aug 2011, Dongxu Li, if rtti() is not defined for the parent, the following check for splines may still cause segfault */
	if ( e1->getParent() && e1->getParent() == e2->getParent()) {
        if ( e1->getParent()->rtti()==RS2::EntitySpline ) {
            //do not calculate intersections from neighboring lines of a spline
            if ( abs(e1->getParent()->findEntity(e1) - e1->getParent()->findEntity(e2)) <= 1 ) {
                return ret;
            }
        }
    }

	if(e1->rtti() == RS2::EntitySplinePoints || e2->rtti() == RS2::EntitySplinePoints)
	{
		ret = LC_SplinePoints::getIntersection(e1, e2);
	}
	else
	{
		// issue #484 , quadratic intersection solver is not robust enough for quadratic-quadratic
		// TODO, implement a robust algorithm for quadratic based solvers, and detecting entity type
		// circles/arcs can be removed

		if(e1->rtti()==RS2::EntityCircle && e2->rtti()==RS2::EntityCircle){
			//use specialized arc-arc intersection solver
			ret=getIntersectionArcArc(e1, e2);
		}else{
			const auto qf1=e1->getQuadratic();
			const auto qf2=e2->getQuadratic();
			ret=LC_Quadratic::getIntersection(qf1,qf2);
		}
	}
    RS_VectorSolutions ret2;
	for(const RS_Vector& vp: ret){
		if (!vp.valid) continue;
		if (onEntities) {
            //ignore intersections not on entity
            if (!(
                        (e1->isConstruction(true) || e1->isPointOnEntity(vp, tol)) &&
                        (e2->isConstruction(true) || e2->isPointOnEntity(vp, tol))
                        )
                    ) {
//				std::cout<<"Ignored intersection "<<vp<<std::endl;
//				std::cout<<"because: e1->isPointOnEntity(ret.get(i), tol)="<<e1->isPointOnEntity(vp, tol)
//					<<"\t(e2->isPointOnEntity(ret.get(i), tol)="<<e2->isPointOnEntity(vp, tol)<<std::endl;
                continue;
            }
        }
        // need to test whether the intersection is tangential
		RS_Vector direction1=e1->getTangentDirection(vp);
		RS_Vector direction2=e2->getTangentDirection(vp);
        if( direction1.valid && direction2.valid && fabs(fabs(direction1.dotP(direction2)) - sqrt(direction1.squared()*direction2.squared())) < sqrt(tol)*tol )
            ret2.setTangent(true);
        //TODO, make the following tangential test, nearest test work for all entity types

//        RS_Entity   *lpLine = nullptr,
//                    *lpCircle = nullptr;
//        if( RS2::EntityLine == e1->rtti() && RS2::EntityCircle == e2->rtti()) {
//            lpLine = e1;
//            lpCircle = e2;
//        }
//        else if( RS2::EntityCircle == e1->rtti() && RS2::EntityLine == e2->rtti()) {
//            lpLine = e2;
//            lpCircle = e1;
//        }
//        if( nullptr != lpLine && nullptr != lpCircle) {
//            double dist = 0.0;
//            RS_Vector nearest = lpLine->getNearestPointOnEntity( lpCircle->getCenter(), false, &dist);

//            // special case: line touches circle tangent
//            if( nearest.valid && fabs( dist - lpCircle->getRadius()) < tol) {
//                ret.set(i,nearest);
//                ret2.setTangent(true);
//            }
//        }
        ret2.push_back(vp);
    }

    return ret2;
}
Пример #6
0
/**
 * Calculates the intersection point(s) between two entities.
 *
 * @param onEntities true: only return intersection points which are
 *                   on both entities.
 *                   false: return all intersection points.
 *
 * @todo support more entities
 *
 * @return All intersections of the two entities. The tangent flag in
 * RS_VectorSolutions is set if one intersection is a tangent point.
 */
RS_VectorSolutions RS_Information::getIntersection(RS_Entity* e1,
    RS_Entity* e2, bool onEntities)
{

  RS_VectorSolutions ret;
  double tol = 1.0e-4;

  if (e1==NULL || e2==NULL)
  {
    return ret;
  }

  // unsupported entities / entity combinations:
  if ((e1->rtti()==RS2::EntityEllipse && e2->rtti()==RS2::EntityEllipse) ||
      e1->rtti()==RS2::EntityText || e2->rtti()==RS2::EntityText ||
      isDimension(e1->rtti()) || isDimension(e2->rtti()))
  {
    return ret;
  }

  // (only) one entity is an ellipse:
  if (e1->rtti()==RS2::EntityEllipse || e2->rtti()==RS2::EntityEllipse)
  {
    if (e2->rtti()==RS2::EntityEllipse)
    {
      RS_Entity* tmp = e1;
      e1 = e2;
      e2 = tmp;
    }
    if (e2->rtti()==RS2::EntityLine)
    {
      RS_Ellipse* ellipse = (RS_Ellipse*)e1;
      ret = getIntersectionLineEllipse((RS_Line*)e2, ellipse);
      tol = 1.0e-1;
    }

    // ellipse / arc, ellipse / ellipse: not supported:
    else
    {
      return ret;
    }
  }
  else
  {

    RS_Entity* te1 = e1;
    RS_Entity* te2 = e2;

    // entity copies - so we only have to deal with lines and arcs
    RS_Line l1(NULL,
               RS_LineData(RS_Vector(0.0, 0.0), RS_Vector(0.0,0.0)));
    RS_Line l2(NULL,
               RS_LineData(RS_Vector(0.0, 0.0), RS_Vector(0.0,0.0)));

    RS_Arc a1(NULL,
              RS_ArcData(RS_Vector(0.0,0.0), 1.0, 0.0, 2*M_PI, false));
    RS_Arc a2(NULL,
              RS_ArcData(RS_Vector(0.0,0.0), 1.0, 0.0, 2*M_PI, false));

    // convert construction lines to lines:
    if (e1->rtti()==RS2::EntityConstructionLine)
    {
      RS_ConstructionLine* cl = (RS_ConstructionLine*)e1;

      l1.setStartpoint(cl->getPoint1());
      l1.setEndpoint(cl->getPoint2());

      te1 = &l1;
    }
    if (e2->rtti()==RS2::EntityConstructionLine)
    {
      RS_ConstructionLine* cl = (RS_ConstructionLine*)e2;

      l2.setStartpoint(cl->getPoint1());
      l2.setEndpoint(cl->getPoint2());

      te2 = &l2;
    }


    // convert circles to arcs:
    if (e1->rtti()==RS2::EntityCircle)
    {
      RS_Circle* c = (RS_Circle*)e1;

      RS_ArcData data(c->getCenter(), c->getRadius(), 0.0, 2*M_PI, false);
      a1.setData(data);

      te1 = &a1;
    }
    if (e2->rtti()==RS2::EntityCircle)
    {
      RS_Circle* c = (RS_Circle*)e2;

      RS_ArcData data(c->getCenter(), c->getRadius(), 0.0, 2*M_PI, false);
      a2.setData(data);

      te2 = &a2;
    }


    // line / line:
    //
    //else
    if (te1->rtti()==RS2::EntityLine &&
        te2->rtti()==RS2::EntityLine)
    {

      RS_Line* line1 = (RS_Line*)te1;
      RS_Line* line2 = (RS_Line*)te2;

      ret = getIntersectionLineLine(line1, line2);
    }

    // line / arc:
    //
    else if (te1->rtti()==RS2::EntityLine &&
             te2->rtti()==RS2::EntityArc)
    {

      RS_Line* line = (RS_Line*)te1;
      RS_Arc* arc = (RS_Arc*)te2;

      ret = getIntersectionLineArc(line, arc);
    }

    // arc / line:
    //
    else if (te1->rtti()==RS2::EntityArc &&
             te2->rtti()==RS2::EntityLine)
    {

      RS_Arc* arc = (RS_Arc*)te1;
      RS_Line* line = (RS_Line*)te2;

      ret = getIntersectionLineArc(line, arc);
    }

    // arc / arc:
    //
    else if (te1->rtti()==RS2::EntityArc &&
             te2->rtti()==RS2::EntityArc)
    {

      RS_Arc* arc1 = (RS_Arc*)te1;
      RS_Arc* arc2 = (RS_Arc*)te2;

      ret = getIntersectionArcArc(arc1, arc2);
    }
    else
    {
      RS_DEBUG->print("RS_Information::getIntersection:: Unsupported entity type.");
    }
  }


  // Check all intersection points for being on entities:
  //
  if (onEntities==true)
  {
    if (!e1->isPointOnEntity(ret.get(0), tol) ||
        !e2->isPointOnEntity(ret.get(0), tol))
    {
      ret.set(0, RS_Vector(false));
    }
    if (!e1->isPointOnEntity(ret.get(1), tol) ||
        !e2->isPointOnEntity(ret.get(1), tol))
    {
      ret.set(1, RS_Vector(false));
    }
    if (!e1->isPointOnEntity(ret.get(2), tol) ||
        !e2->isPointOnEntity(ret.get(2), tol))
    {
      ret.set(2, RS_Vector(false));
    }
    if (!e1->isPointOnEntity(ret.get(3), tol) ||
        !e2->isPointOnEntity(ret.get(3), tol))
    {
      ret.set(3, RS_Vector(false));
    }
  }

  int k=0;
  for (int i=0; i<4; ++i)
  {
    if (ret.get(i).valid)
    {
      ret.set(k, ret.get(i));
      k++;
    }
  }
  for (int i=k; i<4; ++i)
  {
    ret.set(i, RS_Vector(false));
  }

  return ret;
}
Пример #7
0
/**
 * Calculates the intersection point(s) between two entities.
 *
 * @param onEntities true: only return intersection points which are
 *                   on both entities.
 *                   false: return all intersection points.
 *
 * @todo support more entities
 *
 * @return All intersections of the two entities. The tangent flag in
 * RS_VectorSolutions is set if one intersection is a tangent point.
 */
RS_VectorSolutions RS_Information::getIntersection(RS_Entity* e1,
        RS_Entity* e2, bool onEntities) {

    RS_VectorSolutions ret;
    const double tol = 1.0e-4;

    if (e1==NULL || e2==NULL ) {
        RS_DEBUG->print("RS_Information::getIntersection() for NULL entities");
        return ret;
    }
    if (e1->getId() == e2->getId()) {
        RS_DEBUG->print("RS_Information::getIntersection() of the same entity");
        return ret;
    }

    // unsupported entities / entity combinations:
    if (
        e1->rtti()==RS2::EntityMText || e2->rtti()==RS2::EntityMText ||
        e1->rtti()==RS2::EntityText || e2->rtti()==RS2::EntityText ||
        isDimension(e1->rtti()) || isDimension(e2->rtti())) {
        return ret;
    }
    // a little check to avoid doing unneeded intersections, an attempt to avoid O(N^2) increasing of checking two-entity information
    if (onEntities &&
            (! (e1 -> isConstructionLayer() || e2 -> isConstructionLayer() ))
            && (
                e1 -> getMin().x > e2 -> getMax().x
                || e1 -> getMax().x < e2 -> getMin().x
                || e1 -> getMin().y > e2 -> getMax().y
                || e1 -> getMax().y < e2 -> getMin().y
                )
            ) {
            return ret;
    }

    //avoid intersections between line segments the same spline
    /* ToDo: 24 Aug 2011, Dongxu Li, if rtti() is not defined for the parent, the following check for splines may still cause segfault */
    if ( e1->getParent() != NULL && e1->getParent() == e2->getParent()) {
        if ( e1->getParent()->rtti()==RS2::EntitySpline ) {
            //do not calculate intersections from neighboring lines of a spline
            if ( abs(e1->getParent()->findEntity(e1) - e1->getParent()->findEntity(e2)) <= 1 ) {
                return ret;
            }
        }
    }
    const auto&& qf1=e1->getQuadratic();
    const auto&& qf2=e2->getQuadratic();
    ret=LC_Quadratic::getIntersection(qf1,qf2);
    RS_VectorSolutions ret2;
    for(int i=0;i<ret.getNumber();i++) {
        RS_Vector&& vp=ret.get(i);
        if ( ! ret.get(i).valid) continue;
        if (onEntities==true) {
            //ignore intersections not on entity
            if (!(
                        (e1->isConstructionLayer(true) || e1->isPointOnEntity(vp, tol)) &&
                        (e2->isConstructionLayer(true) || e2->isPointOnEntity(vp, tol))
                        )
                    ) {
//                std::cout<<"Ignored intersection "<<ret.get(i)<<std::endl;
//                std::cout<<"because: e1->isPointOnEntity(ret.get(i), tol)="<<e1->isPointOnEntity(ret.get(i), tol)
//                    <<"\t(e2->isPointOnEntity(ret.get(i), tol)="<<e2->isPointOnEntity(ret.get(i), tol)<<std::endl;
                continue;
            }
        }
        // need to test whether the intersection is tangential
        RS_Vector&& direction1=e1->getTangentDirection(vp);
        RS_Vector&& direction2=e2->getTangentDirection(vp);
        if( direction1.valid && direction2.valid && fabs(fabs(direction1.dotP(direction2)) - sqrt(direction1.squared()*direction2.squared())) < sqrt(tol)*tol )
            ret2.setTangent(true);
        //TODO, make the following tangential test, nearest test work for all entity types

//        RS_Entity   *lpLine = NULL,
//                    *lpCircle = NULL;
//        if( RS2::EntityLine == e1->rtti() && RS2::EntityCircle == e2->rtti()) {
//            lpLine = e1;
//            lpCircle = e2;
//        }
//        else if( RS2::EntityCircle == e1->rtti() && RS2::EntityLine == e2->rtti()) {
//            lpLine = e2;
//            lpCircle = e1;
//        }
//        if( NULL != lpLine && NULL != lpCircle) {
//            double dist = 0.0;
//            RS_Vector nearest = lpLine->getNearestPointOnEntity( lpCircle->getCenter(), false, &dist);

//            // special case: line touches circle tangent
//            if( nearest.valid && fabs( dist - lpCircle->getRadius()) < tol) {
//                ret.set(i,nearest);
//                ret2.setTangent(true);
//            }
//        }
        ret2.push_back(vp);
    }

    return ret2;
}
Пример #8
0
/**
 * Calculates the intersection point(s) between two entities.
 *
 * @param onEntities true: only return intersection points which are
 *                   on both entities.
 *                   false: return all intersection points.
 *
 * @todo support more entities
 *
 * @return All intersections of the two entities. The tangent flag in
 * RS_VectorSolutions is set if one intersection is a tangent point.
 */
RS_VectorSolutions RS_Information::getIntersection(RS_Entity* e1,
        RS_Entity* e2, bool onEntities) {

    RS_VectorSolutions ret;
    double tol = 1.0e-4;

    if (e1==NULL || e2==NULL ) {
        RS_DEBUG->print("RS_Information::getIntersection() for NULL entities");
        return ret;
    }
    if (e1->getId() == e2->getId()) {
        RS_DEBUG->print("RS_Information::getIntersection() of the same entity");
        return ret;
    }

    // unsupported entities / entity combinations:
    if (
        e1->rtti()==RS2::EntityMText || e2->rtti()==RS2::EntityMText ||
        e1->rtti()==RS2::EntityText || e2->rtti()==RS2::EntityText ||
        isDimension(e1->rtti()) || isDimension(e2->rtti())) {
        return ret;
    }
    // a little check to avoid doing unneeded intersections, an attempt to avoid O(N^2) increasing of checking two-entity information
    if (onEntities &&
            (! (e1 -> isHelpLayer() || e2 -> isHelpLayer() ))
            && (
                e1 -> getMin().x > e2 -> getMax().x
                || e1 -> getMax().x < e2 -> getMin().x
                || e1 -> getMin().y > e2 -> getMax().y
                || e1 -> getMax().y < e2 -> getMin().y
                )
            ) {
            return ret;
    }

    //avoid intersections between line segments the same spline
    /* ToDo: 24 Aug 2011, Dongxu Li, if rtti() is not defined for the parent, the following check for splines may still cause segfault */
    if ( e1->getParent() != NULL && e1->getParent() == e2->getParent()) {
        if ( e1->getParent()->rtti()==RS2::EntitySpline ) {
            //do not calculate intersections from neighboring lines of a spline
            if ( abs(e1->getParent()->findEntity(e1) - e1->getParent()->findEntity(e2)) <= 1 ) {
                return ret;
            }
        }
    }
    const auto&& qf1=e1->getQuadratic();
    const auto&& qf2=e2->getQuadratic();
    ret=LC_Quadratic::getIntersection(qf1,qf2);
    RS_VectorSolutions ret2;
    for(int i=0;i<ret.getNumber();i++) {
        if ( ! ret.get(i).valid) continue;
        if (onEntities==true) {
            //ignore intersections not on entity
            if (!(
                        (e1->isHelpLayer(true) || e1->isPointOnEntity(ret.get(i), tol)) &&
                        (e2->isHelpLayer(true) || e2->isPointOnEntity(ret.get(i), tol))
                        )
                    ) {
//                std::cout<<"Ignored intersection "<<ret.get(i)<<std::endl;
//                std::cout<<"because: e1->isPointOnEntity(ret.get(i), tol)="<<e1->isPointOnEntity(ret.get(i), tol)
//                    <<"\t(e2->isPointOnEntity(ret.get(i), tol)="<<e2->isPointOnEntity(ret.get(i), tol)<<std::endl;
                continue;
            }
        }
        ret2.push_back(ret.get(i));
    }

    return ret2;
}