/** * create the path of centers of common tangent circles of the two given circles *@ return nullptr, if failed *@ at success return either an ellipse or hyperbola */ std::vector<RS_Entity*> RS_Creation::createCircleTangent2( RS_Entity* circle1,RS_Entity* circle2) { std::vector<RS_Entity*> ret(0, nullptr); if (!(circle1 && circle2)) return ret; RS_Entity* e1=circle1; RS_Entity* e2=circle2; if (e1->getRadius() < e2->getRadius()) std::swap(e1,e2); RS_Vector center1=e1->getCenter(); RS_Vector center2=e2->getCenter(); RS_Vector cp=(center1+center2)*0.5; double dist=center1.distanceTo(center2); if(dist<RS_TOLERANCE) return ret; RS_Vector vp= center1 - cp; double c=dist/(e1->getRadius()+e2->getRadius()); if( c < 1. - RS_TOLERANCE) { //two circles intersection or one circle in the other, there's an ellipse path ret.push_back(new RS_Ellipse(nullptr, RS_EllipseData(cp,vp,sqrt(1. - c*c),0.,0.,false))); } if( dist + e2 ->getRadius() < e1->getRadius() +RS_TOLERANCE ) { //one circle inside of another, the path is an ellipse return ret; } if(c > 1. + RS_TOLERANCE) { //not circle in circle, there's a hyperbola path c= (e1->getRadius() - e2->getRadius())/dist; ret.push_back(new LC_Hyperbola(nullptr, LC_HyperbolaData(cp,vp*c,sqrt(1. - c*c),0.,0.,false))); return ret; } ret.push_back(new RS_Line{cp, {cp.x - vp.y, cp.y+vp.x}}); return ret; }
bool RS_ActionDrawEllipseInscribe::preparePreview(){ valid=false; if(getStatus() == SetLine4) { RS_Ellipse e(preview.get(), RS_EllipseData()); valid= e.createInscribeQuadrilateral(lines); if(valid){ eData.reset(new RS_EllipseData(e.getData())); }else if( RS_DIALOGFACTORY){ RS_DIALOGFACTORY->commandMessage(tr("Can not determine uniquely an ellipse")); } } return valid; }
/** * Updates the entity buffer of this insert entity. This method * needs to be called whenever the block this insert is based on changes. */ void RS_Insert::update() { RS_DEBUG->print("RS_Insert::update"); RS_DEBUG->print("RS_Insert::update: name: %s", data.name.toLatin1().data()); // RS_DEBUG->print("RS_Insert::update: insertionPoint: %f/%f", // data.insertionPoint.x, data.insertionPoint.y); if (updateEnabled==false) { return; } clear(); RS_Block* blk = getBlockForInsert(); if (blk==nullptr) { //return nullptr; RS_DEBUG->print("RS_Insert::update: Block is nullptr"); return; } if (isUndone()) { RS_DEBUG->print("RS_Insert::update: Insert is in undo list"); return; } if (fabs(data.scaleFactor.x)<1.0e-6 || fabs(data.scaleFactor.y)<1.0e-6) { RS_DEBUG->print("RS_Insert::update: scale factor is 0"); return; } RS_Pen tmpPen; /*QListIterator<RS_Entity> it = createIterator(); RS_Entity* e; while ( (e = it.current()) != nullptr ) { ++it;*/ RS_DEBUG->print("RS_Insert::update: cols: %d, rows: %d", data.cols, data.rows); RS_DEBUG->print("RS_Insert::update: block has %d entities", blk->count()); //int i_en_counts=0; for(auto e: *blk){ for (int c=0; c<data.cols; ++c) { // RS_DEBUG->print("RS_Insert::update: col %d", c); for (int r=0; r<data.rows; ++r) { // i_en_counts++; // RS_DEBUG->print("RS_Insert::update: row %d", r); if (e->rtti()==RS2::EntityInsert && data.updateMode!=RS2::PreviewUpdate) { // RS_DEBUG->print("RS_Insert::update: updating sub-insert"); ((RS_Insert*)e)->update(); } // RS_DEBUG->print("RS_Insert::update: cloning entity"); RS_Entity* ne; if ( (data.scaleFactor.x - data.scaleFactor.y)>1.0e-6) { if (e->rtti()== RS2::EntityArc) { RS_Arc* a= (RS_Arc*)e; ne = new RS_Ellipse(this, RS_EllipseData(a->getCenter(), RS_Vector(a->getRadius(), 0), 1, a->getAngle1(), a->getAngle2(), a->isReversed() )); ne->setLayer(e->getLayer()); ne->setPen(e->getPen(false)); } else if (e->rtti()== RS2::EntityCircle) { RS_Circle* a= (RS_Circle*)e; ne = new RS_Ellipse(this, RS_EllipseData(a->getCenter(), RS_Vector(a->getRadius(), 0), 1, 0.0,2.0*M_PI, false)); ne->setLayer(e->getLayer()); ne->setPen(e->getPen(false)); } else ne = e->clone(); } else ne = e->clone(); ne->initId(); ne->setUpdateEnabled(false); // if entity layer are 0 set to insert layer to allow "1 layer control" bug ID #3602152 RS_Layer *l= ne->getLayer();//special fontchar block don't have if (l != nullptr && ne->getLayer()->getName() == "0") ne->setLayer(this->getLayer()); ne->setParent(this); ne->setVisible(getFlag(RS2::FlagVisible)); // RS_DEBUG->print("RS_Insert::update: transforming entity"); // Move: // RS_DEBUG->print("RS_Insert::update: move 1"); if (fabs(data.scaleFactor.x)>1.0e-6 && fabs(data.scaleFactor.y)>1.0e-6) { ne->move(data.insertionPoint + RS_Vector(data.spacing.x/data.scaleFactor.x*c, data.spacing.y/data.scaleFactor.y*r)); } else { ne->move(data.insertionPoint); } // Move because of block base point: // RS_DEBUG->print("RS_Insert::update: move 2"); ne->move(blk->getBasePoint()*-1); // Scale: // RS_DEBUG->print("RS_Insert::update: scale"); ne->scale(data.insertionPoint, data.scaleFactor); // Rotate: // RS_DEBUG->print("RS_Insert::update: rotate"); ne->rotate(data.insertionPoint, data.angle); // Select: ne->setSelected(isSelected()); // individual entities can be on indiv. layers tmpPen = ne->getPen(false); // color from block (free floating): if (tmpPen.getColor()==RS_Color(RS2::FlagByBlock)) { tmpPen.setColor(getPen().getColor()); } // line width from block (free floating): if (tmpPen.getWidth()==RS2::WidthByBlock) { tmpPen.setWidth(getPen().getWidth()); } // line type from block (free floating): if (tmpPen.getLineType()==RS2::LineByBlock) { tmpPen.setLineType(getPen().getLineType()); } // now that we've evaluated all flags, let's strip them: // TODO: strip all flags (width, line type) //tmpPen.setColor(tmpPen.getColor().stripFlags()); ne->setPen(tmpPen); ne->setUpdateEnabled(true); if (data.updateMode!=RS2::PreviewUpdate) { // RS_DEBUG->print("RS_Insert::update: updating new entity"); ne->update(); } // RS_DEBUG->print("RS_Insert::update: adding new entity"); appendEntity(ne); // std::cout<<"done # of entity: "<<i_en_counts<<std::endl; } } } calculateBorders(); RS_DEBUG->print("RS_Insert::update: OK"); }
/*RS_EntityContainer* parent, const RS_LineData& d*/ Plugin_Entity::Plugin_Entity(RS_EntityContainer* parent, enum DPI::ETYPE type){ hasContainer = false; entity = NULL; switch (type) { case DPI::POINT: entity = new RS_Point(parent, RS_PointData(RS_Vector(0,0))); break; case DPI::LINE: entity = new RS_Line(parent, RS_LineData()); break; /* case DPI::CONSTRUCTIONLINE: entity = new RS_ConstructionLine(); break;*/ case DPI::CIRCLE: entity = new RS_Circle(parent, RS_CircleData()); break; case DPI::ARC: entity = new RS_Arc(parent, RS_ArcData()); break; case DPI::ELLIPSE: entity = new RS_Ellipse(parent, RS_EllipseData(RS_Vector(0,0), RS_Vector(0,0),0.0,0.0,0.0,false)); break; case DPI::IMAGE: entity = new RS_Image(parent, RS_ImageData()); break; /* case DPI::OVERLAYBOX: entity = new RS_OverlayBox(); break; case DPI::SOLID: entity = new RS_Solid(); break;*/ case DPI::TEXT: entity = new RS_Text(parent, RS_TextData()); break; /* case DPI::INSERT: entity = new RS_Insert(); break;*/ case DPI::POLYLINE: entity = new RS_Polyline(parent, RS_PolylineData()); break; /* case DPI::SPLINE: entity = new RS_Spline(); break; case DPI::HATCH: entity = new RS_Hatch(); break; case DPI::DIMLEADER: entity = new RS_Leader(); break; case DPI::DIMALIGNED: entity = new RS_DimAligned(); break; case DPI::DIMLINEAR: entity = new RS_DimLinear(); break; case DPI::DIMRADIAL: entity = new RS_DimRadial(); break; case DPI::DIMDIAMETRIC: entity = new RS_DimDiametric(); break; case DPI::DIMANGULAR: entity = new RS_DimAngular(); break;*/ default: break; } }