private static Cartesian2D ToDymaxionPoint(Cartesian3D point) { // Here be dragons var gz = Sqrt(1 - Pow(point.X, 2) - Pow(point.Y, 2)); var gs = Sqrt(5 + 2 * Sqrt(5)) / (gz * Sqrt(15)); var gxp = point.X * gs; var gyp = point.Y * gs; var ga1p = 2.0 * gyp / Sqrt(3.0) + (GElevation / 3.0); var ga2p = gxp - (gyp / Sqrt(3)) + (GElevation / 3.0); var ga3p = (GElevation / 3.0) - gxp - (gyp / Sqrt(3)); var ga1 = Gt + Atan((ga1p - 0.5 * GElevation) / GDve); var ga2 = Gt + Atan((ga2p - 0.5 * GElevation) / GDve); var ga3 = Gt + Atan((ga3p - 0.5 * GElevation) / GDve); var gx = 0.5 * (ga2 - ga3); var gy = (1.0 / (2.0 * Sqrt(3))) * (2 * ga1 - ga2 - ga3); /* Re-scale so plane triangle edge length is 1. */ var x = gx / GArc; var y = gy / GArc; return(new Cartesian2D(x: x, y: y)); }
public void Cartesian3D_Vector_Maths_Tests() { Vector3 v1 = new Vector3(1, 1, 1); Vector3 v2 = new Vector3(1, 4, 1); Vector3 v3 = new Vector3(10, 0, 0); Vector3 v4 = new Vector3(0, 3, 0); Vector3 v5 = new Vector3(2, 5, 2); Vector3 normal = new Vector3(1, 0, 0); var sq = Cartesian3D.DistanceSquared(v1, v2); sq.Should().Be(9); var dst = Cartesian3D.Distance(v1, v2); dst.Should().Be(3); var nm = Cartesian3D.Normalize(v3); nm.Should().Be(normal); var mag = Cartesian3D.Magnitude(v3); mag.Should().Be(10); var sub = Cartesian3D.Subtract(v2, v1); sub.Should().Be(v4); var add = Cartesian3D.Add(v2, v1); add.Should().Be(v5); }
private static int GetLcdTriangleIndex(FullerIcosahedron.Face face, Cartesian3D point) { var hDist1 = (point - face.A).Magnitude(); var hDist2 = (point - face.B).Magnitude(); var hDist3 = (point - face.C).Magnitude(); if ((hDist1 <= hDist2) && (hDist2 <= hDist3)) { return(0); } if ((hDist1 <= hDist3) && (hDist3 <= hDist2)) { return(5); } if ((hDist2 <= hDist1) && (hDist1 <= hDist3)) { return(1); } if ((hDist2 <= hDist3) && (hDist3 <= hDist1)) { return(2); } if ((hDist3 <= hDist1) && (hDist1 <= hDist2)) { return(4); } if ((hDist3 <= hDist2) && (hDist2 <= hDist1)) { return(3); } else { throw new Exception("Could not identify lowest common denominator triangle"); } }
public void Can_rotate_around_z(double initialX, double initialY, double initialZ, double rotationAngleDegrees, double expectedX, double expectedY, double expectedZ) { var point = new Cartesian3D(initialX, initialY, initialZ); var result = point.RotateZ(Angle.From(Degrees.FromRaw(rotationAngleDegrees))); Assert.Equal(new Cartesian3D(expectedX, expectedY, expectedZ), result); }
public void Can_calculate_magnitude(double x, double y, double z, double expected) { var point = new Cartesian3D(x, y, z); var result = point.Magnitude(); Assert.Equal(expected, result); }
public Face(Cartesian3D a, Cartesian3D b, Cartesian3D c) { A = a; B = b; C = c; var unscaledCentroid = (A + B + C).Divide(3); Centroid = unscaledCentroid.Divide(unscaledCentroid.Magnitude()); }
public void Can_subtract() { var point1 = new Cartesian3D(1, 2, 3); var point2 = new Cartesian3D(4, 5, 6); var result = point2 - point1; Assert.Equal(new Cartesian3D(3, 3, 3), result); }
public void Can_add() { var point1 = new Cartesian3D(1, 2, 3); var point2 = new Cartesian3D(4, 5, 6); var result = point1 + point2; Assert.Equal(new Cartesian3D(5, 7, 9), result); }
public void Can_create() { var(x, y, z) = (1, 2, 3); var point = new Cartesian3D(x, y, z); Assert.Equal(x, point.X); Assert.Equal(y, point.Y); Assert.Equal(z, point.Z); }
public static FullerTriangle ForPoint(Cartesian3D point) { var container = FullerIcosahedron.Faces .Select((f, i) => new { Index = i, Face = f }) .OrderBy(o => (o.Face.Centroid - point).Magnitude()) .First(); var lcdIndex = GetLcdTriangleIndex(container.Face, point); var transform = GetFullerTransformation(container.Index, lcdIndex); return(new FullerTriangle(container.Face, lcdIndex, transform)); }
public void Can_convert_cartesian_to_spherical(double x, double y, double z, double phi, double theta, double r) { var point = new Cartesian3D(x, y, z); var result = Conversion.Spherical.From(point); var expected = new Spherical( phi: Angle.From(Degrees.FromRaw(phi)), theta: Angle.From(Degrees.FromRaw(theta)), r: r); Assert.Equal(expected, result); }
public void Can_convert_spherical_to_cartesian(double phi, double theta, double r, double x, double y, double z) { var spherical = new Spherical( phi: Angle.From(Degrees.FromRaw(phi)), theta: Angle.From(Degrees.FromRaw(theta)), r: r); var cartesian = Conversion.Cartesian3D.From(spherical); var expected = new Cartesian3D(x, y, z); Assert.Equal(expected, cartesian); }
public static Cartesian2D GetCoordinatesOnFullerProjection(Cartesian3D point) { var containingTriangle = FullerTriangle.ForPoint(point); var triangleCentre = Conversion.Spherical.From(containingTriangle.IcosahedronFace.Centroid); var vertexPoint = containingTriangle.IcosahedronFace.A .RotateZ(triangleCentre.Phi) .RotateY(triangleCentre.Theta); point = point .RotateZ(triangleCentre.Phi) .RotateY(triangleCentre.Theta); var sphericalVertexPoint = Conversion.Spherical.From(vertexPoint); var adjustedLongitude = sphericalVertexPoint.Phi - (Angle.From(Degrees.Ninety)); point = point.RotateZ(adjustedLongitude); var dymaxionPoint = ToDymaxionPoint(point); return(containingTriangle.Transform(dymaxionPoint)); }
/// <summary> /// Compute normal map for lighting /// </summary> private void ComputeNormalMap() { var j = 0; var i = 0; double currY; double currX; Vector3 v1; Vector3 v2; Vector3 v3; // Build triangle list for normal computation later for (int y = 0; y < ElevData.GridSize - 1; y++) { for (int x = 0; x < ElevData.GridSize - 1; x++) { v1 = ElevData.EcefPoints[i]; v2 = ElevData.EcefPoints[i + 1]; v3 = ElevData.EcefPoints[i + ElevData.GridSize + 1]; ElevData.Triangles[j] = new Triangle(v1, v2, v3); // Add two triangles per square v1 = ElevData.EcefPoints[i + ElevData.GridSize + 1]; v2 = ElevData.EcefPoints[i + ElevData.GridSize]; v3 = ElevData.EcefPoints[i]; ElevData.Triangles[j + 1] = new Triangle(v1, v2, v3); i++; j += 2; } i++; } ElevData.HasData = true; ElevData.HasLighting = true; // Compute normal map ElevData.VertexNormals = Cartesian3D.ComputeVertextNormals(ref ElevData.Triangles, ElevData.GridSize); }