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

📄 rs_information.cpp

📁 qcad2.05可用于windows和linux的源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/****************************************************************************** $Id: rs_information.cpp 2378 2005-05-16 17:05:15Z 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_information.h"#include "rs_constructionline.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_Information::RS_Information(RS_EntityContainer& container) {    this->container = &container;}/** * @return true: if the entity is a dimensioning enity. *         false: otherwise */bool RS_Information::isDimension(RS2::EntityType type) {    if (type==RS2::EntityDimAligned ||            type==RS2::EntityDimLinear ||            type==RS2::EntityDimRadial ||            type==RS2::EntityDimDiametric ||            type==RS2::EntityDimAngular) {        return true;    } else {        return false;    }}/** * @retval true the entity can be trimmed. * i.e. it is in a graphic or in a polyline. */bool RS_Information::isTrimmable(RS_Entity* e) {	if (e!=NULL) {		if (e->getParent()!=NULL) {			if (e->getParent()->rtti()==RS2::EntityPolyline) {				return true;			}			else if (e->getParent()->rtti()==RS2::EntityContainer ||			          e->getParent()->rtti()==RS2::EntityGraphic ||					  e->getParent()->rtti()==RS2::EntityBlock) {				// normal entity:				return true;			}		}	}	return false;}/** * @retval true the two entities can be trimmed to each other; * i.e. they are in a graphic or in the same polyline. */bool RS_Information::isTrimmable(RS_Entity* e1, RS_Entity* e2) {	if (e1!=NULL && e2!=NULL) {		if (e1->getParent()!=NULL && e2->getParent()!=NULL) {			if (e1->getParent()->rtti()==RS2::EntityPolyline &&			   e2->getParent()->rtti()==RS2::EntityPolyline &&			   e1->getParent()==e2->getParent()) {				// in the same polyline				RS_EntityContainer* pl = e1->getParent();				int idx1 = pl->findEntity(e1);				int idx2 = pl->findEntity(e2);				RS_DEBUG->print("RS_Information::isTrimmable: "					"idx1: %d, idx2: %d", idx1, idx2);				if (abs(idx1-idx2)==1 || abs(idx1-idx2)==pl->count()-1) {					// directly following entities					return true;				}				else {					// not directly following entities					return false;				}			}			else if ((e1->getParent()->rtti()==RS2::EntityContainer ||			          e1->getParent()->rtti()==RS2::EntityGraphic ||					  e1->getParent()->rtti()==RS2::EntityBlock) &&					 (e2->getParent()->rtti()==RS2::EntityContainer ||			          e2->getParent()->rtti()==RS2::EntityGraphic ||					  e2->getParent()->rtti()==RS2::EntityBlock)) {				// normal entities:				return true;			}		}		else {			// independent entities with the same parent:			return (e1->getParent()==e2->getParent());		}	}	return false;}/** * Gets the nearest end point to the given coordinate. * * @param coord Coordinate (typically a mouse coordinate) * * @return the coordinate found or an invalid vector * if there are no elements at all in this graphics  * container. */RS_Vector RS_Information::getNearestEndpoint(const RS_Vector& coord,        double* dist) const {    return container->getNearestEndpoint(coord, dist);}/** * Gets the nearest point to the given coordinate which is on an entity.  * * @param coord Coordinate (typically a mouse coordinate) * @param dist Pointer to a double which will contain the  *        measured distance after return or NULL * @param entity Pointer to a pointer which will point to the *        entity on which the point is or NULL * * @return the coordinate found or an invalid vector * if there are no elements at all in this graphics  * container. */RS_Vector RS_Information::getNearestPointOnEntity(const RS_Vector& coord,        bool onEntity,        double* dist,        RS_Entity** entity) const {    return container->getNearestPointOnEntity(coord, onEntity, dist, entity);}/** * Gets the nearest entity to the given coordinate. * * @param coord Coordinate (typically a mouse coordinate) * @param dist Pointer to a double which will contain the  *             masured distance after return * @param level Level of resolving entities. * * @return the entity found or NULL if there are no elements  * at all in this graphics container. */RS_Entity* RS_Information::getNearestEntity(const RS_Vector& coord,        double* dist,        RS2::ResolveLevel level) const {    return container->getNearestEntity(coord, dist, level);}/** * 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;}/** * @return Intersection between two lines. */RS_VectorSolutions RS_Information::getIntersectionLineLine(RS_Line* e1,        RS_Line* e2) {    RS_VectorSolutions ret;    if (e1==NULL || e2==NULL) {        return ret;    }    RS_Vector p1 = e1->getStartpoint();    RS_Vector p2 = e1->getEndpoint();    RS_Vector p3 = e2->getStartpoint();    RS_Vector p4 = e2->getEndpoint();    double num = ((p4.x-p3.x)*(p1.y-p3.y) - (p4.y-p3.y)*(p1.x-p3.x));    double div = ((p4.y-p3.y)*(p2.x-p1.x) - (p4.x-p3.x)*(p2.y-p1.y));    if (fabs(div)>RS_TOLERANCE) {        double u = num / div;        double xs = p1.x + u * (p2.x-p1.x);        double ys = p1.y + u * (p2.y-p1.y);        ret = RS_VectorSolutions(RS_Vector(xs, ys));    }    // lines are parallel    else {        ret = RS_VectorSolutions();    }    return ret;}/** * @return One or two intersection points between given entities.

⌨️ 快捷键说明

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