Example #1
0
void Constraint::DoEqualLenTicks(Vector a, Vector b, Vector gn) {
    Vector m = (a.ScaledBy(1.0/3)).Plus(b.ScaledBy(2.0/3));
    Vector ab = a.Minus(b);
    Vector n = (gn.Cross(ab)).WithMagnitude(10/SS.GW.scale);

    LineDrawOrGetDistance(m.Minus(n), m.Plus(n));
}
Example #2
0
void ssglFatLine(Vector a, Vector b, double width)
{
    // The half-width of the line we're drawing.
    double hw = width / 2;
    Vector ab  = b.Minus(a);
    Vector gn = (SS.GW.projRight).Cross(SS.GW.projUp);
    Vector abn = (ab.Cross(gn)).WithMagnitude(1);
    abn = abn.Minus(gn.ScaledBy(gn.Dot(abn)));
    // So now abn is normal to the projection of ab into the screen, so the
    // line will always have constant thickness as the view is rotated.

    abn = abn.WithMagnitude(hw);
    ab  = gn.Cross(abn);
    ab  = ab. WithMagnitude(hw);

    // The body of a line is a quad
    glBegin(GL_QUADS);
    ssglVertex3v(a.Minus(abn));
    ssglVertex3v(b.Minus(abn));
    ssglVertex3v(b.Plus (abn));
    ssglVertex3v(a.Plus (abn));
    glEnd();
    // And the line has two semi-circular end caps.
    FatLineEndcap(a, ab,              abn);
    FatLineEndcap(b, ab.ScaledBy(-1), abn);
}
Example #3
0
void SSurface::TangentsAt(double u, double v, Vector *tu, Vector *tv) {
    Vector num   = Vector::From(0, 0, 0),
           num_u = Vector::From(0, 0, 0),
           num_v = Vector::From(0, 0, 0);
    double den   = 0,
           den_u = 0,
           den_v = 0;

    int i, j;
    for(i = 0; i <= degm; i++) {
        for(j = 0; j <= degn; j++) {
            double Bi  = Bernstein(i, degm, u),
                   Bj  = Bernstein(j, degn, v),
                   Bip = BernsteinDerivative(i, degm, u),
                   Bjp = BernsteinDerivative(j, degn, v);

            num = num.Plus(ctrl[i][j].ScaledBy(Bi*Bj*weight[i][j]));
            den += weight[i][j]*Bi*Bj;

            num_u = num_u.Plus(ctrl[i][j].ScaledBy(Bip*Bj*weight[i][j]));
            den_u += weight[i][j]*Bip*Bj;

            num_v = num_v.Plus(ctrl[i][j].ScaledBy(Bi*Bjp*weight[i][j]));
            den_v += weight[i][j]*Bi*Bjp;
        }
    }
    // quotient rule; f(t) = n(t)/d(t), so f' = (n'*d - n*d')/(d^2)
    *tu = ((num_u.ScaledBy(den)).Minus(num.ScaledBy(den_u)));
    *tu = tu->ScaledBy(1.0/(den*den));

    *tv = ((num_v.ScaledBy(den)).Minus(num.ScaledBy(den_v)));
    *tv = tv->ScaledBy(1.0/(den*den));
}
Example #4
0
bool Vector::BoundingBoxIntersectsLine(Vector amax, Vector amin,
                                       Vector p0, Vector p1, bool segment)
{
    Vector dp = p1.Minus(p0);
    double lp = dp.Magnitude();
    dp = dp.ScaledBy(1.0/lp);

    int i, a;
    for(i = 0; i < 3; i++) {
        int j = WRAP(i+1, 3), k = WRAP(i+2, 3);
        if(lp*fabs(dp.Element(i)) < LENGTH_EPS) continue; // parallel to plane

        for(a = 0; a < 2; a++) {
            double d = (a == 0) ? amax.Element(i) : amin.Element(i);
            // n dot (p0 + t*dp) = d
            // (n dot p0) + t * (n dot dp) = d
            double t = (d - p0.Element(i)) / dp.Element(i);
            Vector p = p0.Plus(dp.ScaledBy(t));

            if(segment && (t < -LENGTH_EPS || t > (lp+LENGTH_EPS))) continue;

            if(p.Element(j) > amax.Element(j) + LENGTH_EPS) continue;
            if(p.Element(k) > amax.Element(k) + LENGTH_EPS) continue;

            if(p.Element(j) < amin.Element(j) - LENGTH_EPS) continue;
            if(p.Element(k) < amin.Element(k) - LENGTH_EPS) continue;

            return true;
        }
    }

    return false;
}
Example #5
0
Vector SBsp2::IntersectionWith(Vector a, Vector b) {
    double da = a.Dot(no) - d;
    double db = b.Dot(no) - d;
    if(da*db > 0) oops();

    double dab = (db - da);
    return (a.ScaledBy(db/dab)).Plus(b.ScaledBy(-da/dab));
}
Example #6
0
Vector Vector::ProjectVectorInto(hEntity wrkpl) {
    EntityBase *w = SK.GetEntity(wrkpl);
    Vector u = w->Normal()->NormalU();
    Vector v = w->Normal()->NormalV();

    double up = this->Dot(u);
    double vp = this->Dot(v);

    return (u.ScaledBy(up)).Plus(v.ScaledBy(vp));
}
Example #7
0
Vector Vector::AtIntersectionOfPlanes(Vector n1, double d1,
                                      Vector n2, double d2)
{
    double det = (n1.Dot(n1))*(n2.Dot(n2)) - 
                 (n1.Dot(n2))*(n1.Dot(n2));
    double c1 = (d1*n2.Dot(n2) - d2*n1.Dot(n2))/det;
    double c2 = (d2*n1.Dot(n1) - d1*n1.Dot(n2))/det;
    
    return (n1.ScaledBy(c1)).Plus(n2.ScaledBy(c2));
}
Example #8
0
bool TextWindow::EditControlDoneForView(const char *s) {
    switch(edit.meaning) {
        case Edit::VIEW_SCALE: {
            Expr *e = Expr::From(s, /*popUpError=*/true);
            if(e) {
                double v =  e->Eval() / SS.MmPerUnit();
                if(v > LENGTH_EPS) {
                    SS.GW.scale = v;
                } else {
                    Error(_("Scale cannot be zero or negative."));
                }
            }
            break;
        }

        case Edit::VIEW_ORIGIN: {
            Vector pt;
            if(sscanf(s, "%lf, %lf, %lf", &pt.x, &pt.y, &pt.z) == 3) {
                pt = pt.ScaledBy(SS.MmPerUnit());
                SS.GW.offset = pt.ScaledBy(-1);
            } else {
                Error(_("Bad format: specify x, y, z"));
            }
            break;
        }

        case Edit::VIEW_PROJ_RIGHT:
        case Edit::VIEW_PROJ_UP: {
            Vector pt;
            if(sscanf(s, "%lf, %lf, %lf", &pt.x, &pt.y, &pt.z) != 3) {
                Error(_("Bad format: specify x, y, z"));
                break;
            }
            if(edit.meaning == Edit::VIEW_PROJ_RIGHT) {
                SS.GW.projRight = pt;
                SS.GW.NormalizeProjectionVectors();
                edit.meaning = Edit::VIEW_PROJ_UP;
                HideEditControl();
                ShowEditControl(10, ssprintf("%.3f, %.3f, %.3f", CO(SS.GW.projUp)),
                                editControl.halfRow + 2);
                edit.showAgain = true;
            } else {
                SS.GW.projUp = pt;
                SS.GW.NormalizeProjectionVectors();
            }
            break;
        }

        default:
            return false;
    }
    return true;
}
Example #9
0
Quaternion Quaternion::Times(Quaternion b) {
    double sa = w, sb = b.w;
    Vector va = { vx, vy, vz };
    Vector vb = { b.vx, b.vy, b.vz };

    Quaternion r;
    r.w = sa*sb - va.Dot(vb);
    Vector vr = vb.ScaledBy(sa).Plus(
                va.ScaledBy(sb).Plus(
                va.Cross(vb)));
    r.vx = vr.x;
    r.vy = vr.y;
    r.vz = vr.z;
    return r;
}
Example #10
0
Vector EntityBase::PointGetNum(void) {
    Vector p;
    switch(type) {
        case POINT_IN_3D:
            p = Vector::From(param[0], param[1], param[2]);
            break;

        case POINT_IN_2D: {
            EntityBase *c = SK.GetEntity(workplane);
            Vector u = c->Normal()->NormalU();
            Vector v = c->Normal()->NormalV();
            p =        u.ScaledBy(SK.GetParam(param[0])->val);
            p = p.Plus(v.ScaledBy(SK.GetParam(param[1])->val));
            p = p.Plus(c->WorkplaneGetOffset());
            break;
        }

        case POINT_N_TRANS: {
            Vector trans = Vector::From(param[0], param[1], param[2]);
            p = numPoint.Plus(trans.ScaledBy(timesApplied));
            break;
        }

        case POINT_N_ROT_TRANS: {
            Vector offset = Vector::From(param[0], param[1], param[2]);
            Quaternion q = PointGetQuaternion();
            p = q.Rotate(numPoint);
            p = p.Plus(offset);
            break;
        }

        case POINT_N_ROT_AA: {
            Vector offset = Vector::From(param[0], param[1], param[2]);
            Quaternion q = PointGetQuaternion();
            p = numPoint.Minus(offset);
            p = q.Rotate(p);
            p = p.Plus(offset);
            break;
        }

        case POINT_N_COPY:
            p = numPoint;
            break;

        default: oops();
    }
    return p;
}
Example #11
0
Vector Vector::AtIntersectionOfLines(Vector a0, Vector a1,
                                     Vector b0, Vector b1,
                                     bool *skew,
                                     double *parama, double *paramb)
{
    Vector da = a1.Minus(a0), db = b1.Minus(b0);

    double pa, pb;
    Vector::ClosestPointBetweenLines(a0, da, b0, db, &pa, &pb);

    if(parama) *parama = pa;
    if(paramb) *paramb = pb;

    // And from either of those, we get the intersection point.
    Vector pi = a0.Plus(da.ScaledBy(pa));

    if(skew) {
        // Check if the intersection points on each line are actually
        // coincident...
        if(pi.Equals(b0.Plus(db.ScaledBy(pb)))) {
            *skew = false;
        } else {
            *skew = true;
        }
    }
    return pi;
}
Example #12
0
void ConstraintBase::ModifyToSatisfy() {
    if(type == Type::ANGLE) {
        Vector a = SK.GetEntity(entityA)->VectorGetNum();
        Vector b = SK.GetEntity(entityB)->VectorGetNum();
        if(other) a = a.ScaledBy(-1);
        if(workplane.v != EntityBase::FREE_IN_3D.v) {
            a = a.ProjectVectorInto(workplane);
            b = b.ProjectVectorInto(workplane);
        }
        double c = (a.Dot(b))/(a.Magnitude() * b.Magnitude());
        valA = acos(c)*180/PI;
    } else {
        // We'll fix these ones up by looking at their symbolic equation;
        // that means no extra work.
        IdList<Equation,hEquation> l = {};
        // Generate the equations even if this is a reference dimension
        GenerateReal(&l);
        ssassert(l.n == 1, "Expected constraint to generate a single equation");

        // These equations are written in the form f(...) - d = 0, where
        // d is the value of the valA.
        valA += (l.elem[0].e)->Eval();

        l.Clear();
    }
}
void ConstraintBase::ModifyToSatisfy(void) {
    if(type == ANGLE) {
        Vector a = SK.GetEntity(entityA)->VectorGetNum();
        Vector b = SK.GetEntity(entityB)->VectorGetNum();
        if(other) a = a.ScaledBy(-1);
        if(workplane.v != EntityBase::FREE_IN_3D.v) {
            a = a.ProjectVectorInto(workplane);
            b = b.ProjectVectorInto(workplane);
        }
        double c = (a.Dot(b))/(a.Magnitude() * b.Magnitude());
        valA = acos(c)*180/PI;
    } else {
        // We'll fix these ones up by looking at their symbolic equation;
        // that means no extra work.
        IdList<Equation,hEquation> l;
        // An uninit IdList could lead us to free some random address, bad.
        ZERO(&l);
        // Generate the equations even if this is a reference dimension
        GenerateReal(&l);
        if(l.n != 1) oops();

        // These equations are written in the form f(...) - d = 0, where
        // d is the value of the valA.
        valA += (l.elem[0].e)->Eval();

        l.Clear();
    }
}
Example #14
0
Quaternion Quaternion::Mirror(void) {
    Vector u = RotationU(),
           v = RotationV();
    u = u.ScaledBy(-1);
    v = v.ScaledBy(-1);
    return Quaternion::From(u, v);
}
Example #15
0
Vector GraphicsWindow::VectorFromProjs(Vector rightUpForward) {
    Vector n = projRight.Cross(projUp);

    Vector r = (projRight.ScaledBy(rightUpForward.x));
    r =  r.Plus(projUp.ScaledBy(rightUpForward.y));
    r =  r.Plus(n.ScaledBy(rightUpForward.z));
    return r;
}
Example #16
0
//-----------------------------------------------------------------------------
// Draw a line with arrows on both ends, and possibly a gap in the middle for
// the dimension. We will use these for most length dimensions. The length
// being dimensioned is from A to B; but those points get extended perpendicular
// to the line AB, until the line between the extensions crosses ref (the
// center of the label).
//-----------------------------------------------------------------------------
void Constraint::DoLineWithArrows(Vector ref, Vector a, Vector b,
                                  bool onlyOneExt)
{
    Vector gn = (SS.GW.projRight.Cross(SS.GW.projUp)).WithMagnitude(1);
    double pixels = 1.0 / SS.GW.scale;

    Vector ab   = a.Minus(b);
    Vector ar   = a.Minus(ref);
    // Normal to a plane containing the line and the label origin.
    Vector n    = ab.Cross(ar);
    // Within that plane, and normal to the line AB; so that's our extension
    // line.
    Vector out  = ab.Cross(n).WithMagnitude(1);
    out = out.ScaledBy(-out.Dot(ar));

    Vector ae = a.Plus(out), be = b.Plus(out);

    // Extension lines extend 10 pixels beyond where the arrows get
    // drawn (which is at the same offset perpendicular from AB as the
    // label).
    LineDrawOrGetDistance(a, ae.Plus(out.WithMagnitude(10*pixels)));
    if(!onlyOneExt) {
        LineDrawOrGetDistance(b, be.Plus(out.WithMagnitude(10*pixels)));
    }

    int within = DoLineTrimmedAgainstBox(ref, ae, be);

    // Arrow heads are 13 pixels long, with an 18 degree half-angle.
    double theta = 18*PI/180;
    Vector arrow = (be.Minus(ae)).WithMagnitude(13*pixels);

    if(within != 0) {
        arrow = arrow.ScaledBy(-1);
        Vector seg = (be.Minus(ae)).WithMagnitude(18*pixels);
        if(within < 0) LineDrawOrGetDistance(ae, ae.Minus(seg));
        if(within > 0) LineDrawOrGetDistance(be, be.Plus(seg));
    }

    LineDrawOrGetDistance(ae, ae.Plus(arrow.RotatedAbout(n,  theta)));
    LineDrawOrGetDistance(ae, ae.Plus(arrow.RotatedAbout(n, -theta)));
    arrow = arrow.ScaledBy(-1);
    LineDrawOrGetDistance(be, be.Plus(arrow.RotatedAbout(n,  theta)));
    LineDrawOrGetDistance(be, be.Plus(arrow.RotatedAbout(n, -theta)));
}
Example #17
0
void ssglWriteTextRefCenter(const char *str, double h, Vector t, Vector u, Vector v,
                            ssglLineFn *fn, void *fndata)
{
    u = u.WithMagnitude(1);
    v = v.WithMagnitude(1);

    double scale = FONT_SCALE(h)/SS.GW.scale;
    double fh = ssglStrHeight(h);
    double fw = ssglStrWidth(str, h);

    t = t.Plus(u.ScaledBy(-fw/2));
    t = t.Plus(v.ScaledBy(-fh/2));

    // Undo the (+5, +5) offset that ssglWriteText applies.
    t = t.Plus(u.ScaledBy(-5*scale));
    t = t.Plus(v.ScaledBy(-5*scale));

    ssglWriteText(str, h, t, u, v, fn, fndata);
}
Example #18
0
Vector GraphicsWindow::ParametricCurve::TangentAt(double t) {
    if(isLine) {
        return p1.Minus(p0);
    } else {
        double theta = theta0 + dtheta*t;
        Vector t =  u.ScaledBy(-r*sin(theta)).Plus(v.ScaledBy(r*cos(theta)));
        t = t.ScaledBy(dtheta);
        return t;
    }
}
Example #19
0
void SSurface::BlendRowOrCol(bool row, int this_ij, SSurface *a, int a_ij,
                                                    SSurface *b, int b_ij)
{
    if(row) {
        int j;
        for(j = 0; j <= degn; j++) {
            Vector c = (a->ctrl  [a_ij][j]).Plus(b->ctrl  [b_ij][j]);
            double w = (a->weight[a_ij][j]   +   b->weight[b_ij][j]);
            ctrl  [this_ij][j] = c.ScaledBy(0.5);
            weight[this_ij][j] = w / 2;
        }
    } else {
        int i;
        for(i = 0; i <= degm; i++) {
            Vector c = (a->ctrl  [i][a_ij]).Plus(b->ctrl  [i][b_ij]);
            double w = (a->weight[i][a_ij]   +   b->weight[i][b_ij]);
            ctrl  [i][this_ij] = c.ScaledBy(0.5);
            weight[i][this_ij] = w / 2;
        }
    }
}
Example #20
0
Vector Vector::InPerspective(Vector u, Vector v, Vector n, 
                             Vector origin, double cameraTan)
{
    Vector r = this->Minus(origin);
    r = r.DotInToCsys(u, v, n);
    // yes, minus; we are assuming a csys where u cross v equals n, backwards
    // from the display stuff
    double w = (1 - r.z*cameraTan);
    r = r.ScaledBy(1/w);

    return r;
}
Example #21
0
void Constraint::DoLabel(Vector ref, Vector *labelPos, Vector gr, Vector gu) {
    double th;
    if(type == COMMENT) {
        th = Style::TextHeight(disp.style);
    } else {
        th = DEFAULT_TEXT_HEIGHT;
    }

    char *s = Label();
    double swidth  = ssglStrWidth(s, th),
           sheight = ssglStrHeight(th);

    // By default, the reference is from the center; but the style could
    // specify otherwise if one is present, and it could also specify a
    // rotation.
    if(type == COMMENT && disp.style.v) {
        Style *st = Style::Get(disp.style);
        // rotation first
        double rads = st->textAngle*PI/180;
        double c = cos(rads), s = sin(rads);
        Vector pr = gr, pu = gu;
        gr = pr.ScaledBy( c).Plus(pu.ScaledBy(s));
        gu = pr.ScaledBy(-s).Plus(pu.ScaledBy(c));
        // then origin
        int o = st->textOrigin;
        if(o & Style::ORIGIN_LEFT) ref = ref.Plus(gr.WithMagnitude(swidth/2));
        if(o & Style::ORIGIN_RIGHT) ref = ref.Minus(gr.WithMagnitude(swidth/2));
        if(o & Style::ORIGIN_BOT) ref = ref.Plus(gu.WithMagnitude(sheight/2));
        if(o & Style::ORIGIN_TOP) ref = ref.Minus(gu.WithMagnitude(sheight/2));
    }

    if(labelPos) {
        // labelPos is from the top left corner (for the text box used to
        // edit things), but ref is from the center.
        *labelPos = ref.Minus(gr.WithMagnitude(swidth/2)).Minus(
                              gu.WithMagnitude(sheight/2));
    }


    if(dogd.drawing) {
        ssglWriteTextRefCenter(s, th, ref, gr, gu, LineCallback, this);
    } else {
        double l = swidth/2 - sheight/2;
        l = max(l, 5/SS.GW.scale);
        Point2d a = SS.GW.ProjectPoint(ref.Minus(gr.WithMagnitude(l)));
        Point2d b = SS.GW.ProjectPoint(ref.Plus (gr.WithMagnitude(l)));
        double d = dogd.mp.DistanceToLine(a, b.Minus(a), true);

        dogd.dmin = min(dogd.dmin, d - (th / 2));
        dogd.refp = ref;
    }
}
Example #22
0
Vector SBezier::PointAt(double t) {
    Vector pt = Vector::From(0, 0, 0);
    double d = 0;

    int i;
    for(i = 0; i <= deg; i++) {
        double B = Bernstein(i, deg, t);
        pt = pt.Plus(ctrl[i].ScaledBy(B*weight[i]));
        d += weight[i]*B;
    }
    pt = pt.ScaledBy(1.0/d);
    return pt;
}
Example #23
0
void ssglWriteText(const char *str, double h, Vector t, Vector u, Vector v,
                   ssglLineFn *fn, void *fndata)
{
    if(!fn) fn = LineDrawCallback;
    u = u.WithMagnitude(1);
    v = v.WithMagnitude(1);

    double scale = FONT_SCALE(h)/SS.GW.scale;
    int xo = 5;
    int yo = 5;

    for(; *str; str++) {
        int c = *str;
        if(c < 32 || c > 126) c = 32;

        c -= 32;

        int j;
        Vector prevp = Vector::From(VERY_POSITIVE, 0, 0);
        for(j = 0; j < Font[c].points; j++) {
            int x = Font[c].coord[j*2];
            int y = Font[c].coord[j*2+1];

            if(x == PEN_UP && y == PEN_UP) {
                prevp.x = VERY_POSITIVE;
            } else {
                Vector p = t;
                p = p.Plus(u.ScaledBy((xo + x)*scale));
                p = p.Plus(v.ScaledBy((yo + y)*scale));
                if(EXACT(prevp.x != VERY_POSITIVE)) {
                    fn(fndata, prevp, p);
                }
                prevp = p;
            }
        }

        xo += Font[c].width;
    }
}
Example #24
0
Vector SBezier::TangentAt(double t) {
    Vector pt = Vector::From(0, 0, 0), pt_p = Vector::From(0, 0, 0);
    double d = 0, d_p = 0;

    int i;
    for(i = 0; i <= deg; i++) {
        double B  = Bernstein(i, deg, t),
               Bp = BernsteinDerivative(i, deg, t);

        pt = pt.Plus(ctrl[i].ScaledBy(B*weight[i]));
        d += weight[i]*B;

        pt_p = pt_p.Plus(ctrl[i].ScaledBy(Bp*weight[i]));
        d_p += weight[i]*Bp;
    }

    // quotient rule; f(t) = n(t)/d(t), so f' = (n'*d - n*d')/(d^2)
    Vector ret;
    ret = (pt_p.ScaledBy(d)).Minus(pt.ScaledBy(d_p));
    ret = ret.ScaledBy(1.0/(d*d));
    return ret;
}
Example #25
0
//-----------------------------------------------------------------------------
// Compute the exact tangent to the intersection curve between two surfaces,
// by taking the cross product of the surface normals. We choose the direction
// of this tangent so that its dot product with dir is positive.
//-----------------------------------------------------------------------------
Vector SSurface::ExactSurfaceTangentAt(Vector p, SSurface *srfA, SSurface *srfB, Vector dir)
{
    Point2d puva, puvb;
    srfA->ClosestPointTo(p, &puva);
    srfB->ClosestPointTo(p, &puvb);
    Vector ts = (srfA->NormalAt(puva)).Cross(
                (srfB->NormalAt(puvb)));
    ts = ts.WithMagnitude(1);
    if(ts.Dot(dir) < 0) {
        ts = ts.ScaledBy(-1);
    }
    return ts;
}
Example #26
0
void Constraint::DoEqualRadiusTicks(hEntity he) {
    Entity *circ = SK.GetEntity(he);

    Vector center = SK.GetEntity(circ->point[0])->PointGetNum();
    double r = circ->CircleGetRadiusNum();
    Quaternion q = circ->Normal()->NormalGetNum();
    Vector u = q.RotationU(), v = q.RotationV();

    double theta;
    if(circ->type == Entity::CIRCLE) {
        theta = PI/2;
    } else if(circ->type == Entity::ARC_OF_CIRCLE) {
        double thetaa, thetab, dtheta;
        circ->ArcGetAngles(&thetaa, &thetab, &dtheta);
        theta = thetaa + dtheta/2;
    } else oops();

    Vector d = u.ScaledBy(cos(theta)).Plus(v.ScaledBy(sin(theta)));
    d = d.ScaledBy(r);
    Vector p = center.Plus(d);
    Vector tick = d.WithMagnitude(10/SS.GW.scale);
    LineDrawOrGetDistance(p.Plus(tick), p.Minus(tick));
}
Example #27
0
static void FatLineEndcap(Vector p, Vector u, Vector v)
{
    // A table of cos and sin of (pi*i/10 + pi/2), as i goes from 0 to 10
    static const double Circle[11][2] = {
        {  0.0000,   1.0000 },
        { -0.3090,   0.9511 },
        { -0.5878,   0.8090 },
        { -0.8090,   0.5878 },
        { -0.9511,   0.3090 },
        { -1.0000,   0.0000 },
        { -0.9511,  -0.3090 },
        { -0.8090,  -0.5878 },
        { -0.5878,  -0.8090 },
        { -0.3090,  -0.9511 },
        {  0.0000,  -1.0000 },
    };
    glBegin(GL_TRIANGLE_FAN);
    for(int i = 0; i <= 10; i++) {
        double c = Circle[i][0], s = Circle[i][1];
        ssglVertex3v(p.Plus(u.ScaledBy(c)).Plus(v.ScaledBy(s)));
    }
    glEnd();
}
Example #28
0
void Group::GenerateForStepAndRepeat(T *steps, T *outs) {
    T workA, workB;
    workA = {};
    workB = {};
    T *soFar = &workA, *scratch = &workB;

    int n = (int)valA, a0 = 0;
    if(subtype == ONE_SIDED && skipFirst) {
        a0++; n++;
    }
    int a;
    for(a = a0; a < n; a++) {
        int ap = a*2 - (subtype == ONE_SIDED ? 0 : (n-1));
        int remap = (a == (n - 1)) ? REMAP_LAST : a;

        T transd = {};
        if(type == TRANSLATE) {
            Vector trans = Vector::From(h.param(0), h.param(1), h.param(2));
            trans = trans.ScaledBy(ap);
            transd.MakeFromTransformationOf(steps,
                trans, Quaternion::IDENTITY, 1.0);
        } else {
            Vector trans = Vector::From(h.param(0), h.param(1), h.param(2));
            double theta = ap * SK.GetParam(h.param(3))->val;
            double c = cos(theta), s = sin(theta);
            Vector axis = Vector::From(h.param(4), h.param(5), h.param(6));
            Quaternion q = Quaternion::From(c, s*axis.x, s*axis.y, s*axis.z);
            // Rotation is centered at t; so A(x - t) + t = Ax + (t - At)
            transd.MakeFromTransformationOf(steps,
                trans.Minus(q.Rotate(trans)), q, 1.0);
        }

        // We need to rewrite any plane face entities to the transformed ones.
        transd.RemapFaces(this, remap);

        // And tack this transformed copy on to the return.
        if(soFar->IsEmpty()) {
            scratch->MakeFromCopyOf(&transd);
        } else {
            scratch->MakeFromUnionOf(soFar, &transd);
        }

        swap(scratch, soFar);
        scratch->Clear();
        transd.Clear();
    }

    outs->Clear();
    *outs = *soFar;
}
Example #29
0
Vector SSurface::PointAt(double u, double v) {
    Vector num = Vector::From(0, 0, 0);
    double den = 0;

    int i, j;
    for(i = 0; i <= degm; i++) {
        for(j = 0; j <= degn; j++) {
            double Bi = Bernstein(i, degm, u),
                   Bj = Bernstein(j, degn, v);

            num = num.Plus(ctrl[i][j].ScaledBy(Bi*Bj*weight[i][j]));
            den += weight[i][j]*Bi*Bj;
        }
    }
    num = num.ScaledBy(1.0/den);
    return num;
}
Example #30
0
void GraphicsWindow::HandlePointForZoomToFit(Vector p, Point2d *pmax, Point2d *pmin,
                                             double *wmin, bool usePerspective)
{
    double w;
    Vector pp = ProjectPoint4(p, &w);
    // If usePerspective is true, then we calculate a perspective projection of the point.
    // If not, then we do a parallel projection regardless of the current
    // scale factor.
    if(usePerspective) {
        pp = pp.ScaledBy(1.0/w);
    }

    pmax->x = max(pmax->x, pp.x);
    pmax->y = max(pmax->y, pp.y);
    pmin->x = min(pmin->x, pp.x);
    pmin->y = min(pmin->y, pp.y);
    *wmin = min(*wmin, w);
}