示例#1
0
QList<RVector> RShape::getIntersectionPointsLT(const RLine& line1,
        const RTriangle& triangle2, bool limited) {

    QList<RVector> res;

    RVector normal = triangle2.getNormal();

    if (normal.getMagnitude() < 1.0e-12) {
        return res;
    }

    if (line1.getLength() < 1.0e-12) {
        return res;
    }

    double t = RVector::getDotProduct(normal, triangle2.getCorner(2) - line1.getStartPoint())
            / RVector::getDotProduct(normal, (line1.getEndPoint() - line1.getStartPoint()));

    // check if intersection point is on the line:
    if (limited && (t < 0.0 || t > 1.0)) {
        return res;
    }

    // intersection point:
    RVector ip = line1.getStartPoint() + (line1.getEndPoint() - line1.getStartPoint()) * t;

    // check if intersection point is inside the triangle:
    if (!limited || triangle2.isPointInTriangle(ip)) {
        res.push_back(ip);
    }

    return res;
}
示例#2
0
void RPainterPathExporter::exportLineSegment(const RLine& line, double angle) {
    if (line.getLength()<RS::PointTolerance) {
        if (exportZeroLinesAsPoints) {
            path.addPoint(line.getStartPoint());
        }
        else {
            // Qt won't export a zero length line as point:
            // e.g. dot in a dash/dot line:
            RVector startPoint = line.startPoint - RVector::createPolar(0.01, angle);
            RVector endPoint = line.endPoint + RVector::createPolar(0.01, angle);
            path.moveTo(startPoint);
            path.lineTo(endPoint);
//            path.moveTo(line.getStartPoint()-RVector(0.01,0));
//            path.lineTo(line.getEndPoint()+RVector(0.01, 0));
//            path.moveTo(line.getStartPoint()-RVector(0,0.01));
//            path.lineTo(line.getEndPoint()+RVector(0, 0.01));
        }
    }
    else {
        if (!path.isAtPosition(line.getStartPoint())) {
            path.moveTo(line.getStartPoint());
        }
        path.lineTo(line.getEndPoint());
    }
}
示例#3
0
void RPainterPathExporter::exportLineSegment(const RLine& line) {
    if (line.getLength()<RS::PointTolerance) {
        path.addPoint(line.getStartPoint());
    }
    else {
        path.moveTo(line.getStartPoint());
        path.lineTo(line.getEndPoint());
    }
}
示例#4
0
RVector RVector::rotate3D(const RLine& axis, double rotation) {
    RVector off = -axis.getStartPoint();
    RVector ret = *this;
    ret.move(off);
    RVector ax = axis.getStartPoint() - axis.getEndPoint();
    QQuaternion quat = QQuaternion::fromAxisAndAngle(ax.x, ax.y, ax.z, RMath::rad2deg(rotation));
    QVector3D qv = quat.rotatedVector(QVector3D(ret.x, ret.y, ret.z));
    ret = RVector(qv.x(), qv.y(), qv.z());
    ret.move(-off);
    *this = ret;
    return *this;
}
示例#5
0
void RSpline::appendToExploded(const RLine& line) const {
    if (line.getLength()<1.0e-6) {
        return;
    }

    if (!exploded.isEmpty()) {
        // compare angle of this sement with last segment and
        // modify last segment if angle is the same (straight line):
        QSharedPointer<RLine> prev = exploded.last().dynamicCast<RLine>();
        if (!prev.isNull()) {
            if (RMath::fuzzyCompare(prev->getAngle(), prev->getStartPoint().getAngleTo(line.getEndPoint()))) {
                prev->setEndPoint(line.getEndPoint());
                return;
            }
        }
    }

    exploded.append(QSharedPointer<RShape>(new RLine(line)));
}
示例#6
0
QList<RVector> RShape::getIntersectionPointsLE(const RLine& line1,
        const REllipse& ellipse2, bool limited) {

    QList<RVector> res;

    // find out if line1 is (almost) a tangent:
    QList<RLine> tangents = ellipse2.getTangents(line1.getMiddlePoint());
    for (int i=0; i<tangents.length(); i++) {
        double a = tangents[i].getAngle();
        double ad1 = fabs(RMath::getAngleDifference180(a, line1.getDirection1()));
        double ad2 = fabs(RMath::getAngleDifference180(a, line1.getDirection2()));

        if (ad1 < 1.0e-2 || ad2 < 1.0e-2) {
            res.append(tangents[i].getEndPoint());

            // no need to continue: max. one tangent possible:
            return res;
        }
    }

    // rotate into normal position:
    double ang = ellipse2.getAngle();

    double rx = ellipse2.getMajorRadius();
    double ry = ellipse2.getMinorRadius();
    RVector center = ellipse2.getCenter();
    RVector a1 = line1.getStartPoint();
    a1.rotate(-ang, center);
    RVector a2 = line1.getEndPoint();
    a2.rotate(-ang, center);
    RVector origin = a1;
    RVector dir = a2-a1;
    RVector diff = origin - center;
    RVector mDir = RVector(dir.x/(rx*rx), dir.y/(ry*ry));
    RVector mDiff = RVector(diff.x/(rx*rx), diff.y/(ry*ry));

    double a = RVector::getDotProduct(dir, mDir);
    double b = RVector::getDotProduct(dir, mDiff);
    double c = RVector::getDotProduct(diff, mDiff) - 1.0;
    double d = b*b - a*c;

    RVector res1 = RVector::invalid;
    RVector res2 = RVector::invalid;

    if (d < 0) {
        // no solution
    } else if ( d > 0 ) {
        double root = sqrt(d);
        double t_a = (-b - root) / a;
        double t_b = (-b + root) / a;

        res1 = a1.getLerp(a2, t_a).rotate(ang, center);
        res2 = a1.getLerp(a2, t_b).rotate(ang, center);
    } else {
        double t = -b/a;
        if ( 0 <= t && t <= 1 ) {
            // one solution:
            res1 = a1.getLerp(a2, t).rotate(ang, center);
        } else {
            // no solution
        }
    }

    if (res1.isValid()) {
        if (!limited || (line1.isOnShape(res1) && ellipse2.isOnShape(res1))) {
            res.append(res1);
        }
    }
    if (res2.isValid()) {
        if (!limited || (line1.isOnShape(res2) && ellipse2.isOnShape(res2))) {
            res.append(res2);
        }
    }

    return res;
}
示例#7
0
QList<RVector> RShape::getIntersectionPointsLC(const RLine& line1,
        const RCircle& circle2, bool limited) {
    QList<RVector> res;

    RVector vLineCenter = line1.getVectorTo(circle2.getCenter(), false);
    double dist = vLineCenter.getMagnitude();

    // special case: arc touches line (tangent):
    if (fabs(dist - circle2.getRadius()) < 1.0e-4) {
        res.append(circle2.getCenter() - vLineCenter);
        // ret.setTangent(true);
        return res;
    }

    RVector p = line1.getStartPoint();
    RVector d = line1.getEndPoint() - line1.getStartPoint();
    if (d.getMagnitude() < 1.0e-6) {
        return res;
    }

    RVector delta = p - circle2.getCenter();

    // root term:
    double term = RMath::pow(RVector::getDotProduct(d, delta), 2.0)
                  - RMath::pow(d.getMagnitude(), 2.0)
                  * (RMath::pow(delta.getMagnitude(), 2.0) - RMath::pow(circle2.getRadius(), 2.0));

    // no intersection:
    if (term<0.0) {
        return res;
    }

    // one or two intersections:
    double t1 = (- RVector::getDotProduct(d, delta) + sqrt(term))
                / RMath::pow(d.getMagnitude(), 2.0);
    double t2;
    bool tangent = false;

    // only one intersection:
    if (fabs(term) < RS::PointTolerance) {
        t2 = t1;
        tangent = true;
    }

    // two intersections
    else {
        t2 = (-RVector::getDotProduct(d, delta) - sqrt(term))
             / RMath::pow(d.getMagnitude(), 2.0);
    }

    RVector sol1;
    RVector sol2 = RVector::invalid;

    sol1 = p + d * t1;

    if (!tangent) {
        sol2 = p + d * t2;
    }

    if (!limited || line1.isOnShape(sol1)) {
        res.append(sol1);
    }
    if (sol2.isValid()) {
        if (!limited || line1.isOnShape(sol2)) {
            res.append(sol2);
        }
    }
    // ret.setTangent(tangent);

    return res;
}
示例#8
0
RXLine::RXLine(const RLine& line) :
    basePoint(line.getStartPoint()), directionVector(line.getEndPoint()-line.getStartPoint()) {
}