Пример #1
0
/**
 * Creates an arc from 3 points.
 */
RArc RArc::createFrom3Points(const RVector& startPoint,
                              const RVector& point,
                              const RVector& endPoint) {
    // intersection of two middle lines

    // middle points between first two points:
    RVector mp1 = RVector::getAverage(startPoint, point);
    double a1 = startPoint.getAngleTo(point) + M_PI / 2.0;
    // direction from middle point to center:
    RVector dir1 = RVector::createPolar(1.0, a1);

    // middle points between last two points:
    RVector mp2 = RVector::getAverage(point, endPoint);
    double a2 = point.getAngleTo(endPoint) + M_PI / 2.0;
    // direction from middle point to center:
    RVector dir2 = RVector::createPolar(1.0, a2);

    RLine midLine1(mp1, mp1 + dir1);
    RLine midLine2(mp2, mp2 + dir2);

    QList<RVector> ips = midLine1.getIntersectionPoints(midLine2, false);
    if (ips.length()!=1) {
        //this.error = qsTr("No arc possible");
        return RArc();
    }

    RVector center = ips[0];
    double radius = center.getDistanceTo(endPoint);
    double angle1 = center.getAngleTo(startPoint);
    double angle2 = center.getAngleTo(endPoint);
    bool reversed = RMath::isAngleBetween(center.getAngleTo(point),
                                            angle1, angle2, true);

    return RArc(center, radius, angle1, angle2, reversed);
}
Пример #2
0
RCircle RCircle::createFrom3Points(const RVector& p1,
                                  const RVector& p2,
                                  const RVector& p3) {
    // intersection of two middle lines

    // middle points between first two points:
    RVector mp1 = RVector::getAverage(p1, p2);
    double a1 = p1.getAngleTo(p2) + M_PI / 2.0;
    // direction from middle point to center:
    RVector dir1 = RVector::createPolar(1.0, a1);

    // middle points between last two points:
    RVector mp2 = RVector::getAverage(p2, p3);
    double a2 = p2.getAngleTo(p3) + M_PI / 2.0;
    // direction from middle point to center:
    RVector dir2 = RVector::createPolar(1.0, a2);

    RLine midLine1(mp1, mp1 + dir1);
    RLine midLine2(mp2, mp2 + dir2);

    QList<RVector> ips = midLine1.getIntersectionPoints(midLine2, false);
    if (ips.length()!=1) {
        return RCircle();
    }

    RVector center = ips[0];
    double radius = center.getDistanceTo(p3);
//    double angle1 = center.getAngleTo(p1);
//    double angle2 = center.getAngleTo(p3);
//    bool reversed = RMath::isAngleBetween(center.getAngleTo(p2),
//                                            angle1, angle2, true);

    return RCircle(center, radius);
}
Пример #3
0
void REllipse::moveEndPoint(const RVector& pos, bool changeAngleOnly) {
    if (changeAngleOnly) {
        endParam = getParamTo(pos);
    }
    else {
        RVector sp = getStartPoint();
        double distOri = sp.getDistanceTo(getEndPoint());
        double angleOri = sp.getAngleTo(getEndPoint());
        if (distOri<RS::PointTolerance) {
            return;
        }

        double distNew = sp.getDistanceTo(pos);
        double angleNew = sp.getAngleTo(pos);
        double factor = distNew / distOri;
        if (factor<RS::PointTolerance) {
            return;
        }
        double angleDelta = angleNew - angleOri;

        center.scale(factor, sp);
        center.rotate(angleDelta, sp);
        majorPoint.scale(factor);
        majorPoint.rotate(angleDelta);
    }
}
Пример #4
0
/**
 * Creates an arc from its startpoint, endpoint and bulge (= tan(angle/4)).
 */
RArc RArc::createFrom2PBulge(const RVector& startPoint,
        const RVector& endPoint, double bulge) {

    RArc arc;

    arc.reversed = (bulge < 0.0);
    double alpha = atan(bulge) * 4.0;

    RVector middle = (startPoint + endPoint) / 2.0;
    double dist = startPoint.getDistanceTo(endPoint) / 2.0;

    // alpha can't be 0.0 at this point
    arc.radius = fabs(dist / sin(alpha / 2.0));

    double wu = fabs(RMath::pow(arc.radius, 2.0) - RMath::pow(dist, 2.0));
    double h = sqrt(wu);
    double angle = startPoint.getAngleTo(endPoint);

    if (bulge > 0.0) {
        angle += M_PI / 2.0;
    } else {
        angle -= M_PI / 2.0;
    }

    if (fabs(alpha) > M_PI) {
        h *= -1.0;
    }

    arc.center.setPolar(h, angle);
    arc.center += middle;
    arc.startAngle = arc.center.getAngleTo(startPoint);
    arc.endAngle = arc.center.getAngleTo(endPoint);

    return arc;
}
Пример #5
0
/**
 * \return Shape of segment at given position.
 */
QSharedPointer<RShape> RPolyline::getSegmentAt(int i) const {
    if (i<0 || i>=vertices.size() || i>=bulges.size()) {
        qWarning() << "RPolyline::getSegmentAt(" << i << "): i out of range";
        return QSharedPointer<RShape>();
    }

    RVector p1 = vertices.at(i);
    RVector p2 = vertices.at((i+1) % vertices.size());

    if (RPolyline::isStraight(bulges.at(i))) {
        return QSharedPointer<RShape>(new RLine(p1, p2));
    }

    else {
        double bulge = bulges.at(i);
        bool reversed = bulge<0.0;
        double alpha = atan(bulge)*4.0;

        if (fabs(alpha) > 2*M_PI-RS::AngleTolerance) {
            return QSharedPointer<RShape>();
        }

        double radius;
        RVector center;
        RVector middle;
        double dist;
        double angle;

        middle = (p1+p2)/2.0;
        dist = p1.getDistanceTo(p2)/2.0;
        angle = p1.getAngleTo(p2);

        // alpha can't be 0.0 at this point
        radius = fabs(dist / sin(alpha/2.0));

        double rootTerm = fabs(radius*radius - dist*dist);
        double h = sqrt(rootTerm);

        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;

        a1 = center.getAngleTo(p1);
        a2 = center.getAngleTo(p2);

        return QSharedPointer<RShape>(new RArc(center, radius, a1, a2, reversed));
    }
}
Пример #6
0
bool RDimDiametricData::moveReferencePoint(const RVector& referencePoint,
        const RVector& targetPoint) {

    bool ret = false;

    if (referencePoint.equalsFuzzy(chordPoint)) {
        RVector c = (definitionPoint + chordPoint)/2.0;
        double d = c.getDistanceTo(chordPoint);
        double a = c.getAngleTo(targetPoint);

        RVector v = RVector::createPolar(d, a);
        chordPoint = c + v;
        definitionPoint = c - v;

        autoTextPos = true;
        ret = true;
    }
    else if (referencePoint.equalsFuzzy(definitionPoint)) {
        RVector c = (definitionPoint + chordPoint)/2.0;
        double d = c.getDistanceTo(definitionPoint);
        double a = c.getAngleTo(targetPoint);

        RVector v = RVector::createPolar(d, a);
        definitionPoint = c + v;
        chordPoint = c - v;

        autoTextPos = true;
        ret = true;
    }

    if (!ret) {
        ret = RDimensionData::moveReferencePoint(referencePoint, targetPoint);
    }

    if (ret) {
        update();
    }

    return ret;
}
Пример #7
0
/**
 * Finds out which angles this dimension actually measures.
 *
 * \param ang1 Reference will return the start angle
 * \param ang2 Reference will return the end angle
 * \param reversed Reference will return the reversed flag.
 *
 * \return true: on success
 */
bool RDimAngularData::getAngles(double& ang1, double& ang2, bool& reversed,
                              RVector& p1, RVector& p2) const {

    RVector center = getCenter();
    double ang = center.getAngleTo(dimArcPosition);
    bool done = false;

    // find out the angles this dimension refers to:
    for (int f1=0; f1<=1 && !done; ++f1) {
        ang1 = RMath::getNormalizedAngle(extensionLine1End.getAngleTo(extensionLine1Start) + f1*M_PI);
        if (f1==0) {
            p1 = extensionLine1Start;
        } else {
            p1 = extensionLine1End;
        }
        for (int f2=0; f2<=1 && !done; ++f2) {
            ang2 = RMath::getNormalizedAngle(extensionLine2Start.getAngleTo(definitionPoint) + f2*M_PI);
            if (f2==0) {
                p2 = definitionPoint;
            } else {
                p2 = extensionLine2Start;
            }
            for (int t=0; t<=1 && !done; ++t) {
                reversed = (bool)t;

                double angDiff;

                if (!reversed) {
                    if (ang2<ang1) {
                        ang2+=2*M_PI;
                    }
                    angDiff = ang2-ang1;
                } else {
                    if (ang1<ang2) {
                        ang1+=2*M_PI;
                    }
                    angDiff = ang1-ang2;
                }

                ang1 = RMath::getNormalizedAngle(ang1);
                ang2 = RMath::getNormalizedAngle(ang2);

                if (RMath::isAngleBetween(ang, ang1, ang2, reversed) && angDiff<=M_PI) {
                    done = true;
                    break;
                }
            }
        }
    }

    return done;
}
Пример #8
0
void RDimAlignedData::recomputeDefinitionPoint(
    const RVector& oldExtPoint1, const RVector& oldExtPoint2,
    const RVector& newExtPoint1, const RVector& newExtPoint2) {

    RLine dLine(oldExtPoint1, oldExtPoint2);
    double d = dLine.getDistanceTo(definitionPoint, false);
    RS::Side s = dLine.getSideOfPoint(definitionPoint);

    double a = newExtPoint1.getAngleTo(newExtPoint2);
    if (s==RS::LeftHand) {
        a+=M_PI/2.0;
    }
    else {
        a-=M_PI/2.0;
    }
    RVector v = RVector::createPolar(d, a);
    RVector dp = newExtPoint1 + v;
    if (dp.isValid()) {
        definitionPoint = dp;
    }
}
Пример #9
0
/**
 * \todo Not working as expected, fix or disable
 */
QSharedPointer<RShape> RArc::getTransformed(const QTransform& transform) const {
    RVector ct = center.getTransformed2d(transform);
    RVector sp = getStartPoint();
    RVector spt = sp.getTransformed2d(transform);
    RVector ep = getEndPoint();
    RVector ept = ep.getTransformed2d(transform);
    //RVector mp = getMiddlePoint();
    //RVector mpt = mp.getTransformed2d(transform);

    RArc* ret = new RArc(
            ct,
            ct.getDistanceTo(spt),
            ct.getAngleTo(spt),
            ct.getAngleTo(ept),
            reversed
        );

//    if (!ret->getMiddlePoint().equalsFuzzy(mpt)) {
//        ret->setReversed(!reversed);
//    }

    return QSharedPointer<RShape>(ret);
}
Пример #10
0
QList<QSharedPointer<RShape> > RDimAngularData::getShapes(const RBox& queryBox, bool ignoreComplex, bool segment) const {
    Q_UNUSED(queryBox)
    Q_UNUSED(ignoreComplex)
    Q_UNUSED(segment)

    QSharedPointer<RBlockReferenceEntity> dimBlockReference = getDimensionBlockReference();
    if (!dimBlockReference.isNull()) {
        return dimBlockReference->getShapes(queryBox, ignoreComplex);
    }

    QList<QSharedPointer<RShape> > ret;

    double dimexo = getDimexo();
    double dimexe = getDimexe();
    double dimtxt = getDimtxt();
    double dimgap = getDimgap();
    double dimasz = getDimasz();

    // find out center:
    RVector center = getCenter();

    if (!center.isValid()) {
        return ret;
    }

    double ang1 = 0.0;
    double ang2 = 0.0;
    bool reversed = false;
    RVector p1;
    RVector p2;

    getAngles(ang1, ang2, reversed, p1, p2);

    double rad = dimArcPosition.getDistanceTo(center);

    RLine line;
    RVector dir;
    double len;
    double dist;

    // 1st extension line:
    dist = center.getDistanceTo2D(p1);
    len = rad - dist + dimexe;
    dir.setPolar(1.0, ang1);
    line = RLine(center + dir*dist + dir*dimexo, center + dir*dist + dir*len);
    ret.append(QSharedPointer<RShape>(new RLine(line)));

    // 2nd extension line:
    dist = center.getDistanceTo2D(p2);
    len = rad - dist + dimexe;
    dir.setPolar(1.0, ang2);
    line = RLine(center + dir*dist + dir*dimexo, center + dir*dist + dir*len);
    ret.append(QSharedPointer<RShape>(new RLine(line)));

    // Create dimension line (arc):
    RArc arc(center, rad, ang1, ang2, reversed);
    ret.append(QSharedPointer<RShape>(new RArc(arc)));

    // length of dimension arc:
    double distance = arc.getLength();

    // do we have to put the arrows outside of the arc?
    bool outsideArrows = (distance<dimasz*2);

    // arrow angles:
    double arrowAngle1, arrowAngle2;
    double arrowAng;
    if (rad>1.0e-6) {
        arrowAng = getDimasz() / rad;
    }
    else {
        arrowAng = 0.0;
    }

    if (outsideArrows) {
        arrowAngle1 = arc.getDirection1();
        arrowAngle2 = arc.getDirection2();
    }
    else {
        RVector v1, v2;
        if (!arc.isReversed()) {
            v1.setPolar(rad, arc.getStartAngle()+arrowAng);
        } else {
            v1.setPolar(rad, arc.getStartAngle()-arrowAng);
        }
        v1+=arc.getCenter();
        arrowAngle1 = arc.getStartPoint().getAngleTo(v1);


        if (!arc.isReversed()) {
            v2.setPolar(rad, arc.getEndAngle()-arrowAng);
        } else {
            v2.setPolar(rad, arc.getEndAngle()+arrowAng);
        }
        v2+=arc.getCenter();
        arrowAngle2 = arc.getEndPoint().getAngleTo(v2);

        arrowAngle1 = arrowAngle1+M_PI;
        arrowAngle2 = arrowAngle2+M_PI;
    }

    // Arrows:
    //RTriangle arrow = RTriangle::createArrow(arc.getStartPoint(), arrowAngle1, dimasz);
    QList<QSharedPointer<RShape> > arrow = getArrow(arc.getStartPoint(), arrowAngle1);
    ret.append(arrow);
    //arrow = RTriangle::createArrow(arc.getEndPoint(), arrowAngle2, dimasz);
    arrow = getArrow(arc.getEndPoint(), arrowAngle2);
    ret.append(arrow);
    //ret.append(QSharedPointer<RShape>(new RTriangle(arrow)));

    //RVector oldMot = textPosition;
    //textPosition = RVector(0,0);
    //defaultAngle = 0.0;
    //dimLineLength = RNANDOUBLE;
    //getTextData();
    //textPosition = oldMot;

    RVector textPos = arc.getMiddlePoint();
    double dimAngle1 = textPos.getAngleTo(arc.getCenter())-M_PI/2.0;
    if (!autoTextPos) {
        dimAngle1 = textPositionCenter.getAngleTo(arc.getCenter())-M_PI/2.0;
    }

    RVector distV;
    double textAngle;
    // rotate text so it's readable from the bottom or right (ISO)
    // quadrant 1 & 4
    if (dimAngle1>M_PI/2.0*3.0+0.001 ||
        dimAngle1<M_PI/2.0+0.001) {

        distV.setPolar(dimgap + dimtxt/2, dimAngle1+M_PI/2.0);
        textAngle = dimAngle1;
    }
    // quadrant 2 & 3
    else {
        distV.setPolar(dimgap + dimtxt/2, dimAngle1-M_PI/2.0);
        textAngle = dimAngle1+M_PI;
    }

    if (!autoTextPos) {
        textPos = textPositionCenter;
    } else {
        // move text away from dimension line:
        textPos+=distV;

        textPositionCenter = textPos;
    }
    defaultAngle = textAngle;
    //getTextData();
    //textData.rotate(textAngle, RVector(0,0));
    //textData.move(textPos);

    return ret;
}
Пример #11
0
void REventHandler::drawSnapLabel(QPainter* painter, const RVector& pos, const RVector& posRestriction, const QString& text) {
    RVector p = graphicsView->mapToView(pos);
    RVector pr = RVector::invalid;
    if (posRestriction.isValid()) {
        pr = graphicsView->mapToView(posRestriction);
    }
    RColor color = RSettings::getColor("GraphicsViewColors/TextLabelColor", RColor(249,198,31));
    painter->setPen(color);

    QFont font = RSettings::getSnapLabelFont();
    font.setPointSizeF(font.pointSizeF()*graphicsView->getDevicePixelRatio());
    QFontMetrics fm(font);
    painter->setFont(font);

    int offset = 5 * graphicsView->getDevicePixelRatio();

    if (!text.isEmpty()) {
        painter->drawText(
            p.x + offset, p.y + offset,
            fm.width(text)+10, fm.height()+10,
            Qt::AlignHCenter | Qt::AlignVCenter,
            text, NULL);
    }

    painter->drawEllipse(p.x-offset, p.y-offset, offset*2, offset*2);

    // restriction position:
    if (pr.isSane()) {
        painter->drawLine(pr.x, pr.y-offset, pr.x+offset, pr.y);
        painter->drawLine(pr.x+offset, pr.y, pr.x, pr.y+offset);
        painter->drawLine(pr.x, pr.y+offset, pr.x-offset, pr.y);
        painter->drawLine(pr.x-offset, pr.y, pr.x, pr.y-offset);
    }

    // display distance/angle:
    int display = RSettings::getIntValue("DisplaySettings/DisplayDistanceAngle", 0);
    if (display == 0) {
        return;
    }

    RDocumentInterface* di = graphicsView->getDocumentInterface();
    RDocument* doc = graphicsView->getDocument();

    RVector relativeZero = di->getRelativeZero();

    double dist, angle;
    if (posRestriction.isSane()) {
        dist = relativeZero.getDistanceTo(posRestriction);
        angle = relativeZero.getAngleTo(posRestriction);
    } else {
        dist = relativeZero.getDistanceTo(pos);
        angle = relativeZero.getAngleTo(pos);
    }

    int lp = doc->getLinearPrecision();
    QString distStr = RUnit::doubleToString(dist, lp);

    angle = RMath::rad2deg(angle);
    int ap = doc->getAnglePrecision();
    QString angStr = RUnit::doubleToString(angle, ap);

    QString sep = RSettings::getStringValue("Input/PolarCoordinateSeparator", "<");

    color = RSettings::getColor("GraphicsViewColors/MeasurementToolsColor", RColor(155,220,112));
    painter->setPen(color);
    QString displayText;
    switch (display) {
    case 0:
        displayText = "";
        break;
    case 1:
        displayText = distStr + sep + angStr + QChar(0x00b0);
        break;
    case 2:
        displayText = distStr;
        break;
    case 3:
        displayText = angStr + QChar(0x00b0);
        break;
    default:
        displayText = "";
    }

    if (!displayText.isEmpty()) {
        painter->drawText(
                    p.x + offset, p.y - 3*offset - fm.height(),
                    fm.width(displayText)+10, fm.height()+10,
                    Qt::AlignHCenter | Qt::AlignVCenter,
                    displayText, NULL);
    }
}