⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rs_polyline.cpp

📁 qcad2.05可用于windows和linux的源码
💻 CPP
字号:
/****************************************************************************** $Id: rs_polyline.cpp 1959 2005-03-08 14:09:02Z js $**** 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_polyline.h"#include "rs_debug.h"#include "rs_line.h"#include "rs_arc.h"#include "rs_graphicview.h"/** * Constructor. */RS_Polyline::RS_Polyline(RS_EntityContainer* parent)        :RS_EntityContainer(parent) {    closingEntity = NULL;    nextBulge = 0.0;}/** * Constructor. * @param d Polyline data */RS_Polyline::RS_Polyline(RS_EntityContainer* parent,                         const RS_PolylineData& d)        :RS_EntityContainer(parent), data(d) {    closingEntity = NULL;    nextBulge = 0.0;    calculateBorders();}/** * Destructor  */RS_Polyline::~RS_Polyline() {}/** * Removes the last vertex of this polyline. */void RS_Polyline::removeLastVertex() {	RS_Entity* last = lastEntity();	if (last!=NULL) {		removeEntity(last);		last = lastEntity();		if (last!=NULL) {			if (last->isAtomic()) {				data.endpoint = ((RS_AtomicEntity*)last)->getEndpoint();			}			else {				RS_DEBUG->print(RS_Debug::D_WARNING, 					"RS_Polyline::removeLastVertex: "				 	"polyline contains non-atomic entity");			}		}	}}/** * Adds a vertex from the endpoint of the last segment or * from the startpoint of the first segment to 'v' or * sets the startpoint to the point 'v'. * * The very first vertex added with this method is the startpoint. *  * @param v vertex coordinate to be added * @param bulge The bulge of the arc or 0 for a line segment (see DXF documentation) * @param prepend true: prepend at start instead of append at end * * @return Pointer to the entity that was addded or NULL if this *         was the first vertex added. */RS_Entity* RS_Polyline::addVertex(const RS_Vector& v, double bulge, bool prepend) {    RS_Entity* entity=NULL;    //static double nextBulge = 0.0;    // very first vertex:    if (!data.startpoint.valid) {        data.startpoint = data.endpoint = v;        nextBulge = bulge;    }    // consequent vertices:    else {        // add entity to the polyline:        entity = createVertex(v, nextBulge, prepend);        if (entity!=NULL) {			if (prepend==false) {            	RS_EntityContainer::addEntity(entity);				data.endpoint = v;			}			else {            	RS_EntityContainer::insertEntity(0, entity);				data.startpoint = v;			}        }        nextBulge = bulge;    	endPolyline();    }    //data.endpoint = v;    return entity;}/** * Creates a vertex from the endpoint of the last element or  * sets the startpoint to the point 'v'. * * The very first vertex added is the starting point. *  * @param v vertex coordinate * @param bulge The bulge of the arc (see DXF documentation) * @param prepend true: Prepend instead of append at end * * @return Pointer to the entity that was created or NULL if this *         was the first vertex added. */RS_Entity* RS_Polyline::createVertex(const RS_Vector& v, double bulge, bool prepend) {    RS_Entity* entity=NULL;    RS_DEBUG->print("RS_Polyline::createVertex: %f/%f to %f/%f bulge: %f",                    data.endpoint.x, data.endpoint.y, v.x, v.y, bulge);    // create line for the polyline:    if (fabs(bulge)<RS_TOLERANCE) {		if (prepend==false) {        	entity = new RS_Line(this, RS_LineData(data.endpoint, v));		}		else {        	entity = new RS_Line(this, RS_LineData(v, data.startpoint));		}        entity->setSelected(isSelected());        entity->setPen(RS_Pen(RS2::FlagInvalid));        entity->setLayer(NULL);        //RS_EntityContainer::addEntity(entity);        //data.endpoint = v;    }    // create arc for the polyline:    else {        bool reversed = (bulge<0.0);        double alpha = atan(bulge)*4.0;        double radius;        RS_Vector center;        RS_Vector middle;        double dist;        double angle;		if (prepend==false) {	        middle = (data.endpoint+v)/2.0;    	    dist = data.endpoint.distanceTo(v)/2.0;        	angle = data.endpoint.angleTo(v);		}		else {	        middle = (data.startpoint+v)/2.0;    	    dist = data.startpoint.distanceTo(v)/2.0;        	angle = v.angleTo(data.startpoint);		}        // alpha can't be 0.0 at this point        radius = fabs(dist / sin(alpha/2.0));        double wu = fabs(RS_Math::pow(radius, 2.0) - RS_Math::pow(dist, 2.0));        double h = sqrt(wu);        if (bulge>0.0) {            angle+=M_PI/2.0;        } else {            angle-=M_PI/2.0;        }        if (fabs(alpha)>M_PI) {            h*=-1.0;        }        center.setPolar(h, angle);        center+=middle;		double a1;		double a2;		if (prepend==false) {			a1 = center.angleTo(data.endpoint);			a2 = center.angleTo(v);		}		else {			a1 = center.angleTo(v);			a2 = center.angleTo(data.startpoint);		}        RS_ArcData d(center, radius,                     a1, a2,                     reversed);        entity = new RS_Arc(this, d);        entity->setSelected(isSelected());        entity->setPen(RS_Pen(RS2::FlagInvalid));        entity->setLayer(NULL);    }    return entity;}/** * Ends polyline and adds the last entity if the polyline is closed */void RS_Polyline::endPolyline() {	RS_DEBUG->print("RS_Polyline::endPolyline");    if (isClosed()) {		RS_DEBUG->print("RS_Polyline::endPolyline: adding closing entity");		        // remove old closing entity:        if (closingEntity!=NULL) {            removeEntity(closingEntity);        }        // add closing entity to the polyline:        closingEntity = createVertex(data.startpoint, nextBulge);        if (closingEntity!=NULL) {            RS_EntityContainer::addEntity(closingEntity);            //data.endpoint = data.startpoint;        }    }}		/** * @return The bulge of the closing entity. */double RS_Polyline::getClosingBulge() {    if (isClosed()) {		RS_Entity* e = lastEntity();		if (e!=NULL && e->rtti()==RS2::EntityArc) {			return ((RS_Arc*)e)->getBulge();		}	}	return 0.0;}/** * Sets the polylines start and endpoint to match the first and last vertex. */void RS_Polyline::updateEndpoints() {	RS_Entity* e1 = firstEntity();	if (e1!=NULL && e1->isAtomic()) {		RS_Vector v = ((RS_AtomicEntity*)e1)->getStartpoint();		setStartpoint(v);	}		RS_Entity* e2 = lastEntity();	if (isClosed()) {		e2 = prevEntity();	}	if (e2!=NULL && e2->isAtomic()) {		RS_Vector v = ((RS_AtomicEntity*)e2)->getEndpoint();		setEndpoint(v);	}}/** * Reimplementation of the addEntity method for a normal container. * This reimplementation deletes the given entity! * * To add entities use addVertex() or addSegment() instead. */void RS_Polyline::addEntity(RS_Entity* entity) {    RS_DEBUG->print(RS_Debug::D_WARNING, "RS_Polyline::addEntity:"                    " should never be called");    if (entity==NULL) {        return;    }    delete entity;}/** * Adds a segment to the polyline. *//*void RS_Polyline::addSegment(RS_Entity* entity) {	RS_EntityContainer::addEntity(entity);	// TODO: reorder and check polyline}*/RS_VectorSolutions RS_Polyline::getRefPoints() {    RS_VectorSolutions ret(count()+1);    int i=0;    ret.set(0, data.startpoint);	i++;    	for (RS_Entity* e=firstEntity(RS2::ResolveNone);            e!=NULL;            e = nextEntity(RS2::ResolveNone), i++) {		if (e->isAtomic()) {        	ret.set(i, ((RS_AtomicEntity*)e)->getEndpoint());		}    }    	ret.set(count(), data.endpoint);    return ret;}RS_Vector RS_Polyline::getNearestRef(const RS_Vector& coord,                                   double* dist) {    return RS_Entity::getNearestRef(coord, dist);}RS_Vector RS_Polyline::getNearestSelectedRef(const RS_Vector& coord,        double* dist) {    return RS_Entity::getNearestSelectedRef(coord, dist);}/*void RS_Polyline::reorder() {	// current point:	RS_Vector cp;	bool done = false;	do {			} while(!done);}*/void RS_Polyline::move(RS_Vector offset) {    RS_EntityContainer::move(offset);    data.startpoint.move(offset);    data.endpoint.move(offset);}void RS_Polyline::rotate(RS_Vector center, double angle) {    RS_EntityContainer::rotate(center, angle);    data.startpoint.rotate(center, angle);    data.endpoint.rotate(center, angle);}void RS_Polyline::scale(RS_Vector center, RS_Vector factor) {    RS_EntityContainer::scale(center, factor);    data.startpoint.scale(center, factor);    data.endpoint.scale(center, factor);}void RS_Polyline::mirror(RS_Vector axisPoint1, RS_Vector axisPoint2) {    RS_EntityContainer::mirror(axisPoint1, axisPoint2);    data.startpoint.mirror(axisPoint1, axisPoint2);    data.endpoint.mirror(axisPoint1, axisPoint2);}void RS_Polyline::moveRef(const RS_Vector& ref, const RS_Vector& offset) {	RS_EntityContainer::moveRef(ref, offset);    if (ref.distanceTo(data.startpoint)<1.0e-4) {       data.startpoint.move(offset);    }    if (ref.distanceTo(data.endpoint)<1.0e-4) {       data.endpoint.move(offset);    }    //update();}void RS_Polyline::stretch(RS_Vector firstCorner,                                 RS_Vector secondCorner,                                 RS_Vector offset) {    if (data.startpoint.isInWindow(firstCorner, secondCorner)) {        data.startpoint.move(offset);    }     if (data.endpoint.isInWindow(firstCorner, secondCorner)) {        data.endpoint.move(offset);    } 		RS_EntityContainer::stretch(firstCorner, secondCorner, offset);}/** * Slightly optimized drawing for polylines. */void RS_Polyline::draw(RS_Painter* painter, RS_GraphicView* view, 	double /*patternOffset*/) {    if (painter==NULL || view==NULL) {        return;    }		// draw first entity and set correct pen:    RS_Entity* e = firstEntity(RS2::ResolveNone);    view->drawEntity(e);	// draw subsequent entities with same pen:    for (RS_Entity* e=nextEntity(RS2::ResolveNone);            e!=NULL;            e = nextEntity(RS2::ResolveNone)) {        view->drawEntityPlain(e);    }}/** * Dumps the point's data to stdout. */std::ostream& operator << (std::ostream& os, const RS_Polyline& l) {    os << " Polyline: " << l.getData() << " {\n";    os << (RS_EntityContainer&)l;    os << "\n}\n";    return os;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -