Exemplo n.º 1
0
        private static Model3D[] CreateIcons_Rotate(double arcRadius, double arcThickness, double arrowThickness, double sphereRadius)
        {
            const int NUMSIDES_TOTAL = 13;
            const int NUMSIDES_USE   = 9;

            #region create triangles

            Point[] pointsTheta = Math2D.GetCircle_Cached(NUMSIDES_TOTAL);

            var circlePoints = pointsTheta.
                               Select(o => GetCirclePoints(o, arcRadius, arcThickness, sphereRadius)).
                               ToArray();

            List <Triangle> triangles = new List <Triangle>();

            for (int cntr = 0; cntr < NUMSIDES_USE - 1; cntr++)
            {
                triangles.Add(new Triangle(circlePoints[cntr].inner, circlePoints[cntr].outer, circlePoints[cntr + 1].inner));
                triangles.Add(new Triangle(circlePoints[cntr].outer, circlePoints[cntr + 1].outer, circlePoints[cntr + 1].inner));
            }

            int i1 = NUMSIDES_USE - 1;
            int i2 = NUMSIDES_USE;

            var arrowBase = GetCirclePoints(pointsTheta[i1], arcRadius, arrowThickness, sphereRadius);
            var arrowTip  = GetCirclePoints(pointsTheta[i2], arcRadius, arcThickness * .75, sphereRadius);       //NOTE: Not using mid, because that curls the arrow too steeply (looks odd).  So using outer as a comprimise between pointing in and pointing straight

            triangles.Add(new Triangle(arrowBase.inner, circlePoints[i1].inner, arrowTip.outer));
            triangles.Add(new Triangle(circlePoints[i1].inner, circlePoints[i1].outer, arrowTip.outer));
            triangles.Add(new Triangle(circlePoints[i1].outer, arrowBase.outer, arrowTip.outer));

            // It would be more efficient to build the link triangles directly, but a lot more logic
            ITriangleIndexed[] indexedTriangles = TriangleIndexed.ConvertToIndexed(triangles.ToArray());

            #endregion

            List <Model3D> retVal = new List <Model3D>();

            MaterialGroup material = new MaterialGroup();
            material.Children.Add(new DiffuseMaterial(new SolidColorBrush(WorldColors.ImpulseEngine_Icon_Color)));
            material.Children.Add(WorldColors.ImpulseEngine_Icon_Specular);
            material.Children.Add(WorldColors.ImpulseEngine_Icon_Emissive);

            foreach (Transform3D transform in GetRotations_Tetrahedron(sphereRadius))
            {
                GeometryModel3D geometry = new GeometryModel3D();
                geometry.Material     = material;
                geometry.BackMaterial = material;
                geometry.Geometry     = UtilityWPF.GetMeshFromTriangles(indexedTriangles);
                geometry.Transform    = transform;

                retVal.Add(geometry);
            }

            return(retVal.ToArray());
        }
Exemplo n.º 2
0
        /// <summary>
        /// This is exposed so it can be called externally on a separate thread, then call this asteroid's constructor
        /// in the main thread once this returns
        /// </summary>
        public static ITriangleIndexed[] GetHullTriangles(double radius)
        {
            const int NUMPOINTS = 60;           // too many, and it looks too perfect

            Exception lastException = null;
            Random    rand          = StaticRandom.GetRandomForThread();

            for (int infiniteLoopCntr = 0; infiniteLoopCntr < 50; infiniteLoopCntr++)           // there is a slight chance that the convex hull generator will choke on the inputs.  If so just retry
            {
                try
                {
                    double minRadius = radius * .9d;

                    Point3D[] points = new Point3D[NUMPOINTS];

                    // Make a point cloud
                    for (int cntr = 0; cntr < NUMPOINTS; cntr++)
                    {
                        points[cntr] = Math3D.GetRandomVector_Spherical(minRadius, radius).ToPoint();
                    }

                    // Squash it
                    Transform3DGroup transform = new Transform3DGroup();
                    transform.Children.Add(new ScaleTransform3D(.33d + (rand.NextDouble() * .66d), .33d + (rand.NextDouble() * .66d), 1d)); // squash it
                    transform.Children.Add(new RotateTransform3D(new QuaternionRotation3D(Math3D.GetRandomRotation())));                    // giving it a random rotation, since it's always squashed along the same axiis
                    transform.Transform(points);

                    // Get a hull that wraps those points
                    ITriangleIndexed[] retVal = Math3D.GetConvexHull(points.ToArray());

                    // Get rid of unused points
                    retVal = TriangleIndexed.Clone_CondensePoints(retVal);

                    // Exit Function
                    return(retVal);
                }
                catch (Exception ex)
                {
                    lastException = ex;
                }
            }

            throw new ApplicationException(lastException.ToString());
        }
        private void btnTessellateConcave_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                ClearAllVisuals();

                // Create some random triangles
                Point[][] initialPolys = new Point[5][];

                for (int cntr = 0; cntr < initialPolys.Length; cntr++)
                {
                    Point[] triangle = Enumerable.Range(0, 3).
                        Select(o => Math3D.GetRandomVector_Circular(20d)).
                        Select(o => new Point(o.X, o.Y)).
                        ToArray();

                    initialPolys[cntr] = triangle;
                }

                // Turn into polygons
                Polygon2D[] unionPolys = Math2D.GetUnion_Polygons(initialPolys);

                TriangleIndexed[][] triangulated = new TriangleIndexed[unionPolys.Length][];
                for (int cntr = 0; cntr < unionPolys.Length; cntr++)
                {
                    //http://wiki.unity3d.com/index.php?title=Triangulator

                    Point3D[] poly3D = unionPolys[cntr].Polygon.Select(o => o.ToPoint3D()).ToArray();

                    triangulated[cntr] = Triangulator.Triangulate(unionPolys[cntr].Polygon).
                        Select(o => new TriangleIndexed(o.Item1, o.Item2, o.Item3, poly3D)).
                        ToArray();
                }

                #region Draw

                Visual3D visual;

                // Orig polygons
                foreach (Polygon2D polygon in unionPolys)       // ignoring holes
                {
                    visual = GetVisual_PolygonLines(polygon.Polygon.Select(o => o.ToPoint3D()).ToArray(), Colors.Gray, 2);
                    _debugVisuals.Add(visual);
                    _viewport.Children.Add(visual);
                }

                // Individual triangles
                foreach (TriangleIndexed triangle in triangulated.SelectMany(o => o))
                {
                    visual = GetVisual_Triangle(new ITriangle[] { triangle }, UtilityWPF.GetRandomColor(128, 0, 255));

                    _debugVisuals.Add(visual);
                    _viewport.Children.Add(visual);
                }

                #endregion
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString(), this.Title, MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }
Exemplo n.º 4
0
        private static Tuple <HullVoronoiExploder_Response, bool> SplitHull(ITriangleIndexed[] convexHull, Tuple <Point3D, Vector3D, double>[] shots, HullVoronoiExploder_Options options, double aabbLen)
        {
            #region intersect with the hull

            var hits = shots.
                       Select(o => new HullVoronoiExploder_ShotHit()
            {
                Shot = o,
                Hit  = GetHit(convexHull, o.Item1, o.Item2, o.Item3),
            }).
                       Where(o => o.Hit != null).
                       ToArray();

            if (hits.Length == 0)
            {
                return(null);
            }

            #endregion

            #region voronoi

            Point3D[] controlPoints = GetVoronoiCtrlPoints(hits, convexHull, options.MinCount, options.MaxCount, aabbLen);

            VoronoiResult3D voronoi = Math3D.GetVoronoi(controlPoints, true);
            if (voronoi == null)
            {
                return(null);
            }

            #endregion

            // There is enough to start populating the response
            HullVoronoiExploder_Response retVal = new HullVoronoiExploder_Response()
            {
                Hits          = hits,
                ControlPoints = controlPoints,
                Voronoi       = voronoi,
            };

            #region intersect voronoi and hull

            // Intersect
            Tuple <int, ITriangleIndexed[]>[] shards = null;
            try
            {
                shards = Math3D.GetIntersection_Hull_Voronoi_full(convexHull, voronoi);
            }
            catch (Exception)
            {
                return(Tuple.Create(retVal, false));
            }

            if (shards == null)
            {
                return(Tuple.Create(retVal, false));
            }

            // Smooth
            if (options.ShouldSmoothShards)
            {
                shards = shards.
                         Select(o => Tuple.Create(o.Item1, Asteroid.SmoothTriangles(o.Item2))).
                         ToArray();
            }

            // Validate
            shards = shards.
                     Where(o => o.Item2 != null && o.Item2.Length >= 3).
                     Where(o =>
            {
                Vector3D firstNormal = o.Item2[0].NormalUnit;
                return(o.Item2.Skip(1).Any(p => !Math.Abs(Vector3D.DotProduct(firstNormal, p.NormalUnit)).IsNearValue(1)));
            }).
                     ToArray();

            if (shards.Length == 0)
            {
                return(Tuple.Create(retVal, false));
            }

            #endregion

            #region populate shards

            retVal.Shards = shards.
                            Select(o =>
            {
                var aabb = Math3D.GetAABB(o.Item2);

                double radius = Math.Sqrt((aabb.Item2 - aabb.Item1).Length / 2);

                Point3D center      = Math3D.GetCenter(TriangleIndexed.GetUsedPoints(o.Item2));
                Vector3D centerVect = center.ToVector();

                Point3D[] allPoints = o.Item2[0].AllPoints.
                                      Select(p => p - centerVect).
                                      ToArray();

                TriangleIndexed[] shiftedTriangles = o.Item2.
                                                     Select(p => new TriangleIndexed(p.Index0, p.Index1, p.Index2, allPoints)).
                                                     ToArray();

                return(new HullVoronoiExploder_Shard()
                {
                    VoronoiControlPointIndex = o.Item1,
                    Hull_ParentCoords = o.Item2,
                    Hull_Centered = shiftedTriangles,
                    Radius = radius,
                    Center_ParentCoords = center,
                });
            }).
                            Where(o => o != null).
                            ToArray();

            #endregion

            return(Tuple.Create(retVal, true));
        }
Exemplo n.º 5
0
        public Rhombicuboctahedron(int[][] squarePolys_Orth, int[][] squarePolys_Diag, TriangleIndexed[] triangles, Point3D[] allPoints)
        {
            this.Squares_Orth = Math2D.GetTrianglesFromConvexPoly(squarePolys_Orth, allPoints);
            this.Squares_Diag = Math2D.GetTrianglesFromConvexPoly(squarePolys_Diag, allPoints);
            this.Triangles = triangles;

            this.SquarePolys_Orth = squarePolys_Orth;
            this.SquarePolys_Diag = squarePolys_Diag;

            this.AllPoints = allPoints;

            this.AllTriangles = UtilityCore.Iterate(
                this.Squares_Orth.SelectMany(o => o),
                this.Squares_Diag.SelectMany(o => o),
                triangles
                ).ToArray();
        }
Exemplo n.º 6
0
        private static TriangleIndexed[] GetTrianglesFromMesh_Deduped(MeshGeometry3D[] meshes, Transform3D[] transforms = null)
        {
            #region Points

            // Key=original index
            // Value=new index
            SortedList<int, int> pointMap = new SortedList<int, int>();

            // Points
            List<Point3D> allPointsList = new List<Point3D>();

            int posOffset = 0;

            for (int m = 0; m < meshes.Length; m++)
            {
                Point3D[] positions = meshes[m].Positions.ToArray();

                if (transforms != null && transforms[m] != null)
                {
                    transforms[m].Transform(positions);
                }

                for (int p = 0; p < positions.Length; p++)
                {
                    int dupeIndex = IndexOfDupe(allPointsList, positions[p]);

                    if (dupeIndex < 0)
                    {
                        allPointsList.Add(positions[p]);
                        pointMap.Add(posOffset + p, allPointsList.Count - 1);
                    }
                    else
                    {
                        pointMap.Add(posOffset + p, dupeIndex);
                    }
                }

                posOffset += meshes[m].Positions.Count;
            }

            Point3D[] allPoints = allPointsList.ToArray();

            #endregion

            List<TriangleIndexed> retVal = new List<TriangleIndexed>();

            #region Triangles

            posOffset = 0;

            foreach (MeshGeometry3D mesh in meshes)
            {
                //string report = mesh.ReportGeometry();

                if (mesh.TriangleIndices.Count % 3 != 0)
                {
                    throw new ArgumentException("The mesh's triangle indicies need to be divisible by 3");
                }

                int numTriangles = mesh.TriangleIndices.Count / 3;

                for (int cntr = 0; cntr < numTriangles; cntr++)
                {
                    TriangleIndexed triangle = new TriangleIndexed(
                        pointMap[posOffset + mesh.TriangleIndices[cntr * 3]],
                        pointMap[posOffset + mesh.TriangleIndices[(cntr * 3) + 1]],
                        pointMap[posOffset + mesh.TriangleIndices[(cntr * 3) + 2]],
                        allPoints);

                    double normalLength = triangle.NormalLength;
                    if (!Math1D.IsNearZero(normalLength) && !Math1D.IsInvalid(normalLength))      // don't include bad triangles (the mesh seems to be ok with bad triangles, so just skip them)
                    {
                        retVal.Add(triangle);
                    }
                }

                posOffset += mesh.Positions.Count;
            }

            #endregion

            // Exit Function
            return retVal.ToArray();
        }
Exemplo n.º 7
0
        public static Icosidodecahedron GetIcosidodecahedron(double radius, Transform3D transform = null)
        {
            //NOTE: Don't confuse this with an icosahedron.  That is the more common object (made of equilateral triangles).
            //This object is made of pentagons and triangles.  I'm just making this because it looks cool

            #region Points

            double t = (1d + Math.Sqrt(5d)) / 2d;
            double t2 = t / 2d;
            double t3 = (1d + t) / 2d;

            Point3D[] points = new Point3D[]
            {
                //(0,0,±φ)
                new Point3D(0, 0, t),       // 0
                new Point3D(0, 0, -t),      // 1

                //(0,±φ,0)
                new Point3D(0, t, 0),       // 2
                new Point3D(0, -t, 0),      // 3

                //(±φ,0,0)
                new Point3D(t, 0, 0),       // 4
                new Point3D(-t, 0, 0),      // 5

                //(±1/2, ±φ/2, ±(1+φ)/2)
                new Point3D(.5, t2, t3),        // 6
                new Point3D(.5, t2, -t3),       // 7
                new Point3D(.5, -t2, t3),       // 8
                new Point3D(.5, -t2, -t3),      // 9
                new Point3D(-.5, t2, t3),       // 10
                new Point3D(-.5, t2, -t3),      // 11
                new Point3D(-.5, -t2, t3),      // 12
                new Point3D(-.5, -t2, -t3),     // 13

                //(±φ/2, ±(1+φ)/2, ±1/2)
                new Point3D(t2, t3, .5),        // 14
                new Point3D(t2, t3, -.5),       // 15
                new Point3D(t2, -t3, .5),       // 16
                new Point3D(t2, -t3, -.5),      // 17
                new Point3D(-t2, t3, .5),       // 18
                new Point3D(-t2, t3, -.5),      // 19
                new Point3D(-t2, -t3, .5),      // 20
                new Point3D(-t2, -t3, -.5),     // 21

                //(±(1+φ)/2, ±1/2, ±φ/2)
                new Point3D(t3, .5, t2),        // 22
                new Point3D(t3, .5, -t2),       // 23
                new Point3D(t3, -.5, t2),       // 24
                new Point3D(t3, -.5, -t2),      // 25
                new Point3D(-t3, .5, t2),       // 26
                new Point3D(-t3, .5, -t2),      // 27
                new Point3D(-t3, -.5, t2),      // 28
                new Point3D(-t3, -.5, -t2),     // 29
            };

            double maxLength = points[6].ToVector().Length;     // this represents the longest vector
            double ratio = radius / maxLength;
            points = points.Select(o => (o.ToVector() * ratio).ToPoint()).ToArray();

            if (transform != null)
            {
                points = points.Select(o => transform.Transform(o)).ToArray();
            }

            #endregion

            int[][] pentagonPolys = new int[][]
            {
                new int [] { 0, 10, 26, 28, 12 },
                new int [] { 26, 18, 19, 27, 5 },
                new int [] { 5, 29, 21, 20, 28 },
                new int [] { 10, 6, 14, 2, 18 },
                new int [] { 3, 16, 8, 12, 20 },
                new int [] { 0, 8, 24, 22, 6 },
                new int [] { 9, 17, 3, 21, 13 },
                new int [] { 27, 11, 1, 13, 29 },
                new int [] { 4, 24, 16, 17, 25 },
                new int [] { 1, 7, 23, 25, 9 },
                new int [] { 4, 23, 15, 14, 22 },
                new int [] { 2, 15, 7, 11, 19 },
            };

            TriangleIndexed[] triangles = new TriangleIndexed[]
            {
                new TriangleIndexed(0, 12, 8, points),
                new TriangleIndexed(0, 6, 10, points),
                new TriangleIndexed(10, 18, 26, points),
                new TriangleIndexed(5, 28, 26, points),
                new TriangleIndexed(12, 28, 20, points),
                new TriangleIndexed(3, 20, 21, points),
                new TriangleIndexed(8, 16, 24, points),
                new TriangleIndexed(3, 17, 16, points),
                new TriangleIndexed(9, 25, 17, points),
                new TriangleIndexed(4, 25, 23, points),
                new TriangleIndexed(4, 22, 24, points),
                new TriangleIndexed(13, 21, 29, points),
                new TriangleIndexed(1, 9, 13, points),
                new TriangleIndexed(1, 11, 7, points),
                new TriangleIndexed(11, 27, 19, points),
                new TriangleIndexed(5, 27, 29, points),
                new TriangleIndexed(6, 22, 14, points),
                new TriangleIndexed(2, 14, 15, points),
                new TriangleIndexed(2, 19, 18, points),
                new TriangleIndexed(7, 15, 23, points),
            };

            return new Icosidodecahedron(pentagonPolys, triangles, points);
        }
 public TriangleOverlay(TriangleIndexed triangle, Tuple<int, int, double>[] pixels)
 {
     this.Triangle = triangle;
     this.Pixels = pixels;
 }
Exemplo n.º 9
0
        private void btnPlanes_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                // Clear debug visuals
                foreach (var visual in _debugVisuals)
                {
                    _viewport.Children.Remove(visual);
                }
                _debugVisuals.Clear();

                TriangleIndexed plane1 = new TriangleIndexed(0, 1, 2, new Point3D[] {
                    Math3D.GetRandomVector_Spherical(10).ToPoint(),
                    Math3D.GetRandomVector_Spherical(10).ToPoint(),
                    Math3D.GetRandomVector_Spherical(10).ToPoint() });

                TriangleIndexed plane2 = new TriangleIndexed(0, 1, 2, new Point3D[] {
                    Math3D.GetRandomVector_Spherical(10).ToPoint(),
                    Math3D.GetRandomVector_Spherical(10).ToPoint(),
                    Math3D.GetRandomVector_Spherical(10).ToPoint() });

                // Intersect Line
                Point3D resultPoint;
                Vector3D resultDirection;
                if (Math3D.GetIntersection_Plane_Plane(out resultPoint, out resultDirection, plane1, plane2))
                {
                    ScreenSpaceLines3D gapLine = new ScreenSpaceLines3D(true);
                    gapLine.Color = Colors.White;
                    gapLine.Thickness = 3;
                    gapLine.AddLine(resultPoint, resultPoint + resultDirection * 100);
                    gapLine.AddLine(resultPoint, resultPoint + resultDirection * -100);

                    _debugVisuals.Add(gapLine);
                    _viewport.Children.Add(_debugVisuals[_debugVisuals.Count - 1]);
                }

                MaterialGroup material1 = new MaterialGroup();
                material1.Children.Add(new DiffuseMaterial(new SolidColorBrush(UtilityWPF.ColorFromHex("18FF0000"))));
                material1.Children.Add(new SpecularMaterial(Brushes.Red, 85));

                MaterialGroup material2 = new MaterialGroup();
                material2.Children.Add(new DiffuseMaterial(new SolidColorBrush(UtilityWPF.ColorFromHex("18FFFF00"))));
                material2.Children.Add(new SpecularMaterial(Brushes.Yellow, 85));

                Model3DGroup geometries = new Model3DGroup();

                // Plane 1
                GeometryModel3D geometry = new GeometryModel3D();
                geometry.Material = material1;
                geometry.BackMaterial = material1;
                geometry.Geometry = UtilityWPF.GetSquare2D(100);

                Transform3DGroup transform = new Transform3DGroup();
                transform.Children.Add(new RotateTransform3D(new QuaternionRotation3D(Math3D.GetRotation(new Vector3D(0, 0, 1), plane1.Normal))));
                transform.Children.Add(new TranslateTransform3D(plane1.Point0.ToVector()));
                geometry.Transform = transform;

                geometries.Children.Add(geometry);

                // Plane 2
                geometry = new GeometryModel3D();
                geometry.Material = material1;
                geometry.BackMaterial = material1;
                geometry.Geometry = UtilityWPF.GetSquare2D(100);

                transform = new Transform3DGroup();
                transform.Children.Add(new RotateTransform3D(new QuaternionRotation3D(Math3D.GetRotation(new Vector3D(0, 0, 1), plane2.Normal))));
                transform.Children.Add(new TranslateTransform3D(plane2.Point0.ToVector()));
                geometry.Transform = transform;

                geometries.Children.Add(geometry);

                //// Triangle 1
                //geometry = new GeometryModel3D();
                //geometry.Material = material2;
                //geometry.BackMaterial = material2;
                //geometry.Geometry = UtilityWPF.GetMeshFromTriangles(new TriangleIndexed[] { plane1 });

                //geometries.Children.Add(geometry);

                //// Triangle 2
                //geometry = new GeometryModel3D();
                //geometry.Material = material2;
                //geometry.BackMaterial = material2;
                //geometry.Geometry = UtilityWPF.GetMeshFromTriangles(new TriangleIndexed[] { plane2 });

                //geometries.Children.Add(geometry);

                // Visual
                ModelVisual3D model = new ModelVisual3D();
                model.Content = geometries;

                _debugVisuals.Add(model);
                _viewport.Children.Add(_debugVisuals[_debugVisuals.Count - 1]);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString(), _msgboxCaption, MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }
            private Tuple<IsInsideResult, ITriangle, Point3D> DrawZeroTorqueTestSprtIsInside(TriangleIndexed[] hull, Vector3D opposite)
            {
                if (Math3D.IsInside_Planes(hull, opposite.ToPoint()))
                {
                    return new Tuple<IsInsideResult, ITriangle, Point3D>(IsInsideResult.Inside, null, new Point3D());
                }

                Vector3D[] line = new Vector3D[] { opposite * .001d, opposite * .999d };

                foreach (ITriangle triangle in hull)
                {
                    Vector3D dummy1;
                    double dummy2;
                    Vector3D? intersectionPoint;
                    if (Math3D.IsIntersecting_Polygon2D_Line(new Vector3D[] { triangle.Point0.ToVector(), triangle.Point1.ToVector(), triangle.Point2.ToVector() }, line, 3, out dummy1, out dummy2, out intersectionPoint))
                    {
                        return new Tuple<IsInsideResult, ITriangle, Point3D>(IsInsideResult.Intersects, triangle, intersectionPoint.Value.ToPoint());
                    }
                }

                return new Tuple<IsInsideResult, ITriangle, Point3D>(IsInsideResult.Neither, null, new Point3D());
            }
            private void DrawPossibleHull(TriangleIndexed[] hull, Vector3D offset)
            {
                #region Lines

                ScreenSpaceLines3D lines = new ScreenSpaceLines3D();
                lines.Thickness = 1d;
                lines.Color = UtilityWPF.ColorFromHex("40373403");

                foreach (var triangle in hull)
                {
                    lines.AddLine(triangle.Point0 + offset, triangle.Point1 + offset);
                    lines.AddLine(triangle.Point0 + offset, triangle.Point2 + offset);
                    lines.AddLine(triangle.Point1 + offset, triangle.Point2 + offset);
                }

                _visuals.Add(lines);
                _viewport.Children.Add(lines);

                #endregion

                #region Hull

                // Material
                MaterialGroup materials = new MaterialGroup();
                materials.Children.Add(new DiffuseMaterial(new SolidColorBrush(UtilityWPF.ColorFromHex(HULL_COLOR))));
                materials.Children.Add(new SpecularMaterial(new SolidColorBrush(UtilityWPF.ColorFromHex(HULL_SPECULAR)), HULL_SPECULAR_INTENSITY));

                // Geometry Model
                GeometryModel3D geometry = new GeometryModel3D();
                geometry.Material = materials;
                geometry.BackMaterial = materials;
                geometry.Geometry = UtilityWPF.GetMeshFromTriangles_IndependentFaces(hull);

                ModelVisual3D model = new ModelVisual3D();
                model.Content = geometry;
                model.Transform = new TranslateTransform3D(offset);

                _visuals.Add(model);
                _viewport.Children.Add(model);

                #endregion
            }
 public HullLineResult(TriangleIndexed[] hull, Vector3D intersectTest, IsInsideResult isInside, ITriangle intersectingTriangle, Point3D intersectingPoint)
 {
     this.Hull = hull;
     this.IntersectTest = intersectTest;
     this.IsInside = isInside;
     this.IntersectingTriangle = intersectingTriangle;
     this.IntersectingPoint = intersectingPoint;
 }
Exemplo n.º 13
0
            /// <summary>
            /// This returns all the unique edge triangles of the cells passed in (each face of the cell cube has two triangles), and which
            /// cells share each of those triangles
            /// </summary>
            private static Tuple<ITriangle, int[]>[] GetBlockedCellsSprtEdgeMap(Rectangle3DIndexedMapped[] cells)
            {
                if (cells.Length == 0)
                {
                    return new Tuple<ITriangle, int[]>[0];
                }

                // Get the triangles for each cell
                List<Tuple<int, Tuple<int, int, int>>> trianglesPerCell = new List<Tuple<int, Tuple<int, int, int>>>();

                for (int cntr = 0; cntr < cells.Length; cntr++)
                {
                    Tuple<int, int, int>[] trianglesOrdered = cells[cntr].GetEdgeTriangles().Select(o =>
                    {
                        int[] indices = o.IndexArray.OrderBy(p => p).ToArray();     // sorting them so they can be easily compared to other cell's triangles
                        return Tuple.Create(indices[0], indices[1], indices[2]);
                    }).
                    ToArray();

                    trianglesPerCell.AddRange(trianglesOrdered.Select(o => Tuple.Create(cntr, o)));
                }

                Point3D[] points = cells[0].AllPoints;

                // Now group by triangle
                var retVal = trianglesPerCell.GroupBy(o => o.Item2).
                    Select(o =>
                    {
                        ITriangle triangle = new TriangleIndexed(o.Key.Item1, o.Key.Item2, o.Key.Item3, points);

                        int[] correspondingCells = o.Select(p => p.Item1).Distinct().ToArray();

                        return Tuple.Create(triangle, correspondingCells);
                    }).
                    ToArray();

                // Exit Function
                return retVal;
            }
Exemplo n.º 14
0
        private static Model3D[] CreateIcons_Translate(double lineRadius, double lineThickness, double arrowThickness, double sphereRadius)
        {
            #region define points

            Vector[] cores1 = new[]
            {
                new Vector(1, 0),
                new Vector(0, 1),
                new Vector(-1, 0),
                new Vector(0, -1),
            };

            var cores2 = cores1.
                         Select(o =>
                                (
                                    o * lineThickness / 2,
                                    o * lineRadius * 2d / 3d,
                                    o * lineRadius
                                )).
                         ToArray();

            var lines = cores2.
                        Select(o => new
            {
                from = Math3D.ProjectPointOntoSphere(o.Item1.X, o.Item1.Y, sphereRadius),
                to   = Math3D.ProjectPointOntoSphere(o.Item2.X, o.Item2.Y, sphereRadius),
                tip  = Math3D.ProjectPointOntoSphere(o.Item3.X, o.Item3.Y, sphereRadius),
                bar  = GetLinePoints(o.Item1, o.Item2, lineThickness, arrowThickness, sphereRadius),
            }).
                        ToArray();

            Point3D origin = Math3D.ProjectPointOntoSphere(0, 0, sphereRadius);

            #endregion
            #region create triangles

            List <Triangle> triangles = new List <Triangle>();

            foreach (var line in lines)
            {
                triangles.Add(new Triangle(origin, line.bar.fromRight, line.bar.fromLeft));

                triangles.Add(new Triangle(line.bar.fromLeft, line.bar.fromRight, line.bar.toRight));
                triangles.Add(new Triangle(line.bar.toRight, line.bar.toLeft, line.bar.fromLeft));

                triangles.Add(new Triangle(line.bar.baseLeft, line.bar.toLeft, line.tip));
                triangles.Add(new Triangle(line.bar.toLeft, line.bar.toRight, line.tip));
                triangles.Add(new Triangle(line.bar.toRight, line.bar.baseRight, line.tip));
            }

            ITriangleIndexed[] indexedTriangles = TriangleIndexed.ConvertToIndexed(triangles.ToArray());

            #endregion

            List <Model3D> retVal = new List <Model3D>();

            MaterialGroup material = new MaterialGroup();
            material.Children.Add(new DiffuseMaterial(new SolidColorBrush(WorldColors.ImpulseEngine_Icon_Color)));
            material.Children.Add(WorldColors.ImpulseEngine_Icon_Specular);
            material.Children.Add(WorldColors.ImpulseEngine_Icon_Emissive);

            foreach (Transform3D transform in GetRotations_Tetrahedron(sphereRadius))
            {
                GeometryModel3D geometry = new GeometryModel3D();
                geometry.Material     = material;
                geometry.BackMaterial = material;
                geometry.Geometry     = UtilityWPF.GetMeshFromTriangles(indexedTriangles);
                geometry.Transform    = transform;

                retVal.Add(geometry);
            }

            return(retVal.ToArray());
        }
Exemplo n.º 15
0
        private void ShadowMultiStepSprtFinish(Point3D cameraPos, Vector3D cameraLook, TriangleIndexed[] triangles)
        {
            // Order by distance to plane
            ITriangleIndexed[] sorted = Math3D.SortByPlaneDistance(triangles, cameraPos, cameraLook);

            SortedList<int, List<Point3D[]>> clipPolygons = new SortedList<int, List<Point3D[]>>();

            Vector3D hullDepth = cameraLook.ToUnit() * 50d;

            //for (int outer = 0; outer < sorted.Length - 1; outer++)
            for (int outer = 0; outer < sorted.Length; outer++)
            {
                // Create a volume out of the this triangle
                ITriangleIndexed[] hull = GetHullFromTriangle(sorted[outer], hullDepth);

                if (hull != null && hull.Length > 6)        // if the triangle is super thin, then a 2D hull will be created
                {
                    //for (int inner = outer + 1; inner < sorted.Length; inner++)
                    for (int inner = 0; inner < sorted.Length; inner++)
                    {
                        if (outer == inner)
                        {
                            continue;
                        }

                        Point3D[] poly = HullTriangleIntersect2.GetIntersection_Hull_Triangle(hull, sorted[inner]);
                        if (poly != null)
                        {
                            if (!clipPolygons.ContainsKey(inner))
                            {
                                clipPolygons.Add(inner, new List<Point3D[]>());
                            }

                            clipPolygons[inner].Add(poly);
                        }
                    }
                }
            }

            double[] percents = new double[sorted.Length];
            for (int cntr = 0; cntr < sorted.Length; cntr++)
            {
                if (clipPolygons.ContainsKey(cntr))
                {
                    percents[cntr] = GetPercentVisible(new Point3D[] { sorted[cntr].Point0, sorted[cntr].Point1, sorted[cntr].Point2 }, clipPolygons[cntr].ToArray());
                }
                else
                {
                    percents[cntr] = 1d;
                }
            }

            #region Draw

            Visual3D visual;
            Color color;

            // % in shadow
            for (int cntr = 0; cntr < sorted.Length; cntr++)
            {
                color = UtilityWPF.AlphaBlend(Colors.White, Colors.Black, percents[cntr]);

                visual = GetVisual_PolygonLines(new Point3D[] { sorted[cntr].Point0, sorted[cntr].Point1, sorted[cntr].Point2 }, color, 2d);
                _debugVisuals.Add(visual);
                _viewport.Children.Add(visual);
            }

            // Clip polygons
            foreach (Point3D[] polygon in clipPolygons.Values.SelectMany(o => o))
            {
                visual = GetVisual_PolygonHull(polygon, Colors.DodgerBlue, .005);
                _debugVisuals.Add(visual);
                _viewport.Children.Add(visual);
            }

            // Triangles
            color = UtilityWPF.ColorFromHex("50E0E0E0");

            for (int cntr = 0; cntr < sorted.Length; cntr++)
            {
                visual = GetVisual_Triangle(new ITriangle[] { sorted[cntr] }, color);
                _debugVisuals.Add(visual);
                _viewport.Children.Add(visual);
            }


            //// Draw the plane
            //visual = GetTriangleVisual(GetPlane(_camera.Position, _camera.LookDirection, 60), UtilityWPF.ColorFromHex("20B0B0B0"));
            //_debugVisuals.Add(visual);
            //_viewport.Children.Add(visual);

            #endregion



        }
Exemplo n.º 16
0
        private void btnPlaneTiles3D_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                PrepFor3D();
                ClearAllVisuals();

                TriangleIndexed plane = new TriangleIndexed(0, 1, 2, new[] { Math3D.GetRandomVector_Spherical(HALFSIZE3D).ToPoint(), Math3D.GetRandomVector_Spherical(HALFSIZE3D).ToPoint(), Math3D.GetRandomVector_Spherical(HALFSIZE3D).ToPoint() });

                // Draw the triangle
                _misc3D.Add(new Item3D(AddLines(_viewportFull, new[] { Tuple.Create(0, 1), Tuple.Create(1, 2), Tuple.Create(2, 0) }, plane.AllPoints, Colors.ForestGreen)));

                // Draw the plane
                ModelVisual3D visual = new ModelVisual3D();
                visual.Content = UtilityWPF.GetPlane(plane, HALFSIZE3D * 2, UtilityWPF.ColorFromHex("555548"), UtilityWPF.ColorFromHex("8F8E3C"));

                _viewportFull.Children.Add(visual);
                _misc3D.Add(new Item3D(visual));
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString(), this.Title, MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }
Exemplo n.º 17
0
        private static ITriangle[] GetPlane(Point3D point, Vector3D normal, double size)
        {
            double halfSize = size / 2d;

            Vector3D orth1 = Math3D.GetArbitraryOrhonganal(normal).ToUnit() * halfSize;
            Vector3D orth2 = Vector3D.CrossProduct(orth1, normal).ToUnit() * halfSize;

            Point3D[] points = new Point3D[4];
            points[0] = point - orth1 - orth2;
            points[1] = point + orth1 - orth2;
            points[2] = point + orth1 + orth2;
            points[3] = point - orth1 + orth2;

            ITriangle[] retVal = new ITriangle[2];
            retVal[0] = new TriangleIndexed(0, 1, 2, points);
            retVal[1] = new TriangleIndexed(2, 3, 0, points);

            return retVal;
        }
Exemplo n.º 18
0
            private static LinkBrain2D[] PruneBrainLinks(TriangleIndexed[] triangles, SortedList<Tuple<int, int>, double> all, Item2D[] brains)
            {
                List<Tuple<int[], int[]>> retVal = all.Keys.
                    Select(o => Tuple.Create(new[] { o.Item1 }, new[] { o.Item2 })).
                    ToList();

                foreach (TriangleIndexed triangle in triangles)
                {
                    Tuple<bool, TriangleEdge> changeEdge = PruneBrainLinks_LongThin(triangle, all);
                    if (changeEdge == null)
                    {
                        continue;
                    }

                    if (changeEdge.Item1)
                    {
                        PruneBrainLinks_Merge(triangle, changeEdge.Item2, retVal);
                    }
                    else
                    {
                        PruneBrainLinks_Remove(triangle, changeEdge.Item2, retVal);
                    }
                }

                return retVal.Select(o => new LinkBrain2D(o.Item1, o.Item2, brains)).ToArray();
            }
Exemplo n.º 19
0
        public static Rhombicuboctahedron GetRhombicuboctahedron(double sizeX, double sizeY, double sizeZ, Transform3D transform = null)
        {
            #region Points

            double hX = sizeX / 2d;
            double hY = sizeY / 2d;
            double hZ = sizeZ / 2d;

            double sqrt2_1 = Math.Sqrt(2) + 1d;
            double sX = (sizeX / sqrt2_1) / 2d;     // sX is half the width of one of the faces (the faces form an octogon)
            double sY = (sizeY / sqrt2_1) / 2d;
            double sZ = (sizeZ / sqrt2_1) / 2d;

            // Points
            Point3D[] points = new Point3D[]
            {
                // Top 4
                new Point3D(sX, sY, hZ),        // 0
                new Point3D(sX, -sY, hZ),       // 1
                new Point3D(-sX, -sY, hZ),      // 2
                new Point3D(-sX, sY, hZ),      // 3

                // Top 8
                new Point3D(hX, sY, sZ),        // 4
                new Point3D(hX, -sY, sZ),       // 5
                new Point3D(sX, -hY, sZ),       // 6
                new Point3D(-sX, -hY, sZ),      // 7
                new Point3D(-hX, -sY, sZ),      // 8
                new Point3D(-hX, sY, sZ),       // 9
                new Point3D(-sX, hY, sZ),       // 10
                new Point3D(sX, hY, sZ),        // 11

                // Bottom 8
                new Point3D(hX, sY, -sZ),       // 12
                new Point3D(hX, -sY, -sZ),      // 13
                new Point3D(sX, -hY, -sZ),      // 14
                new Point3D(-sX, -hY, -sZ),     // 15
                new Point3D(-hX, -sY, -sZ),     // 16
                new Point3D(-hX, sY, -sZ),      // 17
                new Point3D(-sX, hY, -sZ),      // 18
                new Point3D(sX, hY, -sZ),       // 19

                // Bottom 4
                new Point3D(sX, sY, -hZ),       // 20
                new Point3D(sX, -sY, -hZ),      // 21
                new Point3D(-sX, -sY, -hZ),     // 22
                new Point3D(-sX, sY, -hZ),     // 23
            };

            if (transform != null)
            {
                points = points.Select(o => transform.Transform(o)).ToArray();
            }

            #endregion

            int[][] squarePolys_Orth = new int[][]
            {
                new int[] { 0, 3, 2, 1 },       // Top
                new int[] { 4, 5, 13, 12 },     // Right
                new int[] { 6, 7, 15, 14 },     // Front
                new int[] { 8, 9, 17, 16 },     // Left
                new int[] { 10, 11, 19, 18 },       // Back
                new int[] { 20, 21, 22, 23 },       // Bottom
            };

            int[][] squarePolys_Diag = new int[][]
            {
                // Top 4 angled
                new int[] {0, 1, 5, 4 },
                new int[] { 1, 2, 7, 6 },
                new int[] { 2, 3, 9, 8 },
                new int[] { 0, 11, 10, 3 },

                // Middle 4 angled
                new int[] { 4, 12, 19, 11 },
                new int[] { 5, 6, 14, 13 },
                new int[] { 7, 8, 16, 15 },
                new int[] { 9, 10, 18, 17 },

                // Bottom 4 angled
                new int[] { 12, 13, 21, 20 },
                new int[] { 14, 15, 22, 21 },
                new int[] { 16, 17, 23, 22 },
                new int[] { 18, 19, 20, 23 },
            };

            TriangleIndexed[] triangles = new TriangleIndexed[]
            {
                // Top 4
                new TriangleIndexed(0, 4, 11, points),
                new TriangleIndexed(1, 6, 5, points),
                new TriangleIndexed(2, 8, 7, points),
                new TriangleIndexed(3, 10, 9, points),

                // Bottom 4
                new TriangleIndexed(12, 20, 19, points),
                new TriangleIndexed(13, 14, 21, points),
                new TriangleIndexed(15, 16, 22, points),
                new TriangleIndexed(17, 18, 23, points),
            };

            return new Rhombicuboctahedron(squarePolys_Orth, squarePolys_Diag, triangles, points);
        }
Exemplo n.º 20
0
            private static void PruneBrainLinks_Merge(TriangleIndexed triangle, TriangleEdge edge, List<Tuple<int[], int[]>> links)
            {
                // Figure out which indexes to look for
                int[] pair = new[] { triangle.GetIndex(edge, true), triangle.GetIndex(edge, false) };
                int other = triangle.IndexArray.First(o => !pair.Contains(o));

                // Extract the affected links out of the list
                List<Tuple<int[], int[]>> affected = new List<Tuple<int[], int[]>>();

                int index = 0;
                while (index < links.Count)
                {
                    var current = links[index];

                    if (current.Item1.Contains(other) && current.Item2.Any(o => pair.Contains(o)))
                    {
                        affected.Add(current);
                        links.RemoveAt(index);
                    }
                    else if (current.Item2.Contains(other) && current.Item1.Any(o => pair.Contains(o)))
                    {
                        affected.Add(Tuple.Create(current.Item2, current.Item1));       // reversing them so that Item1 is always other
                        links.RemoveAt(index);
                    }
                    else
                    {
                        index++;
                    }
                }

                // Combine the affected links (there shouldn't be more than two)
                var merged = Tuple.Create(
                    affected.SelectMany(o => o.Item1).Distinct().ToArray(),
                    affected.SelectMany(o => o.Item2).Distinct().ToArray());

                links.Add(merged);
            }
Exemplo n.º 21
0
        // For speed reasons, the code was duplicated
        private static TriangleIndexed[] GetTrianglesFromMesh_Raw(MeshGeometry3D[] meshes, Transform3D[] transforms = null)
        {
            #region Points

            List<Point3D> allPointsList = new List<Point3D>();

            for (int cntr = 0; cntr < meshes.Length; cntr++)
            {
                Point3D[] positions = meshes[cntr].Positions.ToArray();

                if (transforms != null && transforms[cntr] != null)
                {
                    transforms[cntr].Transform(positions);
                }

                allPointsList.AddRange(positions);
            }

            Point3D[] allPoints = allPointsList.ToArray();

            #endregion

            List<TriangleIndexed> retVal = new List<TriangleIndexed>();

            #region Triangles

            int posOffset = 0;

            foreach (MeshGeometry3D mesh in meshes)
            {
                //string report = mesh.ReportGeometry();

                if (mesh.TriangleIndices.Count % 3 != 0)
                {
                    throw new ArgumentException("The mesh's triangle indicies need to be divisible by 3");
                }

                int numTriangles = mesh.TriangleIndices.Count / 3;

                for (int cntr = 0; cntr < numTriangles; cntr++)
                {
                    TriangleIndexed triangle = new TriangleIndexed(
                        posOffset + mesh.TriangleIndices[cntr * 3],
                        posOffset + mesh.TriangleIndices[(cntr * 3) + 1],
                        posOffset + mesh.TriangleIndices[(cntr * 3) + 2],
                        allPoints);

                    double normalLength = triangle.NormalLength;
                    if (!Math1D.IsNearZero(normalLength) && !Math1D.IsInvalid(normalLength))      // don't include bad triangles (the mesh seems to be ok with bad triangles, so just skip them)
                    {
                        retVal.Add(triangle);
                    }
                }

                posOffset += mesh.Positions.Count;
            }

            #endregion

            // Exit Function
            return retVal.ToArray();
        }
Exemplo n.º 22
0
            private static void PruneBrainLinks_Remove(TriangleIndexed triangle, TriangleEdge edge, List<Tuple<int[], int[]>> links)
            {
                int index1 = triangle.GetIndex(edge, true);
                int index2 = triangle.GetIndex(edge, false);

                Tuple<int[], int[]> existing = null;
                bool? is1in1 = null;

                // Find and remove the link that contains this edge
                for (int cntr = 0; cntr < links.Count; cntr++)
                {
                    if (links[cntr].Item1.Contains(index1) && links[cntr].Item2.Contains(index2))
                    {
                        is1in1 = true;
                    }
                    else if (links[cntr].Item1.Contains(index2) && links[cntr].Item2.Contains(index1))
                    {
                        is1in1 = false;
                    }
                    else
                    {
                        continue;
                    }

                    existing = links[cntr];
                    links.RemoveAt(cntr);
                    break;
                }

                if (existing == null)
                {
                    //throw new ArgumentException("Didn't find the link");

                    // A neighbor triangle probably removed it
                    return;
                }

                // Add back if there were more than 2 involved
                if (existing.Item1.Length == 1 && existing.Item2.Length == 1)
                {
                    // This link only holds one item on each side.  It's already removed from the list, so there is nothing left to do
                    return;
                }

                int[] newItem1 = PruneBrainLinks_Remove_Reduce(existing.Item1, index1, index2, is1in1.Value);
                int[] newItem2 = PruneBrainLinks_Remove_Reduce(existing.Item2, index2, index1, is1in1.Value);

                links.Add(Tuple.Create(newItem1, newItem2));
            }
Exemplo n.º 23
0
        private static TriangleIndexed[] GetIcosahedron_Recurse(TriangleIndexed[] hull, double radius)
        {
            Point3D[] parentPoints = hull[0].AllPoints;

            SortedList<Tuple<int, int>, Tuple<int, Point3D>> childPoints = new SortedList<Tuple<int, int>, Tuple<int, Point3D>>();
            List<Tuple<int, int, int>> childFaces = new List<Tuple<int, int, int>>();

            // Cut each parent triangle into 4
            foreach (TriangleIndexed face in hull)
            {
                // Get the middle of each edge (the point between the two verticies, then extended to touch the sphere)
                int m01 = GetIcosahedron_MidPoint(face.Index0, face.Index1, parentPoints, radius, childPoints);
                int m12 = GetIcosahedron_MidPoint(face.Index1, face.Index2, parentPoints, radius, childPoints);
                int m20 = GetIcosahedron_MidPoint(face.Index2, face.Index0, parentPoints, radius, childPoints);

                // Turn those into triangles
                childFaces.Add(Tuple.Create(face.Index0, m01, m20));
                childFaces.Add(Tuple.Create(face.Index1, m12, m01));
                childFaces.Add(Tuple.Create(face.Index2, m20, m12));
                childFaces.Add(Tuple.Create(m01, m12, m20));
            }

            // Combine the points
            Point3D[] childPointsFinal = childPoints.Values.OrderBy(o => o.Item1).Select(o => o.Item2).ToArray();
            Point3D[] allNewPoints = UtilityCore.ArrayAdd(parentPoints, childPointsFinal);

            // Build the triangles
            return childFaces.Select(o => new TriangleIndexed(o.Item1, o.Item2, o.Item3, allNewPoints)).ToArray();
        }
Exemplo n.º 24
0
 public TriangleOverlay(TriangleIndexed triangle, Tuple <int, int, double>[] pixels)
 {
     this.Triangle = triangle;
     this.Pixels   = pixels;
 }
Exemplo n.º 25
0
        public Icosidodecahedron(int[][] pentagonPolys, TriangleIndexed[] triangles, Point3D[] allPoints)
        {
            this.Pentagons = Math2D.GetTrianglesFromConvexPoly(pentagonPolys, allPoints);
            this.Triangles = triangles;

            this.PentagonPolys = pentagonPolys;

            this.AllPoints = allPoints;

            this.AllTriangles = UtilityCore.Iterate(this.Pentagons.SelectMany(o => o), triangles).ToArray();
        }
Exemplo n.º 26
0
        private void btnShadowFixed6_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                ClearAllVisuals();

                Triangle triangle = new Triangle(new Point3D(-2.39, -3.17, 12.44), new Point3D(-0.44, 1.28, 12.15), new Point3D(-4.24, 3.63, 9.62));

                Point3D[] allPoints = new Point3D[6];
                allPoints[0] = new Point3D(3.35, -1.07, 14.69);
                allPoints[1] = new Point3D(-0.44, 1.28, 12.15);
                allPoints[2] = new Point3D(-2.39, -3.17, 12.44);
                allPoints[3] = new Point3D(3.35, -1.07, -35.31);
                allPoints[4] = new Point3D(-0.44, 1.28, -37.85);
                allPoints[5] = new Point3D(-2.39, -3.17, -37.56);

                TriangleIndexed[] hull = new TriangleIndexed[1];
                hull[0] = new TriangleIndexed(1, 2, 0, allPoints);
                //hull[1] = new TriangleIndexed(3, 4, 1, allPoints);
                //hull[2] = new TriangleIndexed(3, 1, 0, allPoints);
                //hull[3] = new TriangleIndexed(5, 0, 2, allPoints);
                //hull[4] = new TriangleIndexed(5, 2, 1, allPoints);
                //hull[5] = new TriangleIndexed(5, 3, 0, allPoints);
                //hull[6] = new TriangleIndexed(5, 1, 4, allPoints);
                //hull[7] = new TriangleIndexed(5, 4, 3, allPoints);

                Point3D[] clipPolygon = HullTriangleIntersect2.GetIntersection_Hull_Triangle(hull, triangle);
                //Point3D[] clipPolygon = null;

                #region Draw

                Visual3D visual;

                // Dots
                double dotRadius = .05d;

                visual = GetVisual_Dot(new Point3D(3.34828755135393, -1.07062650560222, 14.6744119439448), dotRadius, Colors.Black);
                _debugVisuals.Add(visual);
                _viewport.Children.Add(visual);

                visual = GetVisual_Dot(new Point3D(3.35, -1.07, 14.6750787484006), dotRadius, Colors.White);
                _debugVisuals.Add(visual);
                _viewport.Children.Add(visual);

                visual = GetVisual_Dot(new Point3D(-2.39, -3.17, 12.44), dotRadius, Colors.Green);
                _debugVisuals.Add(visual);
                _viewport.Children.Add(visual);

                visual = GetVisual_Dot(new Point3D(-0.548204828380986, 1.03307103266903, 12.1660920001182), dotRadius, Colors.Yellow);
                _debugVisuals.Add(visual);
                _viewport.Children.Add(visual);


                // Clip polygons
                if (clipPolygon != null)
                {
                    visual = GetVisual_PolygonHull(clipPolygon, Colors.DodgerBlue, .005);
                    _debugVisuals.Add(visual);
                    _viewport.Children.Add(visual);
                }


                // Shadow hull

                Color color = UtilityWPF.AlphaBlend(Colors.Transparent, Colors.DodgerBlue, .85d);

                // Material
                MaterialGroup materials = new MaterialGroup();
                materials.Children.Add(new DiffuseMaterial(new SolidColorBrush(color)));
                materials.Children.Add(new SpecularMaterial(new SolidColorBrush(UtilityWPF.AlphaBlend(Colors.White, color, .5d)), 30d));

                // Geometry Model
                GeometryModel3D geometry = new GeometryModel3D();
                geometry.Material = materials;
                geometry.BackMaterial = materials;
                geometry.Geometry = UtilityWPF.GetMeshFromTriangles(hull.ToArray());

                ModelVisual3D modelVisual = new ModelVisual3D();
                modelVisual.Content = geometry;

                visual = modelVisual;

                _debugVisuals.Add(visual);
                _viewport.Children.Add(visual);


                // Triangle
                color = UtilityWPF.ColorFromHex("50E0E0E0");

                visual = GetVisual_Triangle(new ITriangle[] { triangle }, color);
                _debugVisuals.Add(visual);
                _viewport.Children.Add(visual);


                //// Draw the plane
                //visual = GetTriangleVisual(GetPlane(_camera.Position, _camera.LookDirection, 60), UtilityWPF.ColorFromHex("20B0B0B0"));
                //_debugVisuals.Add(visual);
                //_viewport.Children.Add(visual);

                #endregion
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString(), this.Title, MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }
Exemplo n.º 27
0
        private static GeometryModel3D GetModel_WoodIron_Ring_Band(double ballRadius, double z, System.Windows.Media.Media3D.Material material, TriangleIndexed[] ball, SortedList<string, double> from, SortedList<string, double> to, string prefix)
        {
            const double ENLARGE = 1.04d;

            GeometryModel3D retVal = new GeometryModel3D();

            retVal.Material = material;
            retVal.BackMaterial = material;

            double bandHeight = WeaponDNA.GetKeyValue(prefix + "Height", from, to, StaticRandom.NextPercent(ballRadius * .15, .5));
            double bandHeightHalf = bandHeight / 2d;

            // Slice the hull at the top and bottom band z's
            Point3D[] slice1 = Math3D.GetIntersection_Hull_Plane(ball, new Triangle(new Point3D(0, 0, z - bandHeightHalf), new Point3D(1, 0, z - bandHeightHalf), new Point3D(0, 1, z - bandHeightHalf)));
            Point3D[] slice2 = Math3D.GetIntersection_Hull_Plane(ball, new Triangle(new Point3D(0, 0, z + bandHeightHalf), new Point3D(1, 0, z + bandHeightHalf), new Point3D(0, 1, z + bandHeightHalf)));

            // Enlarge those polygons xy, leave z alone
            slice1 = slice1.Select(o => new Point3D(o.X * ENLARGE, o.Y * ENLARGE, o.Z)).ToArray();
            slice2 = slice2.Select(o => new Point3D(o.X * ENLARGE, o.Y * ENLARGE, o.Z)).ToArray();

            // Now turn those two polygons into a 3d hull
            TriangleIndexed[] band = Math3D.GetConvexHull(UtilityCore.Iterate(slice1, slice2).ToArray());

            retVal.Geometry = UtilityWPF.GetMeshFromTriangles(band);

            return retVal;
        }
Exemplo n.º 28
0
        private static void GetItemDelaunay(out SortedList<Tuple<int, int>, double> segments, out TriangleIndexed[] triangles, LinkItem[] items)
        {
            Tuple<int, int>[] links = null;

            if (items.Length < 2)
            {
                links = new Tuple<int, int>[0];
                triangles = new TriangleIndexed[0];
            }
            else if (items.Length == 2)
            {
                links = new[] { Tuple.Create(0, 1) };
                triangles = new TriangleIndexed[0];
            }
            else if (items.Length == 3)
            {
                links = new[] 
                    {
                        Tuple.Create(0, 1),
                        Tuple.Create(0, 2),
                        Tuple.Create(1, 2),
                    };

                triangles = new[] { new TriangleIndexed(0, 1, 2, items.Select(o => o.Position).ToArray()) };
            }
            else
            {
                Tetrahedron[] tetras = Math3D.GetDelaunay(items.Select(o => o.Position).ToArray());
                links = Tetrahedron.GetUniqueLines(tetras);
                triangles = Tetrahedron.GetUniqueTriangles(tetras);
            }

            segments = GetLengths(links, items);
        }