📄 rs_creation.cpp
字号:
/****************************************************************************** $Id: rs_creation.cpp 1938 2004-12-09 23:09:53Z andrew $**** Copyright (C) 2001-2003 RibbonSoft. All rights reserved.**** This file is part of the qcadlib Library project.**** This file may be distributed and/or modified under the terms of the** GNU General Public License version 2 as published by the Free Software** Foundation and appearing in the file LICENSE.GPL included in the** packaging of this file.**** Licensees holding valid qcadlib Professional Edition licenses may use ** this file in accordance with the qcadlib Commercial License** Agreement provided with the Software.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.**** See http://www.ribbonsoft.com for further details.**** Contact info@ribbonsoft.com if any conditions of this licensing are** not clear to you.************************************************************************/#include "rs_creation.h"#include "rs_information.h"#include "rs_fileinfo.h"#include "rs_graphic.h"#include "rs_constructionline.h"#include "rs_graphicview.h"#include "rs_modification.h"/** * Default constructor. * * @param container The container to which we will add * entities. Usually that's an RS_Graphic entity but * it can also be a polyline, text, ... */RS_Creation::RS_Creation(RS_EntityContainer* container, RS_GraphicView* graphicView, bool handleUndo) { this->container = container; this->graphicView = graphicView; this->handleUndo = handleUndo; if (container!=NULL) { graphic = container->getGraphic(); document = container->getDocument(); } else { graphic = NULL; document = NULL; }}/** * Creates a point entity. * * E.g.:<br> * <code> * creation.createPoint(RS_Vector(10.0, 15.0)); * </code> * * @param p position *//*void RS_Creation::createPoint(const RS_Vector& p) { entityContainer->addEntity(new RS_Point(entityContainer, p));}*//** * Creates a line with two points given. * * E.g.:<br> * <code> * creation.createLine2P(RS_Vector(10.0, 10.0), RS_Vector(100.0, 200.0)); * </code> * * @param p1 start point * @param p2 end point *//*void RS_Creation::createLine2P(const RS_Vector& p1, const RS_Vector& p2) { entityContainer->addEntity(new RS_Line(entityContainer, RS_LineData(p1, p2)));}*//** * Creates a rectangle with two edge points given. * * E.g.:<br> * <code> * creation.createRectangle(RS_Vector(5.0, 2.0), RS_Vector(7.5, 3.0)); * </code> * * @param p1 edge one * @param p2 edge two *//*void RS_Creation::createRectangle(const RS_Vector& e1, const RS_Vector& e2) { RS_Vector e21(e2.x, e1.y); RS_Vector e12(e1.x, e2.y); entityContainer->addEntity(new RS_Line(entityContainer, RS_LineData(e1, e12))); entityContainer->addEntity(new RS_Line(entityContainer, RS_LineData(e12, e2))); entityContainer->addEntity(new RS_Line(entityContainer, RS_LineData(e2, e21))); entityContainer->addEntity(new RS_Line(entityContainer, RS_LineData(e21, e1)));}*//** * Creates a polyline from the given array of entities. * No checking if the entities actually fit together. * Currently this is like a group. * * E.g.:<br> * <code> * RS_Polyline *pl = creation.createPolyline(RS_Vector(25.0, 55.0));<br> * pl->addVertex(RS_Vector(50.0, 75.0));<br> * </code> * * @param entities array of entities * @param startPoint Start point of the polyline *//*RS_Polyline* RS_Creation::createPolyline(const RS_Vector& startPoint) { RS_Polyline* pl = new RS_Polyline(entityContainer, RS_PolylineData(startPoint, RS_Vector(0.0,0.0), 0)); entityContainer->addEntity(pl); return pl;}*//** * Creates an entity parallel to the given entity e through the given * 'coord'. * * @param coord Coordinate to define the distance / side (typically a * mouse coordinate). * @param number Number of parallels. * @param e Original entity. * * @return Pointer to the first created parallel or NULL if no * parallel has been created. */RS_Entity* RS_Creation::createParallelThrough(const RS_Vector& coord, int number, RS_Entity* e) { if (e==NULL) { return NULL; } double dist; if (e->rtti()==RS2::EntityLine) { RS_Line* l = (RS_Line*)e; RS_ConstructionLine cl(NULL, RS_ConstructionLineData(l->getStartpoint(), l->getEndpoint())); dist = cl.getDistanceToPoint(coord); } else { dist = e->getDistanceToPoint(coord); } if (dist<RS_MAXDOUBLE) { return createParallel(coord, dist, number, e); } else { return NULL; }}/** * Creates an entity parallel to the given entity e. * Out of the 2 possible parallels, the one closest to * the given coordinate is returned. * Lines, Arcs and Circles can have parallels. * * @param coord Coordinate to define which parallel we want (typically a * mouse coordinate). * @param distance Distance of the parallel. * @param number Number of parallels. * @param e Original entity. * * @return Pointer to the first created parallel or NULL if no * parallel has been created. */RS_Entity* RS_Creation::createParallel(const RS_Vector& coord, double distance, int number, RS_Entity* e) { if (e==NULL) { return NULL; } switch (e->rtti()) { case RS2::EntityLine: return createParallelLine(coord, distance, number, (RS_Line*)e); break; case RS2::EntityArc: return createParallelArc(coord, distance, number, (RS_Arc*)e); break; case RS2::EntityCircle: return createParallelCircle(coord, distance, number, (RS_Circle*)e); break; default: break; } return NULL;}/** * Creates a line parallel to the given line e. * Out of the 2 possible parallels, the one closest to * the given coordinate is returned. * * @param coord Coordinate to define which parallel we want (typically a * mouse coordinate). * @param distance Distance of the parallel. * @param number Number of parallels. * @param e Original entity. * * @return Pointer to the first created parallel or NULL if no * parallel has been created. */RS_Line* RS_Creation::createParallelLine(const RS_Vector& coord, double distance, int number, RS_Line* e) { if (e==NULL) { return NULL; } double ang = e->getAngle1() + M_PI/2.0; RS_Vector p1, p2; RS_LineData parallelData; RS_Line* ret = NULL; if (document!=NULL && handleUndo) { document->startUndoCycle(); } for (int num=1; num<=number; ++num) { // calculate 1st parallel: p1.setPolar(distance*num, ang); p1 += e->getStartpoint(); p2.setPolar(distance*num, ang); p2 += e->getEndpoint(); RS_Line parallel1(NULL, RS_LineData(p1, p2)); // calculate 2nd parallel: p1.setPolar(distance*num, ang+M_PI); p1 += e->getStartpoint(); p2.setPolar(distance*num, ang+M_PI); p2 += e->getEndpoint(); RS_Line parallel2(NULL, RS_LineData(p1, p2)); double dist1 = parallel1.getDistanceToPoint(coord); double dist2 = parallel2.getDistanceToPoint(coord); double minDist = std::min(dist1, dist2); if (minDist<RS_MAXDOUBLE) { if (dist1<dist2) { parallelData = parallel1.getData(); } else { parallelData = parallel2.getData(); } RS_Line* newLine = new RS_Line(container, parallelData); newLine->setLayerToActive(); newLine->setPenToActive(); if (ret==NULL) { ret = newLine; } if (container!=NULL) { container->addEntity(newLine); } if (document!=NULL && handleUndo) { document->addUndoable(newLine); //document->endUndoCycle(); } if (graphicView!=NULL) { graphicView->drawEntity(newLine); } } } if (document!=NULL && handleUndo) { document->endUndoCycle(); } return ret;}/** * Creates a arc parallel to the given arc e. * Out of the 2 possible parallels, the one closest to * the given coordinate is returned. * * @param coord Coordinate to define which parallel we want (typically a * mouse coordinate). * @param distance Distance of the parallel. * @param number Number of parallels. * @param e Original entity. * * @return Pointer to the first created parallel or NULL if no * parallel has been created. */RS_Arc* RS_Creation::createParallelArc(const RS_Vector& coord, double distance, int number, RS_Arc* e) { if (e==NULL) { return NULL; } RS_ArcData parallelData; RS_Arc* ret = NULL; bool inside = (e->getCenter().distanceTo(coord) < e->getRadius()); if (inside) { distance *= -1; } for (int num=1; num<=number; ++num) { // calculate parallel: bool ok = true; RS_Arc parallel1(NULL, e->getData()); parallel1.setRadius(e->getRadius() + distance*num); if (parallel1.getRadius()<0.0) { parallel1.setRadius(RS_MAXDOUBLE); ok = false; } // calculate 2nd parallel: //RS_Arc parallel2(NULL, e->getData()); //parallel2.setRadius(e->getRadius()+distance*num); //double dist1 = parallel1.getDistanceToPoint(coord); //double dist2 = parallel2.getDistanceToPoint(coord); //double minDist = min(dist1, dist2); //if (minDist<RS_MAXDOUBLE) { if (ok==true) { //if (dist1<dist2) { parallelData = parallel1.getData(); //} else { // parallelData = parallel2.getData(); //} if (document!=NULL && handleUndo) { document->startUndoCycle(); } RS_Arc* newArc = new RS_Arc(container, parallelData); newArc->setLayerToActive(); newArc->setPenToActive(); if (ret==NULL) { ret = newArc; } if (container!=NULL) { container->addEntity(newArc); } if (document!=NULL && handleUndo) { document->addUndoable(newArc); document->endUndoCycle(); } if (graphicView!=NULL) { graphicView->drawEntity(newArc); } } } return ret;}/** * Creates a circle parallel to the given circle e. * Out of the 2 possible parallels, the one closest to * the given coordinate is returned. * * @param coord Coordinate to define which parallel we want (typically a * mouse coordinate). * @param distance Distance of the parallel. * @param number Number of parallels. * @param e Original entity. * * @return Pointer to the first created parallel or NULL if no * parallel has been created. */RS_Circle* RS_Creation::createParallelCircle(const RS_Vector& coord, double distance, int number, RS_Circle* e) { if (e==NULL) { return NULL; } RS_CircleData parallelData; RS_Circle* ret = NULL; bool inside = (e->getCenter().distanceTo(coord) < e->getRadius());
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -