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.

```//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);
const Point3 &getPosition();
```

### 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);
const Point3 &getFrom();
const Point3 &getTo();
```

### 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;
```

This site uses Akismet to reduce spam. Learn how your comment data is processed.