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

📄 rs_creation.cpp

📁 qcad2.05可用于windows和linux的源码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
    if (inside) {        distance *= -1;    }    for (int num=1; num<=number; ++num) {        // calculate parallel:        bool ok = true;        RS_Circle 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_Circle 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_Circle* newCircle = new RS_Circle(container, parallelData);            newCircle->setLayerToActive();            newCircle->setPenToActive();            if (ret==NULL) {                ret = newCircle;            }            if (container!=NULL) {                container->addEntity(newCircle);            }            if (document!=NULL && handleUndo) {                document->addUndoable(newCircle);                document->endUndoCycle();            }            if (graphicView!=NULL) {                graphicView->drawEntity(newCircle);            }        }    }    return ret;}/** * Creates a bisecting line of the angle between the entities  * e1 and e2. Out of the 4 possible bisectors, the one closest to * the given coordinate is returned. * * @param coord Coordinate to define which bisector we want (typically a  *              mouse coordinate). * @param length Length of the bisecting line. * @param num Number of bisectors * @param l1 First line. * @param l2 Second line. * * @return Pointer to the first bisector created or NULL if no bisectors *   were created. */RS_Line* RS_Creation::createBisector(const RS_Vector& coord1,                                     const RS_Vector& coord2,                                     double length,                                     int num,                                     RS_Line* l1,                                     RS_Line* l2) {    RS_VectorSolutions sol;    // check given entities:    if (l1==NULL || l2==NULL ||            l1->rtti()!=RS2::EntityLine || l2->rtti()!=RS2::EntityLine) {        return NULL;    }    // intersection between entities:    sol = RS_Information::getIntersection(l1, l2, false);    RS_Vector inters = sol.get(0);    if (inters.valid==false) {        return NULL;    }    double angle1 = inters.angleTo(l1->getNearestPointOnEntity(coord1));    double angle2 = inters.angleTo(l2->getNearestPointOnEntity(coord2));    double angleDiff = RS_Math::getAngleDifference(angle1, angle2);    if (angleDiff>M_PI) {        angleDiff = angleDiff - 2*M_PI;    }    RS_Line* ret = NULL;    if (document!=NULL && handleUndo) {        document->startUndoCycle();    }    for (int n=1; n<=num; ++n) {        double angle = angle1 +                       (angleDiff / (num+1) * n);        RS_LineData d;        RS_Vector v;        RS_Vector c;        v.setPolar(length, angle);        d = RS_LineData(inters, inters + v);        RS_Line* newLine = new RS_Line(container, d);        if (container!=NULL) {            newLine->setLayerToActive();            newLine->setPenToActive();            container->addEntity(newLine);        }        if (document!=NULL && handleUndo) {            document->addUndoable(newLine);        }        if (graphicView!=NULL) {            graphicView->drawEntity(newLine);        }        if (ret==NULL) {            ret = newLine;        }    }    if (document!=NULL && handleUndo) {        document->endUndoCycle();    }    return ret;}/** * Creates a tangent between a given point and a circle or arc. * Out of the 2 possible tangents, the one closest to * the given coordinate is returned. * * @param coord Coordinate to define which tangent we want (typically a  *              mouse coordinate). * @param point Point. * @param circle Circle, arc or ellipse entity. */RS_Line* RS_Creation::createTangent1(const RS_Vector& coord,                                     const RS_Vector& point,                                     RS_Entity* circle) {    RS_Line* ret = NULL;    RS_Vector circleCenter;    // check given entities:    if (circle==NULL || !point.valid ||            (circle->rtti()!=RS2::EntityArc && circle->rtti()!=RS2::EntityCircle             && circle->rtti()!=RS2::EntityEllipse)) {        return NULL;    }    if (circle->rtti()==RS2::EntityCircle) {        circleCenter = ((RS_Circle*)circle)->getCenter();    } else if (circle->rtti()==RS2::EntityArc) {        circleCenter = ((RS_Arc*)circle)->getCenter();    } else if (circle->rtti()==RS2::EntityEllipse) {        circleCenter = ((RS_Ellipse*)circle)->getCenter();    }    // the two tangent points:    RS_VectorSolutions sol;    // calculate tangent points for arcs / circles:    if (circle->rtti()!=RS2::EntityEllipse) {        // create temp. thales circle:        RS_Vector tCenter = (point + circleCenter)/2.0;        double tRadius = point.distanceTo(tCenter);        RS_Circle tmp(NULL, RS_CircleData(tCenter, tRadius));        // get the two intersection points which are the tangent points:        sol = RS_Information::getIntersection(&tmp, circle, false);    }    // calculate tangent points for ellipses:    else {        RS_Ellipse* el = (RS_Ellipse*)circle;        sol.alloc(2);        //sol.set(0, circleCenter);        //sol.set(1, circleCenter);        double a = el->getMajorRadius();     // the length of the major axis / 2        double b = el->getMinorRadius();     // the length of the minor axis / 2		// rotate and move point:		RS_Vector point2 = point;		point2.move(-el->getCenter());		point2.rotate(-el->getAngle());		        double xp = point2.x;             // coordinates of the given point        double yp = point2.y;		        double xt1;                      // Tangent point 1        double yt1;        double xt2;                      // Tangent point 2        double yt2;        double a2 = a * a;        double b2 = b * b;        double d = a2 / b2 * yp / xp;        double e = a2 / xp;        double af = b2 * d * d + a2;        double bf = -b2 * d * e * 2.0;        double cf = b2 * e * e - a2 * b2;        double t = sqrt(bf * bf - af * cf * 4.0);        yt1 = (t - bf) / (af * 2.0);        xt1 = e - d * yt1;        yt2 = (-t - bf) / (af * 2.0);        xt2 = e - d * yt2;		RS_Vector s1 = RS_Vector(xt1, yt1);		RS_Vector s2 = RS_Vector(xt2, yt2);		s1.rotate(el->getAngle());		s1.move(el->getCenter());			s2.rotate(el->getAngle());		s2.move(el->getCenter());				sol.set(0, s1);		sol.set(1, s2);		    }    if (!sol.get(0).valid || !sol.get(1).valid) {        return NULL;    }    // create all possible tangents:    RS_Line* poss[2];    RS_LineData d;    d = RS_LineData(sol.get(0), point);    poss[0] = new RS_Line(NULL, d);    d = RS_LineData(sol.get(1), point);    poss[1] = new RS_Line(NULL, d);    // find closest tangent:    double minDist = RS_MAXDOUBLE;    double dist;    int idx = -1;    for (int i=0; i<2; ++i) {        dist = poss[i]->getDistanceToPoint(coord);        if (dist<minDist) {            minDist = dist;            idx = i;        }    }    // create the closest tangent:    if (idx!=-1) {        RS_LineData d = poss[idx]->getData();        for (int i=0; i<2; ++i) {            delete poss[i];        }        if (document!=NULL && handleUndo) {            document->startUndoCycle();        }        ret = new RS_Line(container, d);        ret->setLayerToActive();        ret->setPenToActive();        if (container!=NULL) {            container->addEntity(ret);        }        if (document!=NULL && handleUndo) {            document->addUndoable(ret);            document->endUndoCycle();        }        if (graphicView!=NULL) {            graphicView->drawEntity(ret);        }    } else {        ret = NULL;    }    return ret;}/** * Creates a tangent between two circles or arcs. * Out of the 4 possible tangents, the one closest to * the given coordinate is returned. * * @param coord Coordinate to define which tangent we want (typically a  *              mouse coordinate). * @param circle1 1st circle or arc entity. * @param circle2 2nd circle or arc entity. */RS_Line* RS_Creation::createTangent2(const RS_Vector& coord,                                     RS_Entity* circle1,                                     RS_Entity* circle2) {    RS_Line* ret = NULL;    RS_Vector circleCenter1;    RS_Vector circleCenter2;    double circleRadius1 = 0.0;    double circleRadius2 = 0.0;    // check given entities:    if (circle1==NULL || circle2==NULL ||            (circle1->rtti()!=RS2::EntityArc &&             circle1->rtti()!=RS2::EntityCircle) ||            (circle2->rtti()!=RS2::EntityArc &&             circle2->rtti()!=RS2::EntityCircle) ) {        return NULL;    }    if (circle1->rtti()==RS2::EntityCircle) {        circleCenter1 = ((RS_Circle*)circle1)->getCenter();        circleRadius1 = ((RS_Circle*)circle1)->getRadius();    } else if (circle1->rtti()==RS2::EntityArc) {        circleCenter1 = ((RS_Arc*)circle1)->getCenter();        circleRadius1 = ((RS_Arc*)circle1)->getRadius();    }    if (circle2->rtti()==RS2::EntityCircle) {        circleCenter2 = ((RS_Circle*)circle2)->getCenter();        circleRadius2 = ((RS_Circle*)circle2)->getRadius();    } else if (circle2->rtti()==RS2::EntityArc) {        circleCenter2 = ((RS_Arc*)circle2)->getCenter();        circleRadius2 = ((RS_Arc*)circle2)->getRadius();    }    // create all possible tangents:    RS_Line* poss[4];    for (int i=0; i<4; ++i) {        poss[i] = NULL;    }    RS_LineData d;    double angle1 = circleCenter1.angleTo(circleCenter2);    double dist1 = circleCenter1.distanceTo(circleCenter2);    if (dist1>1.0e-6) {        // outer tangents:        double dist2 = circleRadius2 - circleRadius1;        if (dist1>dist2) {            double angle2 = asin(dist2/dist1);            double angt1 = angle1 + angle2 + M_PI/2.0;            double angt2 = angle1 - angle2 - M_PI/2.0;            RS_Vector offs1;            RS_Vector offs2;            offs1.setPolar(circleRadius1, angt1);            offs2.setPolar(circleRadius2, angt1);            d = RS_LineData(circleCenter1 + offs1,                            circleCenter2 + offs2);            poss[0] = new RS_Line(NULL, d);            offs1.setPolar(circleRadius1, angt2);            offs2.setPolar(circleRadius2, angt2);            d = RS_LineData(circleCenter1 + offs1,                            circleCenter2 + offs2);            poss[1] = new RS_Line(NULL, d);        }        // inner tangents:        double dist3 = circleRadius2 + circleRadius1;        if (dist1>dist3) {            double angle3 = asin(dist3/dist1);            double angt3 = angle1 + angle3 + M_PI/2.0;            double angt4 = angle1 - angle3 - M_PI/2.0;            RS_Vector offs1;            RS_Vector offs2;            offs1.setPolar(circleRadius1, angt3);            offs2.setPolar(circleRadius2, angt3);            d = RS_LineData(circleCenter1 - offs1,                            circleCenter2 + offs2);            poss[2] = new RS_Line(NULL, d);            offs1.setPolar(circleRadius1, angt4);            offs2.setPolar(circleRadius2, angt4);            d = RS_LineData(circleCenter1 - offs1,                            circleCenter2 + offs2);            poss[3] = new RS_Line(NULL, d);        }    }    // find closest tangent:    double minDist = RS_MAXDOUBLE;    double dist;    int idx = -1;    for (int i=0; i<4; ++i) {        if (poss[i]!=NULL) {            dist = poss[i]->getDistanceToPoint(coord);            if (dist<minDist) {

⌨️ 快捷键说明

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