Skip to content

Commit

Permalink
Fixed elliptical nosecone; added torus and tube primitives
Browse files Browse the repository at this point in the history
  • Loading branch information
qkmaxware committed Jul 7, 2020
1 parent 37091c6 commit e375717
Show file tree
Hide file tree
Showing 8 changed files with 195 additions and 3 deletions.
19 changes: 19 additions & 0 deletions Geometry.Test/suites/Geometry/Primitives/Torus.test.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.IO;
using Qkmaxware.Geometry;
using Qkmaxware.Geometry.IO;
using Qkmaxware.Geometry.Primitives;

namespace Astro.Testing {

[TestClass]
public class TorusTest : PrimitiveTest {
[TestMethod]
public void TestTorus() {
var geom = new Torus(1, 0.2, Vec3.Zero);
SaveGeometry("torus", geom);
}
}

}
19 changes: 19 additions & 0 deletions Geometry.Test/suites/Geometry/Primitives/Tube.test.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.IO;
using Qkmaxware.Geometry;
using Qkmaxware.Geometry.IO;
using Qkmaxware.Geometry.Primitives;

namespace Astro.Testing {

[TestClass]
public class TubeTest : PrimitiveTest {
[TestMethod]
public void TestTube() {
var geom = new Tube(1, 0.8, 2, Vec3.Zero);
SaveGeometry("tube", geom);
}
}

}
17 changes: 14 additions & 3 deletions Geometry/src/Geometry/Primitives/Nosecone.cs
Original file line number Diff line number Diff line change
Expand Up @@ -131,12 +131,15 @@ private static List<Triangle> FuncNosecone(Func<double,double> radiusAtHeightFun
double yStep = height / segments;
List<Triangle> tris = new List<Triangle>();

var firstLevelHeight = 1 * yStep;
var radiusAtFirstLevelHeight = radiusAtHeightFunc(firstLevelHeight);

// Do top cap
for (var i = 1; i <= resolution; i++) {
double preAngle = (i - 1) * xStep;
double angle = i * xStep;
double heightAtLevel = 1 * yStep;
double radiusAtLevel = radiusAtHeightFunc(heightAtLevel);
double heightAtLevel = firstLevelHeight;
double radiusAtLevel = radiusAtFirstLevelHeight;

// Ring
var x1 = new Vec3(
Expand Down Expand Up @@ -272,7 +275,15 @@ public static Nosecone Elliptical(double radius, double height, int resolution =
return new Nosecone(
FuncNosecone(
(h) => {
return radius * Math.Sqrt(1 - (h * h / height * height));
h = Math.Max(0, Math.Min(h, height)); // clamp h between 0 and height
//var hh = h * h;
var hShifted = h - height;
var hShifted2 = hShifted * hShifted;
var height2 = height * height;
var flipped = (radius/height) * Math.Sqrt( (height2) - (hShifted2));
return flipped;
//var hOverHeight = Math.Min( ((hh) / (height2)), 1 ); // clamp ratio to < 1
//return -radius * Math.Sqrt(1 - hOverHeight) + radius;
},
radius, height, resolution, segments
)
Expand Down
59 changes: 59 additions & 0 deletions Geometry/src/Geometry/Primitives/Torus.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
using System;
using System.Collections.Generic;

namespace Qkmaxware.Geometry.Primitives {

/// <summary>
/// Torus mesh
/// </summary>
public class Torus : Mesh {

public Torus (double majorRadius, double minorRadius, Vec3 centre, int resolution = 8, int segments = 8) {
double ringStep = 2 * Math.PI / resolution;
double moveStep = 2 * Math.PI / segments;

for (int i = 1; i <= segments; i++) {
double prevAngle = (i - 1) * moveStep;
double angle = (i) * moveStep;

var previousDirection = new Vec3(
Math.Cos(prevAngle),
Math.Sin(prevAngle),
0
);
var previousPointCentre = majorRadius * previousDirection + centre;
var previousLeft = previousDirection;
var previousUp = Vec3.K;

var nextDirection = new Vec3(
Math.Cos(angle),
Math.Sin(angle),
0
);
var nextPointCentre = majorRadius * nextDirection + centre;
var nextLeft = nextDirection;
var nextUp = Vec3.K;

// Move around the ring
for (var j = 1; j <= resolution; j++) {
double prevCicleAngle = (j - 1) * ringStep;
double cicleAngle = (j) * ringStep;

// Previous points
var previousStart = previousPointCentre + minorRadius * ( previousLeft * Math.Cos(prevCicleAngle) + previousUp * Math.Sin(prevCicleAngle) );
var previousEnd = previousPointCentre + minorRadius * ( previousLeft * Math.Cos(cicleAngle) + previousUp * Math.Sin(cicleAngle) );

// Next points
var nextStart = nextPointCentre + minorRadius * ( nextLeft * Math.Cos(prevCicleAngle) + nextUp * Math.Sin(prevCicleAngle) );
var nextEnd = nextPointCentre + minorRadius * ( nextLeft * Math.Cos(cicleAngle) + nextUp * Math.Sin(cicleAngle) );

// Create faces
this.Append(new Triangle(previousStart, nextStart, nextEnd));
this.Append(new Triangle(previousStart, nextEnd, previousEnd));
}
}
}

}

}
82 changes: 82 additions & 0 deletions Geometry/src/Geometry/Primitives/Tube.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
using System;
using System.Collections.Generic;

namespace Qkmaxware.Geometry.Primitives {

/// <summary>
/// Tube mesh
/// </summary>
public class Tube : Mesh {
private static List<Triangle> Generate(double outerRadius, double innerRadius, double h, Vec3 centre, int resolution) {
List<Triangle> triangles = new List<Triangle>();
double step = 2 * Math.PI / resolution;
double hStep = h / 2;

for (int i = 1; i <= resolution; i++) {
double prevAngle = (i - 1) * step;
double xi = Math.Cos(prevAngle);
double yi = Math.Sin(prevAngle);

double angle = i * step;
double xe = Math.Cos(angle);
double ye = Math.Sin(angle);

/*
top
/ \
te -- ti
| / |
| / |
be -- bi
\ /
bottom
*/
// Outer tube
// Create top points
Vec3 te = new Vec3(xe * outerRadius, ye * outerRadius, hStep) + centre;
Vec3 ti = new Vec3(xi * outerRadius, yi * outerRadius, hStep) + centre;
// Create bottom points
Vec3 be = new Vec3(xe * outerRadius, ye * outerRadius, -hStep) + centre;
Vec3 bi = new Vec3(xi * outerRadius, yi * outerRadius, -hStep) + centre;

// Create triangles
triangles.Add(new Triangle(be, te, ti));
triangles.Add(new Triangle(be, ti, bi));

// Inner tube
// Create top points
Vec3 ite = new Vec3(xe * innerRadius, ye * innerRadius, hStep) + centre;
Vec3 iti = new Vec3(xi * innerRadius, yi * innerRadius, hStep) + centre;
// Create bottom points
Vec3 ibe = new Vec3(xe * innerRadius, ye * innerRadius, -hStep) + centre;
Vec3 ibi = new Vec3(xi * innerRadius, yi * innerRadius, -hStep) + centre;

// Create triangles
triangles.Add(new Triangle(ibe, iti, ite));
triangles.Add(new Triangle(ibe, ibi, iti));

// Joiners
triangles.Add(new Triangle(te, ite, iti));
triangles.Add(new Triangle(te, iti, ti));

triangles.Add(new Triangle(be, ibi, ibe));
triangles.Add(new Triangle(be, bi, ibi));
}

return triangles;
}

/// <summary>
/// Cylinder with different radii for top and bottom caps
/// </summary>
/// <param name="outerRadius">outer radius</param>
/// <param name="innerRadius">inner radius</param>
/// <param name="height">height</param>
/// <param name="centre">centre</param>
/// <param name="resolution">subdivision level</param>
public Tube (double outerRadius, double innerRadius, double height, Vec3 centre, int resolution = 8) : base(Generate(outerRadius, innerRadius, height, centre, resolution)) {}


}

}
2 changes: 2 additions & 0 deletions Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,10 @@ Geometry in this library is modeled as a collection of triangular faces whose ve
| Plane | Flat planar face in the XY plane | <img width="128" src="docs/images/PrimitivePlane.png"/> |
| Cube | 6 sided cube | <img width="128" src="docs/images/PrimitiveCube.png"/> |
| Cylinder | Solid cylinder with configurable radii | <img width="128" src="docs/images/PrimitiveCylinder.png"/> |
| Tube | Hollowed out cylinder with an inner and outer radius | <img width="128" src="docs/images/PrimitiveTube.png"/> |
| Cone | Cone with a given radius | <img width="128" src="docs/images/PrimitiveCone.png"/> |
| Sphere | UV sphere | <img width="128" src="docs/images/PrimitiveSphere.png"/> |
| Torus | Torus with configurable radii | <img width="128" src="docs/images/PrimitiveTorus.png"/> |
| Frustum | Pyramidal Frustums | <img width="128" src="docs/images/PrimitiveFrustum.png"/> |
| Nosecone | Varieties of aerodynamic nosecones | <img width="128" src="docs/images/PrimitiveNoseconeBiconic.png"/> <img width="128" src="docs/images/PrimitiveNoseconeParabolic.png"/> <img width="128" src="docs/images/PrimitiveNoseconeSecant.png"/>|

Expand Down
Binary file added docs/images/PrimitiveTorus.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/PrimitiveTube.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit e375717

Please sign in to comment.