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.
Class Simple Axis
This class can be used to draw the XYZ axis as lines. An example is shown in the figure below.
//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 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.
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 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.
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 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.
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 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.
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 Polyline
Draws a polyline based on a sequence of points. See the image below for an example.
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 Dashed Line
Draws a dashed line between two points. See the image below for examples.
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 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.
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 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)
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.
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 Cubic Patch
Prepares VAOs to draw cubic Bezier patches with tangent and bitangent data. See image below.
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;