Help end child hunger

VSGeometryLib – Very Simple Geometry Library

 

VSGeometry is a set of classes to draw geometric shapes commonly used in diagrams, such as axis, vectors, points. It also draws curves and cubic bezier patches. It was created for academic purposes to create diagrams to include in notes and present in class.

All classes are subclass of VSModelLib. VSModelLib provides the common frame to create the VAOs and set the material, such as colors and shaders to use. To render an instance just call the method render.

Most classes use an auxiliary class Point3 that is just a convenient way to describe a 3D Cartesian point.

The use a class first declare a variable as an instance of the class. Then, we call the method set to create the geometry and store it in VAOs. To render just call the method render from the parent class VSModelLib.

The available classes are:

Class Simple Axis

This class can be used to draw the XYZ axis as lines. An example is shown in the figure below.

simpleaxis

//declaration
VSSimpleAxis simpleAxis;
...
void init() {
    ...
    simpleAxis.set(2.0f);
    float lightGrey[4] = { 0.6f, 0.6f, 0.6f, 1.0f };
    simpleAxis.setColor(VSResourceLib::EMISSIVE, lightGrey);
    ...
}

void render() {
    // clear buffers, init cameras, etc...
    ...
    simpleAxis.render();
    ...
    // swap buffers
}

Note that we set the emissive color since lines do not have normals.

(class list)


Class Point

A point is represented by a sphere. To set a point just provide it’s location and, optionally, the radius of the sphere. An example of its usage is shown in the image below.

points

Note that the green point is much larger since it was created with a radius three times the default value.

The following code was used to create, set and render the three points.

//declaration
VSPoint p1, p2, p3;
...
void init() {
    ...
    float red[4] = { 0.8f, 0.2f, 0.2f, 1.0f };
    float green[4] = { 0.2f, 0.8f, 0.2f, 1.0f };
    float blue[4] = { 0.2f, 0.2f, 0.8f, 1.0f };
    p1.set(Point3(1, 0, 0));
    p1.setColor(VSResourceLib::DIFFUSE, red);
    p2.set(Point3(0, 1, 0), 0.03f);
    p2.setColor(VSResourceLib::DIFFUSE, green);
    p3.set(Point3(1, 1, 0));
    p3.setColor(VSResourceLib::DIFFUSE, blue);
    ...
}

void render() {
    // clear buffers, init cameras, etc...
    ...
    p1.render(); p2.render(); p3.render();
    ...
    // swap buffers
}

The following methods are available in this class:

    void set(const Point3 &p, float radius = 0.01f);
    void setPosition(const Point3 &p);
    void setPosition(float *p);
    void setPosition(float x, float y, float z);
    void setRadius(float rad);
    const Point3 &getPosition();
    float getRadius();

(class list)


Class Vector

A vector is represented as an arrow (a long cylinder with a cone on the tip) and is defined by its two end points. The radius of the cylinder can be adjusted manually, while the definition of the cone is computed based on the cylinder’s radius. An example is shown in the figure below where the two vectors have different radius.

vectors

The following code was used to create, set and render the two vector.

//declaration
VSVector v1, v2;
...
void init() {
    ...
    v1.set(Point3(0, 0, 0), Point3(0.4f, 0.2f, 0), 0.005);
    v1.setColor(VSResourceLib::DIFFUSE, green);
    v2.set(Point3(0.0f, 0.0f, 0), Point3(0.2f, 0.4f, 0.1f));
    v2.setColor(VSResourceLib::DIFFUSE, red);
   ...
}

void render() {
    // clear buffers, init cameras, etc...
    ...
    v1.render(); v2.render(); 
    ...
    // swap buffers
}

The following methods are available in this class:

    void set(const Point3 &from, const Point3 &to, float radius = 0.01);
    void setFrom(const Point3 &p);
    void setTo(const Point3 &p);
    void setRadius(float radius);
    const Point3 &getFrom();
    const Point3 &getTo();
    float getRadius();

(class list)


Class Axis

This class is similar to the simple axis class, except that the axis are now graphically represented as vectors, and are colored as follows (X,Y,Z) -> (Red, Green, Blue). The origin is drawn as a white sphere. An example is shown below with the axis covering both positive and negative sides, and only in the first quadrant.

axis1 axis2

The code to get the picture on the right side is:

//declaration
VSAxis axis;
...
void init() {
    ...
    axis.set(1.0f);
    ...
}

void render() {
    // clear buffers, init cameras, etc...
    ...
    axis.render();
    ...
    // swap buffers
}

The only method for this class is

    void set(float length = 1.0f, bool positiveOnly = true, float radius = 0.01f);

(class list)


Class Grid

Draws a grid in one of the following planes: XY, XZ or YZ. The following image shows an example of a grid in the XZ plane.

grid

The code to render the grid in the image above is:

//declaration
VSGrid grid;
...
void init() {
    ...
    grid.set(VSGrid::Y, 1, 10);
    grid.setColor(VSResourceLib::EMISSIVE, lightGrey);
    ...
}

void render() {
    // clear buffers, init cameras, etc...
    ...
    grid.render();
    ...
    // swap buffers
}

The only method for this class is

    void set(Axis ax, float max = 1.0, float divisions = 10);
0.01f);

where Axis is an enum containing the possible grid configurations, i.e. the indication of the vector perpendicular to the grid.

    enum Axis {
	X, Y, Z
    };

(class list)


Class Polyline

Draws a polyline based on a sequence of points. See the image below for an example.

polyline

The code to render the polyline in the image above is:

//declaration
VSPolyline pl;
...
void init() {
    ...
    std::vector<Point3> pp = { 
        Point3(0,1,0), Point3(1,1,0), 
        Point3(1,2,0), Point3(2,2,0) };
    pl.set(pp);
    pl.setColor(VSResourceLib::EMISSIVE, lightGrey);
    ...
}

void render() {
    // clear buffers, init cameras, etc...
    ...
    pl.render();
    ...
    // swap buffers
}

The only method for this class is

    void set(const std::vector &polyLine, bool loop = false);

(class list)


Class Dashed Line

Draws a dashed line between two points. See the image below for examples.

dashedline

The code to render the lines in the image above is:

//declaration
VSDashedline dl1, dl2, dl3;
...
void init() {
    ...
    dl1.set(Point3(0, 0.5f, 0), Point3(3, 0.5f, 0), 0.1);
    dl1.setColor(VSResourceLib::EMISSIVE, lightGrey);
    dl2.set(Point3(0, 1.5f, 0), Point3(3, 1.5f, 0));
    dl2.setColor(VSResourceLib::EMISSIVE, lightGrey);
    dl3.set(Point3(0, 2.5f, 0), Point3(3, 2.5f, 0), 0.025);
    dl3.setColor(VSResourceLib::EMISSIVE, lightGrey);
    ...
}

void render() {
    // clear buffers, init cameras, etc...
    ...
    dl1.render(); dl2.render(); dl3.render();
    ...
    // swap buffers
}

The only method for this class is

    void set(const Point3 &from, const Point3 &to, float dashInterval = 0.05f);

(class list)


Class Dashed Arc

Draws a dashed segment of a circle on the XZ plane. In the image below a rotation is applied to some of the arcs.

dashedarc

The code to render the lines in the image above is:

//declaration
VSDashedArc da;
...
void init() {
    ...
    da.set(90.0f, 2.0f);
    da.setColor(VSResourceLib::EMISSIVE, lightGrey);
    ...
}

void render() {
    // clear buffers, init cameras, etc...
    ...
    da.render(); 
    
    vsml->pushMatrix(VSMathLib::MODEL);
    vsml->rotate(90, 0, 0, 1);
    da.render();
	vsml->popMatrix(VSMathLib::MODEL);
    	
    vsml->pushMatrix(VSMathLib::MODEL);
    vsml->rotate(-90, 1, 0, 0);
    da.render();
	vsml->popMatrix(VSMathLib::MODEL);
    ...
    // swap buffers
}

The only method for this class is

    void set(float angleDegrees, float radius, float dashInterval = 0.05f);

(class list)


Class Cubic Curve

Prepares VAOs for Catmull-Rom and Bezier curves. The image below shows a Bezier curve and its convex hull (drawn with a polyline)

bezier

The code to render the lines in the image above is:

//declaration
VSPolyline pl;
VSCubicCurve cc;
...
void init() {
    ...
    // the control points
    std::vector<Point3> pp = { 
         Point3(0,0,0), Point3(0.5,2,0), 
         Point3(2.5,2,0), Point3(3,0,0) };
    // prepare the convex hull
    pl.set(pp);
    float lightGrey[4] = { 0.6f, 0.6f, 0.6f, 1.0f };
    pl.setColor(VSResourceLib::EMISSIVE, lightGrey);
    // prepare the curve
    float lightYellow[4] = { 1.0f, 1.0f, 0.8f, 1.0f };
    cc.setType(VSCubicCurve::BEZIER);
    cc.set(pp, 20);
    cc.setColor(VSResourceLib::EMISSIVE, lightYellow);
    ...
}

void render() {
    // clear buffers, init cameras, etc...
    ...
    pl.render(); 
    cc.render();
    ...
    // swap buffers
}

For each set of 4 control points a curve is drawn.

The image bellow shows a Catmull-Rom curve where the control points are used in a loop. Catmull-Rom curves are drawn first using the first four points, then from the second to the fifth point and so on.

catmullrom

The code to render the lines in the image above is:

//declaration
VSPolyline pl;
VSCubicCurve cc;
...
void init() {
    ...
    // the control points
    std::vector<Point3> pp = { 
        Point3(0.5f,0,0), Point3(1,1,0), Point3(-1,1,0), 
        Point3(-1,-1,0), Point3(1,-1,0) };
    // prepare the convex hull
    pl.set(pp, true);
    float lightGrey[4] = { 0.6f, 0.6f, 0.6f, 1.0f };
    pl.setColor(VSResourceLib::EMISSIVE, lightGrey);
    // prepare the curve
    float lightYellow[4] = { 1.0f, 1.0f, 0.8f, 1.0f };
    cc.setType(VSCubicCurve::CATMULL_ROM);
    cc.set(pp, 20, true);
    cc.setColor(VSResourceLib::EMISSIVE, lightYellow);
    ...
}

void render() {
    // clear buffers, init cameras, etc...
    ...
    pl.render(); 
    cc.render();
    ...
    // swap buffers
}

The following methods are available in this class:

    void set(const std::vector<Point3> &ctrlPts, unsigned int tessLevel, bool loop = false);
    void setType(CurveType c);
    void getPoint(float t, Point3 &res) const;
    void getTangent(float t, Point3 &res) const;

Note that the t in methods getPoint and getTangent is a “global” t, i.e., the integer part is used to determine the segment, and the fractional part is where we are inside the curve.

(class list)


Class Cubic Patch

Prepares VAOs to draw cubic Bezier patches with tangent and bitangent data. See image below.

cubicpatch

The code to render the lines in the image above is:

//declaration
VSCubicPatch cp;
...
void init() {
    ...
    // the control points
    std::vector<Point3> pp = { 
		Point3(0,0,0),
		Point3(0.33,0.25,0),
		Point3(0.66, 0.25,0),
		Point3(1, 0, 0),

		Point3(0, 0.25,0.33),
		Point3(0.33, 0.75,0.33),
		Point3(0.66, 0.75,0.33),
		Point3(1, 0.25,0.33),

		Point3(0, 0.25, 0.66),
		Point3(0.33, 0.75, 0.66),
		Point3(0.66, 0.75, 0.66),
		Point3(1, 0.25, 0.66),

		Point3(0, 0,  1),
		Point3(0.33, 0.25,1),
		Point3(0.66, 0.25,1),
		Point3(1, 0,  1),
	};
    float lightGrey[4] = { 0.6f, 0.6f, 0.6f, 1.0f };
    cp.set(pp, 20);
    cp.setColor(VSResourceLib::DIFFUSE, lightGrey);
    ...
}

void render() {
    // clear buffers, init cameras, etc...
    ...
    pl.render(); 
    cp.render();
    ...
    // swap buffers
}

The following methods are available in this class:

     void set(const std::vector &ctrlPts, unsigned int tessLevel);
     void getPoint(float u, float v, Point3 &res) const;
     void getNormal(float u, float v, Point3 &res) const;
     void getTangent(float u, float v, Point3 &res) const;
     void getBiTangent(float u, float v, Point3 &res) const;
     const std::vector &getControlPoints() const;

Leave a Reply