Exemple #1
0
bool MgArc::_setHandlePoint(int index, const Point2d& pt, float)
{
    if (index == 1) {
        return setStartMidEnd(pt, getMidPoint(), getEndPoint());
    }
    if (index == 2) {
        return setStartMidEnd(getStartPoint(), getMidPoint(), pt);
    }
    if (index == 3) {
        return setStartMidEnd(getStartPoint(), pt, getEndPoint());
    }
    if (index == 4) {
        float a = (pt - getCenter()).angle2();
        return setCenterRadius(getCenter(), getRadius(), a, getEndAngle() - a);
    }
    if (index == 5) {
        float a = (pt - getCenter()).angle2();
        return setCenterRadius(getCenter(), getRadius(), getStartAngle(), a - getStartAngle());
    }
    if (index == 6) {
        return setTanStartEnd(pt - getStartPoint(), getStartPoint(), getEndPoint());
    }
    if (index == 7) {
        return (setTanStartEnd(getEndPoint() - pt, getEndPoint(), getStartPoint())
            && _reverse());
    }
    return setCenterStartEnd(pt, getStartPoint(), getEndPoint());
}
Exemple #2
0
QList<RVector> RArc::getPointsWithDistanceToEnd(double distance, RS::From from) const {
    QList<RVector> ret;

    if (radius<RS::PointTolerance) {
        return ret;
    }

    double a1;
    double a2;
    RVector p;
    double aDist = distance / radius;

    if (isReversed()) {
        a1 = getStartAngle() - aDist;
        a2 = getEndAngle() + aDist;
    } else {
        a1 = getStartAngle() + aDist;
        a2 = getEndAngle() - aDist;
    }

    if (from==RS::FromStart || from==RS::FromAny) {
        p.setPolar(radius, a1);
        p += center;
        ret.append(p);
    }

    if (from==RS::FromEnd || from==RS::FromAny) {
        p.setPolar(radius, a2);
        p += center;
        ret.append(p);
    }

    return ret;
}
Exemple #3
0
void MgArc::_update()
{
    Point2d points[16];
    int n = mgAngleArcToBezier(points, getCenter(), getRadius(), 0, getStartAngle(), getSweepAngle());

    mgBeziersBox(_extent, n, points);
}
Exemple #4
0
float MgArc::_hitTest(const Point2d& pt, float tol, MgHitResult& res) const
{
    Point2d points[16];
    int n = mgcurv::arcToBezier(points, getCenter(), getRadius(), 0, getStartAngle(), getSweepAngle());

    float dist, distMin = _FLT_MAX;
    Point2d ptTemp;

    if (_subtype > 0) {
        dist = mglnrel::ptToLine(getCenter(), getStartPoint(), pt, ptTemp);
        if (dist <= tol && dist < distMin) {
            distMin = dist;
            res.nearpt = ptTemp;
        }
        dist = mglnrel::ptToLine(getCenter(), getEndPoint(), pt, ptTemp);
        if (dist <= tol && dist < distMin) {
            distMin = dist;
            res.nearpt = ptTemp;
        }
    }
    for (int i = 0; i + 3 < n; i += 3) {
        mgnear::nearestOnBezier(pt, points + i, ptTemp);
        dist = pt.distanceTo(ptTemp);
        if (dist <= tol && dist < distMin) {
            distMin = dist;
            res.nearpt = ptTemp;
        }
    }
    
    return distMin;
}
Exemple #5
0
void Arc::draw(MyWindow* win) const {
    for(int r = getRadius(); r > endRadius; r--) {
        for(float theta = getStartAngle(); theta <= getEndAngle(); theta += 0.001) {
            win->putPixel(getCenter().getX()  + r*cos(theta), getCenter().getY() + r*(-sin(theta)), getColor().r, getColor().g, getColor().b);
            //setPixel(discContainer, (center.getX() + r*cos(theta)), (center.getY() + r*(-sin(theta))), color);
        }
    }
}
Exemple #6
0
void RArcEntity::print(QDebug dbg) const {
    dbg.nospace() << "RArcEntity(";
    REntity::print(dbg);
    dbg.nospace() << ", center: " << getCenter();
    dbg.nospace() << ", radius: " << getRadius();
    dbg.nospace() << ", startAngle: " << RMath::rad2deg(getStartAngle());
    dbg.nospace() << ", endAngle: " << RMath::rad2deg(getEndAngle());
    dbg.nospace() << ", reversed: " << isReversed() << ")";
}
Exemple #7
0
float MgArc::getSweepAngle() const
{
    if (!mgIsZero(_sweepAngle)) {
        return _sweepAngle;
    }
    
    const float midAngle = (getMidPoint() - getCenter()).angle2();
    const float startAngle = getStartAngle();
    const float endAngle = getEndAngle();

    if (mgEquals(midAngle, startAngle) && mgEquals(startAngle, endAngle)) {
        return endAngle - startAngle;
    }
    
    Tol tol(getRadius() * 1e-3f, 1e-4f);
    if (getStartPoint().isEqualTo(getEndPoint(), tol)
        && (getMidPoint() + (getStartPoint() + getEndPoint()) / 2).isEqualTo(2 * getCenter(), tol)) {
        return _M_2PI;
    }

    float startAngle2 = startAngle;
    float midAngle2 = midAngle;
    float endAngle2 = endAngle;

    // 先尝试看是否为逆时针方向:endAngle2 > midAngle2 > startAngle2 >= 0
    if (startAngle2 < 0)
        startAngle2 += _M_2PI;
    while (midAngle2 < startAngle2)
        midAngle2 += _M_2PI;
    while (endAngle2 < midAngle2)
        endAngle2 += _M_2PI;

    if (fabsf(startAngle2 + endAngle2 - 2 * midAngle2) < _M_PI_6
        && endAngle2 - startAngle2 < _M_2PI) {
        return endAngle2 - startAngle2;
    }

    // 再尝试看是否为顺时针方向:endAngle2 < midAngle2 < startAngle2 <= 0
    startAngle2 = startAngle;
    midAngle2 = midAngle;
    endAngle2 = endAngle;
    if (startAngle2 > 0)
        startAngle2 -= _M_2PI;
    while (midAngle2 > startAngle2)
        midAngle2 -= _M_2PI;
    while (endAngle2 > midAngle2)
        endAngle2 -= _M_2PI;

    if (fabsf(startAngle2 + endAngle2 - 2 * midAngle2) < _M_PI_6) {
        if (endAngle2 - startAngle2 > -_M_2PI)
            return endAngle2 - startAngle2;
        return mgbase::toRange(endAngle2 - startAngle2, -_M_2PI, 0);
    }

    return endAngle - startAngle;   // error
}
Exemple #8
0
bool MgArc::_hitTestBox(const Box2d& rect) const
{
    if (!getExtent().isIntersect(rect))
        return false;

    Point2d points[16];
    int n = mgAngleArcToBezier(points, getCenter(), getRadius(), 0, getStartAngle(), getSweepAngle());
    
    return mgBeziersIntersectBox(rect, n, points);
}
Exemple #9
0
double RArc::getDistanceFromStart(const RVector& p) const {
    double a1 = getStartAngle();
    double ap = center.getAngleTo(p);
    if (reversed) {
        return RMath::getAngleDifference(ap, a1) * radius;
    }
    else {
        return RMath::getAngleDifference(a1, ap) * radius;
    }
}
Exemple #10
0
bool MgArc::_hitTestBox(const Box2d& rect) const
{
    if (!getExtent().isIntersect(rect))
        return false;

    Point2d points[16];
    int n = mgcurv::arcToBezier(points, getCenter(), getRadius(), 0, getStartAngle(), getSweepAngle());
    
    return rect.contains(getCenter()) || mgnear::beziersIntersectBox(rect, n, points);
}
Exemple #11
0
void REllipseEntity::print(QDebug dbg) const {
    dbg.nospace() << "REllipseEntity(";
    REntity::print(dbg);
    dbg.nospace() << ", center: " << getCenter();
    dbg.nospace() << ", majorPoint: " << getMajorPoint();
    dbg.nospace() << ", ratio: " << getRatio();
    dbg.nospace() << ", startAngle: " << getStartAngle();
    dbg.nospace() << ", endAngle: " << getEndAngle();
    dbg.nospace() << ", reversed: " << isReversed() << ")";
}
Exemple #12
0
void MgArc::_update()
{
    Point2d points[16];
    int n = mgcurv::arcToBezier(points, getCenter(), getRadius(), 0, getStartAngle(), getSweepAngle());

    mgnear::beziersBox(_extent, n, points);
    if (_subtype > 0) {
        _extent.unionWith(getCenter());
    }
    __super::_update();
}
Exemple #13
0
bool MgArc::_draw(int mode, GiGraphics& gs, const GiContext& ctx, int segment) const
{
    bool ret = gs.drawArc(&ctx, getCenter(), getRadius(), 0, getStartAngle(), getSweepAngle());
    if (mode > 0) {
        GiContext ctxln(0, GiColor(0, 126, 0, 64), kGiLineDashDot);
        gs.drawLine(&ctxln, getCenter(), getStartPoint());
        gs.drawLine(&ctxln, getCenter(), getEndPoint());
        gs.drawLine(&ctxln, getStartPoint(), getStartPoint() + getStartTangent());
        gs.drawLine(&ctxln, getEndPoint(), getEndPoint() + getEndTangent());
    }
    return __super::_draw(mode, gs, ctx, segment) || ret;
}
Exemple #14
0
void RArc::print(QDebug dbg) const {
    dbg.nospace() << "RArc(";
    RShape::print(dbg);
    dbg.nospace() << ", center: " << getCenter()
                  << ", radius: " << getRadius()
                  << ", startAngle: " << getStartAngle()
                  << ", endAngle: " << getEndAngle()
                  << ", startPoint: " << getStartPoint()
                  << ", endPoint: " << getEndPoint()
                  << ", reversed: " << isReversed()
                  << ")";
}
Exemple #15
0
// Draw function
void OcclusionArc::drawFunc()
{
   BEGIN_DLIST
   GLUquadricObj* qobj = gluNewQuadric();
   if (isFilled()) {
      gluQuadricDrawStyle(qobj, GLU_FILL);
   }
   else {
      gluQuadricDrawStyle(qobj, GLU_SILHOUETTE);
   }

   gluPartialDisk(qobj, getRadius(), outerRadius, getSlices(), 2, getStartAngle(), getArcLength());

   gluDeleteQuadric(qobj);
   END_DLIST
}
Exemple #16
0
float MgArc::getSweepAngle() const
{
    const float midAngle = (getMidPoint() - getCenter()).angle2();
    const float startAngle = getStartAngle();
    const float endAngle = getEndAngle();

    if (mgEquals(midAngle, startAngle) && mgEquals(startAngle, endAngle)) {
        return endAngle - startAngle;
    }

    float startAngle2 = startAngle;
    float midAngle2 = midAngle;
    float endAngle2 = endAngle;

    // 先尝试看是否为逆时针方向:endAngle2 > midAngle2 > startAngle2 >= 0
    if (startAngle2 < 0)
        startAngle2 += _M_2PI;
    while (midAngle2 < startAngle2)
        midAngle2 += _M_2PI;
    while (endAngle2 < midAngle2)
        endAngle2 += _M_2PI;

    if (fabsf(startAngle2 + endAngle2 - 2 * midAngle2) < _M_PI_6
        && endAngle2 - startAngle2 < _M_2PI) {
        return endAngle2 - startAngle2;
    }

    // 再尝试看是否为顺时针方向:endAngle2 < midAngle2 < startAngle2 <= 0
    startAngle2 = startAngle;
    midAngle2 = midAngle;
    endAngle2 = endAngle;
    if (startAngle2 > 0)
        startAngle2 -= _M_2PI;
    while (midAngle2 > startAngle2)
        midAngle2 -= _M_2PI;
    while (endAngle2 > midAngle2)
        endAngle2 -= _M_2PI;

    if (fabsf(startAngle2 + endAngle2 - 2 * midAngle2) < _M_PI_6) {
        if (endAngle2 - startAngle2 > -_M_2PI)
            return endAngle2 - startAngle2;
        return mgToRange(endAngle2 - startAngle2, -_M_2PI, 0);
    }

    return endAngle - startAngle;   // error
}
Exemple #17
0
float MgArc::_hitTest(const Point2d& pt, float tol, 
                      Point2d& nearpt, int&) const
{
    Point2d points[16];
    int n = mgAngleArcToBezier(points, getCenter(), getRadius(), 0, getStartAngle(), getSweepAngle());

    float distMin = _FLT_MAX;
    Point2d ptTemp;

    for (int i = 0; i + 3 < n; i += 3) {
        mgNearestOnBezier(pt, points + i, ptTemp);
        float dist = pt.distanceTo(ptTemp);
        if (dist <= tol && dist < distMin) {
            distMin = dist;
            nearpt = ptTemp;
        }
    }
    
    return distMin;
}
Exemple #18
0
void MgArc::_output(MgPath& path) const
{
    float r = getRadius();
    float sweepAngle = getSweepAngle();
    Point2d points[16];
    
    if (r < _MGZERO || fabsf(sweepAngle) < _MGZERO)
        return;
    
    int count = mgcurv::arcToBezier(points, getCenter(), r, r,
                                    getStartAngle(), sweepAngle);
    
    if (_subtype > 0) {
        path.moveTo(getCenter());
        path.lineTo(points[0]);
        path.beziersTo(count - 1, points + 1);
        path.closeFigure();
    } else {
        path.moveTo(points[0]);
        path.beziersTo(count - 1, points + 1);
    }
}
Exemple #19
0
RPolyline RArc::approximateWithLines(double segmentLength) {
    RPolyline polyline;

    // avoid a segment length of 0:
    if (segmentLength<1.0e-6) {
        segmentLength = 1.0e-6;
    }

    double a1 = getStartAngle();
    double a2 = getEndAngle();
    double aStep = segmentLength / radius;
    double a, cix, ciy;

    polyline.appendVertex(getStartPoint());
    if (!reversed) {
        // Arc Counterclockwise:
        if (a1>a2-1.0e-10) {
            a2+=2*M_PI;
        }
        for (a=a1+aStep; a<=a2; a+=aStep) {
            cix = center.x + cos(a) * radius;
            ciy = center.y + sin(a) * radius;
            polyline.appendVertex(RVector(cix, ciy));
        }
    } else {
        // Arc Clockwise:
        if (a1<a2+1.0e-10) {
            a2-=2*M_PI;
        }
        for (a=a1-aStep; a>=a2; a-=aStep) {
            cix = center.x + cos(a) * radius;
            ciy = center.y + sin(a) * radius;
            polyline.appendVertex(RVector(cix, ciy));
        }
    }
    polyline.appendVertex(getEndPoint());

    return polyline;
}
Exemple #20
0
bool MgArc::_setHandlePoint2(int index, const Point2d& pt, float, int& data)
{
    static float lastSweepAngle;
    
    if (index == 1 || index == 2) {     // 起点、终点
        return setCenterRadius(getCenter(), pt.distanceTo(getCenter()), getStartAngle(), getSweepAngle());
    }
    if (index == 3) {                   // 弧线中点
        return setStartMidEnd(getStartPoint(), pt, getEndPoint());
    }
    if (index == 4) {                   // 改变起始角度
        if (data == 0) {
            lastSweepAngle = getSweepAngle();
            data++;
        }
        Point2d startPt(getCenter().polarPoint((pt - getCenter()).angle2(), getRadius()));
        bool ret = setCSE(getCenter(), startPt, getEndPoint(), lastSweepAngle);
        lastSweepAngle = getSweepAngle();
        return ret;
    }
    if (index == 5) {                   // 改变终止角度
        if (data == 0) {
            lastSweepAngle = getSweepAngle();
            data++;
        }
        Point2d endPt(getCenter().polarPoint((pt - getCenter()).angle2(), getRadius()));
        bool ret = setCSE(getCenter(), getStartPoint(), endPt, lastSweepAngle);
        lastSweepAngle = getSweepAngle();
        return ret;
    }
    if (index == 6) {
        return setTanStartEnd(pt - getStartPoint(), getStartPoint(), getEndPoint());
    }
    if (index == 7) {
        return (setTanStartEnd(getEndPoint() - pt, getEndPoint(), getStartPoint())
            && _reverse());
    }
    return offset(pt - getCenter(), -1);
}
Exemple #21
0
//------------------------------------------------------------------------------
// drawFunc() -- draws the object(s)
//------------------------------------------------------------------------------
void DialArcSegment::drawFunc()
{
    // get our data from our base class
    double startAngle = getStartAngle();
    double radius = getRadius();
    double sweepAngle = getSweepAngle();

    GLint curSlices = getSlices();
    // our slice amount should go up as we get more of a sweep, if not, it will
    // look funny.  Pretty much one slice per degree sweep
    double y = std::fabs(static_cast<double>(sweepAngle));
    curSlices = curSlices + static_cast<GLint>(y * 0.05f);

    // draw our arc
    glPushMatrix();
        GLUquadric* qobj = gluNewQuadric();
        if (filled) gluQuadricDrawStyle(qobj, GL_FILL);
        else gluQuadricDrawStyle(qobj, GLU_SILHOUETTE);
        gluPartialDisk(qobj, radius, outerRadius, curSlices, 1, startAngle, sweepAngle);
        gluDeleteQuadric(qobj);
    glPopMatrix();
}
Exemple #22
0
//------------------------------------------------------------------------------
// drawFunc() -- draws the object(s)
//------------------------------------------------------------------------------
void DialTickMarks::drawFunc()
{
    GLfloat currentColor[4];
    glGetFloatv(GL_CURRENT_COLOR, currentColor);

    // get our data from our baseclass (AnalogDial)
    double sweepAngle = getSweepAngle();
    double startAngle = getStartAngle();
    double tRadius = getRadius();

    // figure our rotation angle per tick mark (deg)
    double rotation = sweepAngle/quantity;

    glPushMatrix();
        // rotate to our start angle
        glRotatef(static_cast<GLfloat>(-startAngle), 0, 0, 1);
        for (int i = 0; i < quantity + 1; i++) {
            // if we have a graphic, draw that, else we draw a line
            if (myGraphic == nullptr) {
                glBegin(GL_LINES);
                    lcVertex2(0, tRadius);
                    lcVertex2(0, tRadius - length);
                glEnd();
            }
            else {
                myGraphic->lcSaveMatrix();
                    myGraphic->lcTranslate(0, tRadius);
                    myGraphic->draw();
                myGraphic->lcRestoreMatrix();
            }
            glRotatef(static_cast<GLfloat>(-rotation), 0, 0, 1);
        }
    glPopMatrix();

    glColor4fv(currentColor);
}