示例#1
0
        /// <summary>
        /// Linear interpolation of a scalar value.
        /// </summary>
        /// <param name="p">The interpolation point.</param>
        /// <param name="triangle">The triangle containing the point.</param>
        /// <remarks>
        /// The point is expected to lie inside the triangle.
        /// </remarks>
        public static void InterpolateZ(Point p, ITriangle triangle)
        {
            Vertex org = triangle.GetVertex(0);
            Vertex dest = triangle.GetVertex(1);
            Vertex apex = triangle.GetVertex(2);

            double xdo, ydo, xao, yao;
            double denominator;
            double dx, dy;
            double xi, eta;

            // Compute the circumcenter of the triangle.
            xdo = dest.x - org.x;
            ydo = dest.y - org.y;
            xao = apex.x - org.x;
            yao = apex.y - org.y;

            denominator = 0.5 / (xdo * yao - xao * ydo);

            //dx = (yao * dodist - ydo * aodist) * denominator;
            //dy = (xdo * aodist - xao * dodist) * denominator;

            dx = p.x - org.x;
            dy = p.y - org.y;

            // To interpolate z value for the given point inserted, define a
            // coordinate system with a xi-axis, directed from the triangle's
            // origin to its destination, and an eta-axis, directed from its
            // origin to its apex.
            xi = (yao * dx - xao * dy) * (2.0 * denominator);
            eta = (xdo * dy - ydo * dx) * (2.0 * denominator);

            p.z = org.z + xi * (dest.z - org.z) + eta * (apex.z - org.z);
        }
        public void SetTriangle(ITriangle tri)
        {
            if (tri != null)
            {
                lbTriangle.Text = tri.ID.ToString();

                lbV0.Text = tri.GetVertexID(0).ToString();
                lbV1.Text = tri.GetVertexID(1).ToString();
                lbV2.Text = tri.GetVertexID(2).ToString();

                lbN0.Text = tri.GetNeighborID(0).ToString();
                lbN1.Text = tri.GetNeighborID(1).ToString();
                lbN2.Text = tri.GetNeighborID(2).ToString();

                lbS0.Text = GetSegmentString(tri.GetSegment(0));
                lbS1.Text = GetSegmentString(tri.GetSegment(1));
                lbS2.Text = GetSegmentString(tri.GetSegment(2));
            }
            else
            {
                lbTriangle.Text = "-";

                lbV0.Text = "-";
                lbV1.Text = "-";
                lbV2.Text = "-";

                lbN0.Text = "-";
                lbN1.Text = "-";
                lbN2.Text = "-";

                lbS0.Text = "-";
                lbS1.Text = "-";
                lbS2.Text = "-";
            }
        }
        // überprüft, ob ein Strahl ein Dreieck schneidet
        protected float? FindIntersection(Ray ray, ITriangle triangle)
        {
            // überprüfen, ob der Strahl die vom Dreieck aufgespannte Ebene schneidet
            float? f = ray.Intersects(new Plane(triangle.P0, triangle.P1, triangle.P2));

            // wenn ja, überprüfen ob Schnittpunkt im Dreieck liegt
            if (f != null && IsInsideTriangle(triangle, ray.Position + ray.Direction * f.Value))
                return f;

            return null;
        }
        // überprüft, ob ein Punkt in einem Dreieck liegt
        private bool IsInsideTriangle(ITriangle triangle, Vector3 p)
        {
            Vector3[] t = new Vector3[] { triangle.P0, triangle.P1, triangle.P2 };

            // Up-Vektor des Dreiecks mit Cross-Product berechnen
            Vector3 n = Vector3.Normalize(Vector3.Cross(t[1] - t[0], t[2] - t[0]));

            // für alle Seiten des Dreiecks
            for (int i = 0; i < 3; i++)
            {
                // wenn Punkt außerhalb liegt, Überprüfung beenden
                if (Vector3.Dot(Vector3.Normalize(Vector3.Cross(t[i] - p, t[(i + 1) % 3] - p)), n) < 0.0f)
                    return false;
            }

            return true;
        }
示例#5
0
        /// <summary>
        /// Reconstruct a triangulation from its raw data representation.
        /// </summary>
        public static Mesh ToMesh(Polygon polygon, ITriangle[] triangles)
        {
            Otri tri = default(Otri);
            Osub subseg = default(Osub);
            int i = 0;

            int elements = triangles == null ? 0 : triangles.Length;
            int segments = polygon.Segments.Count;

            // TODO: Configuration should be a function argument.
            var mesh = new Mesh(new Configuration());

            mesh.TransferNodes(polygon.Points);

            mesh.regions.AddRange(polygon.Regions);
            mesh.behavior.useRegions = polygon.Regions.Count > 0;

            if (polygon.Segments.Count > 0)
            {
                mesh.behavior.Poly = true;
                mesh.holes.AddRange(polygon.Holes);
            }

            // Create the triangles.
            for (i = 0; i < elements; i++)
            {
                mesh.MakeTriangle(ref tri);
            }

            if (mesh.behavior.Poly)
            {
                mesh.insegments = segments;

                // Create the subsegments.
                for (i = 0; i < segments; i++)
                {
                    mesh.MakeSegment(ref subseg);
                }
            }

            var vertexarray = SetNeighbors(mesh, triangles);

            SetSegments(mesh, polygon, vertexarray);

            return mesh;
        }
            //NOTE: This can return null
            public static Point3D[] GetIntersection(ITriangleIndexed[] hull, ITriangle triangle)
            {
                //TODO: It's possible that the test triangle is touching the hull, but not really intersecting with it.  If that happens, then only
                // one or two points will be shared, but no real intersection

                // See if any of the points are inside
                int[] insidePoints = GetInsidePoints(hull, triangle);

                Point3D[] retVal = null;

                if (insidePoints.Length == 0)
                {
                    // No points are inside the hull, but edges may punch all the way through
                    retVal = AllOutside(hull, triangle);
                }
                else if (insidePoints.Length == 1)
                {
                    // One point is inside the hull.  See where its edges intersect the hull
                    retVal = OneInside(hull, triangle, insidePoints[0]);
                }
                else if (insidePoints.Length == 2)
                {
                    // Two points are inside the hull.  See where their edges intersect the hull
                    retVal = TwoInside(hull, triangle, insidePoints[0], insidePoints[1]);
                }
                else if (insidePoints.Length == 3)
                {
                    // The triangle is completely inside the hull
                    retVal = new Point3D[] { triangle.Point0, triangle.Point1, triangle.Point2 };
                }
                else
                {
                    throw new ApplicationException("");
                }

                if (retVal != null)
                {
                    //TODO: Make sure the returned polygon's normal is the same direction as the triangle passed in
                }

                // Exit Function
                return retVal;
            }
示例#7
0
        /// <summary>
        /// Linear interpolation of vertex attributes.
        /// </summary>
        /// <param name="vertex">The interpolation vertex.</param>
        /// <param name="triangle">The triangle containing the vertex.</param>
        /// <param name="n">The number of vertex attributes.</param>
        /// <remarks>
        /// The vertex is expected to lie inside the triangle.
        /// </remarks>
        public static void InterpolateAttributes(Vertex vertex, ITriangle triangle, int n)
        {
            Vertex org = triangle.GetVertex(0);
            Vertex dest = triangle.GetVertex(1);
            Vertex apex = triangle.GetVertex(2);

            double xdo, ydo, xao, yao;
            double denominator;
            double dx, dy;
            double xi, eta;

            // Compute the circumcenter of the triangle.
            xdo = dest.x - org.x;
            ydo = dest.y - org.y;
            xao = apex.x - org.x;
            yao = apex.y - org.y;

            denominator = 0.5 / (xdo * yao - xao * ydo);

            //dx = (yao * dodist - ydo * aodist) * denominator;
            //dy = (xdo * aodist - xao * dodist) * denominator;

            dx = vertex.x - org.x;
            dy = vertex.y - org.y;

            // To interpolate vertex attributes for the new vertex inserted at
            // the circumcenter, define a coordinate system with a xi-axis,
            // directed from the triangle's origin to its destination, and
            // an eta-axis, directed from its origin to its apex.
            // Calculate the xi and eta coordinates of the circumcenter.
            xi = (yao * dx - xao * dy) * (2.0 * denominator);
            eta = (xdo * dy - ydo * dx) * (2.0 * denominator);
        
            for (int i = 0; i < n; i++)
            {
                // Interpolate the vertex attributes.
                vertex.attributes[i] = org.attributes[i]
                    + xi * (dest.attributes[i] - org.attributes[i])
                    + eta * (apex.attributes[i] - org.attributes[i]);
            }
        }
示例#8
0
    public ITriangle[] Process(IDrawCall drawCall, ICamera camera)
    {
        // vertex shade
        vertexShade.MVP = camera.P * camera.V * drawCall.M;
        vertexShade.N   = (camera.V * drawCall.M).Inverse().Transpose().Minor(3, 3);
        Vector4[]           vertices = drawCall.vertices;
        Vector3[]           normals  = drawCall.normals;
        IVertexOutputData[] outputs  = new VertexOutputData[vertices.Length];
        for (int vIndex = 0; vIndex < vertices.Length; vIndex++)
        {
            IVertexInputData input = new VertexInputData();
            input.vertex    = vertices[vIndex];
            input.normal    = normals[vIndex];
            outputs[vIndex] = vertexShade.Process(input);
        }

        // primitive assembly
        ITriangle[] primitives = primitiveAssemble.Process(outputs, drawCall.indices);

        Queue <ITriangle> triangles = new Queue <ITriangle>();

        for (int pIndex = 0; pIndex < primitives.Length; pIndex++)
        {
            // back-face culling
            ITriangle t = cull.Process(primitives[pIndex]);
            if (t != null)
            {
                // clipping
                ITriangle[] ts = clip.Process(t);
                if (ts != null)
                {
                    foreach (ITriangle each in ts)
                    {
                        triangles.Enqueue(each);
                    }
                }
            }
        }
        return(triangles.ToArray());
    }
示例#9
0
        /// <summary>
        /// Linear interpolation of vertex attributes.
        /// </summary>
        /// <param name="vertex">The interpolation vertex.</param>
        /// <param name="triangle">The triangle containing the vertex.</param>
        /// <param name="n">The number of vertex attributes.</param>
        /// <remarks>
        /// The vertex is expected to lie inside the triangle.
        /// </remarks>
        public static void InterpolateAttributes(Vertex vertex, ITriangle triangle, int n)
        {
            Vertex org  = triangle.GetVertex(0);
            Vertex dest = triangle.GetVertex(1);
            Vertex apex = triangle.GetVertex(2);

            float xdo, ydo, xao, yao;
            float denominator;
            float dx, dy;
            float xi, eta;

            // Compute the circumcenter of the triangle.
            xdo = dest.x - org.x;
            ydo = dest.y - org.y;
            xao = apex.x - org.x;
            yao = apex.y - org.y;

            denominator = 0.5 / (xdo * yao - xao * ydo);

            //dx = (yao * dodist - ydo * aodist) * denominator;
            //dy = (xdo * aodist - xao * dodist) * denominator;

            dx = vertex.x - org.x;
            dy = vertex.y - org.y;

            // To interpolate vertex attributes for the new vertex, define a
            // coordinate system with a xi-axis directed from the triangle's
            // origin to its destination, and an eta-axis, directed from its
            // origin to its apex.
            xi  = (yao * dx - xao * dy) * (2.0 * denominator);
            eta = (xdo * dy - ydo * dx) * (2.0 * denominator);

            for (int i = 0; i < n; i++)
            {
                // Interpolate the vertex attributes.
                vertex.attributes[i] = org.attributes[i]
                                       + xi * (dest.attributes[i] - org.attributes[i])
                                       + eta * (apex.attributes[i] - org.attributes[i]);
            }
        }
        public bool IsRightTriangle(ITriangle triangle)
        {
            try
            {
                var aPow = Math.Pow(triangle.A, 2);
                var bPow = Math.Pow(triangle.B, 2);
                var cPow = Math.Pow(triangle.C, 2);

                if (Equals(aPow, bPow + cPow))
                {
                    return
                        (true);
                }

                if (Equals(bPow, aPow + cPow))
                {
                    return
                        (true);
                }

                if (Equals(cPow, aPow + bPow))
                {
                    return
                        (true);
                }

                return
                    (false);
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                //в боевом проекте здесь будет логирование

                return
                    (false); //либо можно пробросить исключение, дело вкуса
            }
        }
示例#11
0
        internal static Vector3 GetPoint(ITriangle triangle, TriangleEdge edge, bool isFrom)
        {
            switch (edge)
            {
            case TriangleEdge.Edge_01:
                if (isFrom)
                {
                    return(triangle.Point0);
                }
                else
                {
                    return(triangle.Point1);
                }

            case TriangleEdge.Edge_12:
                if (isFrom)
                {
                    return(triangle.Point1);
                }
                else
                {
                    return(triangle.Point2);
                }

            case TriangleEdge.Edge_20:
                if (isFrom)
                {
                    return(triangle.Point2);
                }
                else
                {
                    return(triangle.Point0);
                }

            default:
                throw new ApplicationException("Unknown TriangleEdge: " + edge.ToString());
            }
        }
        /// <summary>
        /// Test whether a given point lies inside a triangle or not.
        /// </summary>
        /// <param name="triangle">Triangle instance.</param>
        /// <param name="x">Point to locate.</param>
        /// <param name="y">Point to locate.</param>
        /// <returns>True, if point is inside or on the edge of this triangle.</returns>
        public static bool Contains(this ITriangle triangle, double x, double y)
        {
            var t0 = triangle.GetVertex(0);
            var t1 = triangle.GetVertex(1);
            var t2 = triangle.GetVertex(2);

            // TODO: no need to create new Point instances here
            Point d0 = new Point(t1.X - t0.X, t1.Y - t0.Y);
            Point d1 = new Point(t2.X - t0.X, t2.Y - t0.Y);
            Point d2 = new Point(x - t0.X, y - t0.Y);

            // crossproduct of (0, 0, 1) and d0
            Point c0 = new Point(-d0.Y, d0.X);

            // crossproduct of (0, 0, 1) and d1
            Point c1 = new Point(-d1.Y, d1.X);

            // Linear combination d2 = s * d0 + v * d1.
            //
            // Multiply both sides of the equation with c0 and c1
            // and solve for s and v respectively
            //
            // s = d2 * c1 / d0 * c1
            // v = d2 * c0 / d1 * c0

            double s = DotProduct(d2, c1) / DotProduct(d0, c1);
            double v = DotProduct(d2, c0) / DotProduct(d1, c0);

            if (s >= 0 && v >= 0 && ((s + v) <= 1))
            {
                // Point is inside or on the edge of this triangle.
                return(true);
            }

            return(false);
        }
示例#13
0
        private void AddPlane(ITriangle plane, Color color, double size = 20)
        {
            // Material
            MaterialGroup materials = new MaterialGroup();
            materials.Children.Add(new DiffuseMaterial(new SolidColorBrush(color)));
            //materials.Children.Add(new SpecularMaterial(new SolidColorBrush(UtilityWPF.AlphaBlend(color, Colors.White, .5d)), 5d));

            // Build a differently sized triangle
            ITriangle plane2 = new Triangle(
                plane.Point1 + ((plane.Point0 - plane.Point1) * size),
                plane.Point2 + ((plane.Point1 - plane.Point2) * size),
                plane.Point0 + ((plane.Point2 - plane.Point0) * size)
                );

            // Create the points for the plane
            Point3D[] points = new Point3D[4];
            points[0] = plane2.Point0;
            points[1] = plane2.Point1;
            points[2] = plane2.Point2;
            points[3] = Math3D.FromBarycentric(plane2, new Vector(1, 1));

            // Geometry Model
            GeometryModel3D geometry = new GeometryModel3D();
            geometry.Material = materials;
            geometry.BackMaterial = materials;
            geometry.Geometry = UtilityWPF.GetMeshFromTriangles(new[] { new TriangleIndexed(0, 1, 2, points), new TriangleIndexed(1, 3, 2, points) });

            // Model Visual
            ModelVisual3D model = new ModelVisual3D();
            model.Content = geometry;

            // Temporarily add to the viewport
            _viewport.Children.Add(model);
            _visuals.Add(model);
        }
        private static Point3D[] GetVoronoiCtrlPoints(HullVoronoiExploder_ShotHit[] hits, ITriangle[] convexHull, int minCount, int maxCount, double aabbLen)
        {
            const int MIN = 5;

            Random rand = StaticRandom.GetRandomForThread();

            #region examine hits

            Tuple<int, double>[] hitsByLength = hits.
                Select((o, i) => Tuple.Create(i, (o.Hit.Item2 - o.Hit.Item1).Length)).
                OrderByDescending(o => o.Item2).
                ToArray();

            double totalLength = hitsByLength.Sum(o => o.Item2);

            Tuple<int, double>[] hitsByPercentLength = hitsByLength.
                Select(o => Tuple.Create(o.Item1, o.Item2 / totalLength)).
                ToArray();

            #endregion

            #region define control point cones

            double entryRadius = aabbLen * .05;
            double exitRadius = aabbLen * .35;
            double maxAxisLength = aabbLen * .75;

            int count = hits.Length * 2;
            count += (totalLength / (aabbLen * .1)).ToInt_Round();

            if (count < minCount) count = minCount;
            else if (count > maxCount) count = maxCount;

            #endregion

            #region randomly pick control points

            // Keep adding rings around shots until the count is exceeded

            var sets = new List<Tuple<int, List<Point3D>>>();
            int runningSum = 0;

            // Make sure each hit line gets some points
            for (int cntr = 0; cntr < hits.Length; cntr++)
            {
                AddToHitline(ref runningSum, sets, cntr, hits[cntr].Hit, entryRadius, exitRadius, maxAxisLength, rand);
            }

            // Now that all hit lines have points, randomly choose lines until count is exceeded
            while (runningSum < count)
            {
                var pointsPerLength = hitsByLength.
                    Select(o =>
                    {
                        var pointsForIndex = sets.FirstOrDefault(p => p.Item1 == o.Item1);
                        int countForIndex = pointsForIndex == null ? 0 : pointsForIndex.Item2.Count;
                        return Tuple.Create(o.Item1, countForIndex / o.Item2);
                    }).
                    OrderBy(o => o.Item2).
                    ToArray();

                double sumRatio = pointsPerLength.Sum(o => o.Item2);

                var pointsPerLengthNormalized = pointsPerLength.
                    Select(o => Tuple.Create(o.Item1, o.Item2 / sumRatio)).
                    ToArray();

                int index = UtilityCore.GetIndexIntoList(rand.NextPow(3), pointsPerLengthNormalized);

                AddToHitline(ref runningSum, sets, index, hits[index].Hit, entryRadius, exitRadius, maxAxisLength, rand);
            }

            #endregion

            #region remove excessive points

            while (runningSum > count)
            {
                Tuple<int, double>[] fractions = sets.
                    Select((o, i) => Tuple.Create(i, o.Item2.Count.ToDouble() / runningSum.ToDouble())).
                    OrderByDescending(o => o.Item2).
                    ToArray();

                int fractionIndex = UtilityCore.GetIndexIntoList(rand.NextPow(1.5), fractions);     //nextPow will favor the front of the list, which is where the rings with the most points are
                int setIndex = fractions[fractionIndex].Item1;

                sets[setIndex].Item2.RemoveAt(UtilityCore.GetIndexIntoList(rand.NextDouble(), sets[setIndex].Item2.Count));

                runningSum--;
            }

            #endregion

            #region ensure enough for voronoi algorithm

            List<Point3D> retVal = new List<Point3D>();
            retVal.AddRange(sets.SelectMany(o => o.Item2));

            // The voronoi algrorithm fails if there aren't at least 5 points (really should fix that).  So add points that are
            // way away from the hull.  This will make the voronoi algorithm happy, and won't affect the local results
            if (count < MIN)
            {
                retVal.AddRange(
                    Enumerable.Range(0, MIN - count).
                    Select(o => Math3D.GetRandomVector_Spherical_Shell(aabbLen * 20).ToPoint())
                    );
            }

            #endregion

            return retVal.ToArray();
        }
示例#15
0
        public static Vector3D GetProjectedVector(this Vector3D vector, ITriangle alongPlane)
        {
            // Get a line that is parallel to the plane, but along the direction of the vector
            Vector3D alongLine = Vector3D.CrossProduct(alongPlane.Normal, Vector3D.CrossProduct(vector, alongPlane.Normal));

            // Use the other overload to get the portion of the vector along this line
            return vector.GetProjectedVector(alongLine);
        }
示例#16
0
        private static RayHitTestParameters CastRay_PlaneLimitedSprtGetSnapLine(ITriangle plane, Vector3D lookDirection)
        {
            const double THRESHOLD = .33d;

            #region Get orthogonal vectors

            Point3D centerPoint = new Point3D();
            DoubleVector testVectors = new DoubleVector();

            //This assumes that the plane was set up with orthogonal vectors, and that these are the ones to use in this case

            for (int cntr = 0; cntr < 3; cntr++)
            {
                switch (cntr)
                {
                    case 0:
                        centerPoint = plane.Point0;
                        testVectors = new DoubleVector((plane.Point1 - plane.Point0).ToUnit(), (plane.Point2 - plane.Point0).ToUnit());
                        break;

                    case 1:
                        centerPoint = plane.Point1;
                        testVectors = new DoubleVector((plane.Point2 - plane.Point1).ToUnit(), (plane.Point0 - plane.Point1).ToUnit());
                        break;

                    case 2:
                        centerPoint = plane.Point2;
                        testVectors = new DoubleVector((plane.Point0 - plane.Point2).ToUnit(), (plane.Point1 - plane.Point2).ToUnit());
                        break;

                    default:
                        throw new ApplicationException("Unexpected cntr: " + cntr.ToString());
                }

                if (Math1D.IsNearZero(Vector3D.DotProduct(testVectors.Standard, testVectors.Orth)))
                {
                    break;
                }
            }

            #endregion

            double dot = Vector3D.DotProduct(testVectors.Standard, lookDirection.ToUnit());
            if (Math.Abs(dot) < THRESHOLD)
            {
                return new RayHitTestParameters(centerPoint, testVectors.Standard);		// standard is fairly orhogonal to the camera's look direction, so only allow the part to slide along this axis
            }

            dot = Vector3D.DotProduct(testVectors.Orth, lookDirection.ToUnit());
            if (Math.Abs(dot) < THRESHOLD)
            {
                return new RayHitTestParameters(centerPoint, testVectors.Orth);
            }

            return null;
        }
示例#17
0
 private void GetNeighbor(ITriangle tri, int i, out ITriangle neighbor, out int nid)
 {
     neighbor = tri.GetNeighbor(i);
     nid      = neighbor == null ? -1 : neighbor.ID;
 }
示例#18
0
 public void SetShape_Plane(ITriangle plane)
 {
     _shape = ShapeType.Plane;
     _plane = plane;
 }
示例#19
0
 public CircleDefinition(ITriangle plane, Point3D center, double radius)
 {
     this.Plane = plane;
     this.Center = center;
     this.Radius = radius;
 }
示例#20
0
 public CircleDefinition(ITriangle plane, Point3D center, double radius)
 {
     this.Plane  = plane;
     this.Center = center;
     this.Radius = radius;
 }
 private void OnTriangleChanged(ITriangle newValue)
 {
     newValue?.Reset();
     TriangleBase = TriangleHeight = Area = 0;
 }
 public void SelectTriangle(ITriangle tri, Vertex org, Vertex dest)
 {
     currentTri  = tri;
     currentOrg  = org;
     currentDest = dest;
 }
 public RectangleAdapter(ITriangle triangle)
 {
     _triangle = triangle;
 }
示例#24
0
        private PointF GetPoint(ITriangle tri, int index)
        {
            var v = tri.GetVertex(index);

            return(new PointF((float)v.X, (float)v.Y));
        }
示例#25
0
        private void grdViewPort_MouseDown(object sender, MouseButtonEventArgs e)
        {
            const double CLICKDISTANCE = BOUNDRYSIZE / 8;

            try
            {
                if (e.ChangedButton != MouseButton.Left)
                {
                    // All the special logic in this method is for the left button
                    return;
                }

                // Fire a ray at the mouse point
                Point clickPoint2D = e.GetPosition(grdViewPort);

                RayHitTestParameters   clickRay;
                List <MyHitTestResult> hits = UtilityWPF.CastRay(out clickRay, clickPoint2D, _viewport, _camera, _viewport, false);

                // Figure out where to place the point
                Point3D   clickPoint3D;
                ITriangle clickPlane = null;
                if (hits != null && hits.Count > 0)
                {
                    // They clicked on something, so use that
                    clickPoint3D = hits[0].Point;
                }
                else
                {
                    //TODO: If there is a mothership, choose a point in a plane that goes through it (orth to the click ray)
                    //
                    // If there isn't, but they click near a swarm, use that plane
                    //
                    // Or if they click near something (like an asteroid)

                    double?clickDistNearSwarm = GetClickDistanceNearSwarm(clickRay);

                    double clickDist;
                    if (clickDistNearSwarm == null)
                    {
                        clickDist = Math.Max(CLICKDISTANCE, _camera.Position.ToVector().Length / 1.1);
                    }
                    else
                    {
                        clickDist = clickDistNearSwarm.Value;
                    }

                    clickPoint3D = clickRay.Origin + clickRay.Direction.ToUnit() * clickDist;
                }

                // Update the click plane
                if (clickPlane == null)
                {
                    Vector3D standard = Math3D.GetArbitraryOrhonganal(clickRay.Direction);
                    Vector3D orth     = Vector3D.CrossProduct(standard, clickRay.Direction);
                    clickPlane = new Triangle(clickPoint3D, clickPoint3D + standard, clickPoint3D + orth);
                }

                // Store the point and plane
                _strokes.AddPointToStroke(clickPoint3D);
                _clickPlane = clickPlane;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString(), this.Title, MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }
示例#26
0
        /// <summary>
        /// Compute angle information for given triangle.
        /// </summary>
        /// <param name="triangle">The triangle to check.</param>
        /// <param name="data">Array of doubles (length 6).</param>
        /// <remarks>
        /// On return, the squared cosines of the minimum and maximum angle will
        /// be stored at position data[0] and data[1] respectively.
        /// If the triangle was obtuse, data[2] will be set to -1 and maximum angle
        /// is computed as (pi - acos(sqrt(data[1]))).
        /// </remarks>
        public static void ComputeAngles(ITriangle triangle, double[] data)
        {
            double min = 0.0;
            double max = 1.0;

            var va = triangle.GetVertex(0);
            var vb = triangle.GetVertex(1);
            var vc = triangle.GetVertex(2);

            double dxa  = vb.x - vc.x;
            double dya  = vb.y - vc.y;
            double lena = dxa * dxa + dya * dya;

            double dxb  = vc.x - va.x;
            double dyb  = vc.y - va.y;
            double lenb = dxb * dxb + dyb * dyb;

            double dxc  = va.x - vb.x;
            double dyc  = va.y - vb.y;
            double lenc = dxc * dxc + dyc * dyc;

            // Dot products.
            double dota = data[0] = dxb * dxc + dyb * dyc;
            double dotb = data[1] = dxc * dxa + dyc * dya;
            double dotc = data[2] = dxa * dxb + dya * dyb;

            // Squared cosines.
            data[3] = (dota * dota) / (lenb * lenc);
            data[4] = (dotb * dotb) / (lenc * lena);
            data[5] = (dotc * dotc) / (lena * lenb);

            // The sign of the dot product will tell us, if the angle is
            // acute (value < 0) or obtuse (value > 0).

            bool acute = true;

            double cos, dot;

            for (int i = 0; i < 3; i++)
            {
                dot = data[i];
                cos = data[3 + i];

                if (dot <= 0.0)
                {
                    if (cos > min)
                    {
                        min = cos;
                    }

                    if (acute && (cos < max))
                    {
                        max = cos;
                    }
                }
                else
                {
                    // Update max angle for (possibly non-acute) triangle
                    if (acute || (cos > max))
                    {
                        max   = cos;
                        acute = false;
                    }
                }
            }

            data[0] = min;
            data[1] = max;
            data[2] = acute ? 1.0 : -1.0;
        }
示例#27
0
        static void Main(string[] args)
        {
            XmlConfigurator.Configure();
            logger.Debug("Programm starts ");
            int userChoice;

            /* Menu for user */
            Console.Write("\n\n---------------MENU---------------\n1.Line\n2.Circle\n3.Rectangle\n4.Triangle\n5.Hexagone\n6.Exit\nEnter Choice: ");

            userChoice = int.Parse(Console.ReadLine());
            switch (userChoice)
            {
            case 1:    /* Line drawing */
                try
                {
                    ILine line = Factory.GetInstanceILine();
                    line = UserInput.GetLineCoordinate();

                    line.DrawLine();
                    logger.Info("line draw successful");
                }
                catch (Exception exception)
                {
                    logger.Error("in line Draw exception: " + exception.ToString());
                    Console.WriteLine("in line Draw exception: " + exception.ToString());
                    Console.ReadLine();
                }
                break;

            case 2:    /* Circle drawing */
                try
                {
                    ICircle circle = Factory.GetInstanceICircle();
                    circle = UserInput.GetCircleProperties();

                    circle.DrawCircle();

                    logger.Info("line draw successful");
                }
                catch (Exception exception)
                {
                    logger.Error("in circle Draw exception: " + exception.ToString());
                }

                break;

            case 3:    /* Rectangle drawing */
                try
                {
                    IRectangle rectangle = Factory.GetInstanceIRectangle();

                    rectangle = UserInput.GetRectangleDiagonal();

                    rectangle.DrawRectangle();

                    logger.Info("line draw successful");
                }
                catch (Exception exception)
                {
                    logger.Error("in rectangle Draw exception: " + exception.ToString());
                }
                break;

            case 4:
                try
                {
                    ITriangle triangle = Factory.GetInstanceITriangle();

                    triangle = UserInput.GetTrianglePoints();

                    triangle.DrawTriangle();

                    logger.Info("triangle draw successful");
                }
                catch (Exception exception)
                {
                    logger.Error("in triangle Draw exception: " + exception.ToString());
                }
                break;

            case 5:
                try
                {
                    IHexagon hexagone = Factory.GetInstanceIHexagone();

                    hexagone = UserInput.GetHexagonePropertis();

                    hexagone.DrawHexagon();

                    logger.Info("hexagone draw successful");
                }
                catch (Exception exception)
                {
                    logger.Error("in hexagone Draw exception: " + exception.ToString());
                }
                break;

            case 6:    /* Exit */
                Console.WriteLine("\nThank you come again!!!");
                break;

            default:
                Console.WriteLine("\nInvalid input");
                break;
            }
        }
 public static double Area(this ITriangle triangle)
 {
     return((triangle.Base * triangle.Height) / 2);
 }
示例#29
0
        private static Point3D? CastRay_Circle(out double clickDistanceSquared, ITriangle plane, Point3D center, double radius, RayHitTestParameters mouseDownClickRay, RayHitTestParameters mouseDownCenterRay, RayHitTestParameters currentClickRay)
        {
            clickDistanceSquared = 0d;		// this will get overwritten, but without setting it globally, the compiler will complain

            // Get points on the circle
            Point3D? mouseDownClickPoint = null;
            Point3D? mouseDownCenterPoint = null;
            Point3D? currentClickPoint = null;

            Point3D[] nearestCirclePoints, nearestLinePoints;

            if (Math3D.GetClosestPoints_Circle_Line(out nearestCirclePoints, out nearestLinePoints, plane, center, radius, currentClickRay.Origin, currentClickRay.Direction, Math3D.RayCastReturn.ClosestToRay))
            {
                clickDistanceSquared = (nearestLinePoints[0] - nearestCirclePoints[0]).LengthSquared;
                currentClickPoint = nearestCirclePoints[0];

                if (Math3D.GetClosestPoints_Circle_Line(out nearestCirclePoints, out nearestLinePoints, plane, center, radius, mouseDownClickRay.Origin, mouseDownClickRay.Direction, Math3D.RayCastReturn.ClosestToRay))
                {
                    mouseDownClickPoint = nearestCirclePoints[0];

                    if (Math3D.GetClosestPoints_Circle_Line(out nearestCirclePoints, out nearestLinePoints, plane, center, radius, mouseDownCenterRay.Origin, mouseDownCenterRay.Direction, Math3D.RayCastReturn.ClosestToRay))
                    {
                        mouseDownCenterPoint = nearestCirclePoints[0];
                    }
                }
            }

            if (mouseDownCenterPoint == null || mouseDownClickPoint == null || currentClickPoint == null)
            {
                clickDistanceSquared = 0d;
                return currentClickPoint;		// it doesn't matter if this one is null or not, the offset can't be determined, so just return the raw click value
            }

            // Get the offset
            Vector3D mouseDownClickLine = mouseDownClickPoint.Value - center;
            Vector3D mouseDownCenterLine = mouseDownCenterPoint.Value - center;

            Quaternion offset = Math3D.GetRotation(mouseDownClickLine, mouseDownCenterLine);

            // Convert to local, and rotate by offset
            Vector3D currentClickLine = currentClickPoint.Value - center;
            currentClickLine = new RotateTransform3D(new QuaternionRotation3D(offset)).Transform(currentClickLine);

            // Now convert back to world coords
            return center + currentClickLine;
        }
示例#30
0
        internal static ITriangle GetTrianglePoints()
        {
            ITriangle triangle = Factory.GetInstanceITriangle();
            Point     one      = new Point();
            Point     two      = new Point();
            Point     three    = new Point();

            /* get input from user point ---------------------1*/
            Console.Write("Enter co-ordinates point one (x1,y1): ");
            string coOrdinate = Console.ReadLine();

            string[] coOrdinateValues = coOrdinate.Split(',');
            /* parsing check and setting null if parsing fails */
            int parseStorageX = 0, parseStorageY = 0;

            if (coOrdinateValues.Count() == 2 && InputValidator.IsInt(coOrdinateValues[0], ref parseStorageX) & InputValidator.IsInt(coOrdinateValues[1], ref parseStorageY))
            {
                one.X        = parseStorageX;
                one.Y        = parseStorageY;
                triangle.one = one;
            }
            else
            {
                triangle = null;
                return(triangle);
            }

            /* get input from user point two-----------------2*/
            Console.Write("Enter co-ordinates point two (x2,y2): ");
            coOrdinate       = Console.ReadLine();
            coOrdinateValues = coOrdinate.Split(',');
            /* parsing check and setting null if parsing fails */
            parseStorageX = 0; parseStorageY = 0;
            if (coOrdinateValues.Count() == 2 && InputValidator.IsInt(coOrdinateValues[0], ref parseStorageX) & InputValidator.IsInt(coOrdinateValues[1], ref parseStorageY))
            {
                two.X        = parseStorageX;
                two.Y        = parseStorageY;
                triangle.two = two;
            }
            else
            {
                triangle = null;
                return(triangle);
            }

            /* get input from user point three----------------3*/
            Console.Write("Enter co-ordinates point two (x3,y3): ");
            coOrdinate       = Console.ReadLine();
            coOrdinateValues = coOrdinate.Split(',');
            /* parsing check and setting null if parsing fails */
            parseStorageX = 0; parseStorageY = 0;
            if (coOrdinateValues.Count() == 2 && InputValidator.IsInt(coOrdinateValues[0], ref parseStorageX) & InputValidator.IsInt(coOrdinateValues[1], ref parseStorageY))
            {
                three.X        = parseStorageX;
                three.Y        = parseStorageY;
                triangle.three = three;
            }
            else
            {
                triangle = null;
                return(triangle);
            }

            return(triangle);
        }
示例#31
0
        /// <summary>
        /// Finds the adjacencies between triangles by forming a stack of triangles for
        /// each vertex. Each triangle is on three different stacks simultaneously.
        /// </summary>
        private static List<Otri>[] SetNeighbors(Mesh mesh, ITriangle[] triangles)
        {
            Otri tri = default(Otri);
            Otri triangleleft = default(Otri);
            Otri checktri = default(Otri);
            Otri checkleft = default(Otri);
            Otri nexttri;
            TVertex tdest, tapex;
            TVertex checkdest, checkapex;
            int[] corner = new int[3];
            int aroundvertex;
            int i;

            // Allocate a temporary array that maps each vertex to some adjacent triangle.
            var vertexarray = new List<Otri>[mesh.vertices.Count];

            // Each vertex is initially unrepresented.
            for (i = 0; i < mesh.vertices.Count; i++)
            {
                Otri tmp = default(Otri);
                tmp.tri = mesh.dummytri;
                vertexarray[i] = new List<Otri>(3);
                vertexarray[i].Add(tmp);
            }

            i = 0;

            // Read the triangles from the .ele file, and link
            // together those that share an edge.
            foreach (var item in mesh.triangles)
            {
                tri.tri = item;

                // Copy the triangle's three corners.
                for (int j = 0; j < 3; j++)
                {
                    corner[j] = triangles[i].GetVertexID(j);

                    if ((corner[j] < 0) || (corner[j] >= mesh.invertices))
                    {
                        Log.Instance.Error("Triangle has an invalid vertex index.", "MeshReader.Reconstruct()");
                        throw new Exception("Triangle has an invalid vertex index.");
                    }
                }

                // Read the triangle's attributes.
                tri.tri.label = triangles[i].Label;

                // TODO: VarArea
                if (mesh.behavior.VarArea)
                {
                    tri.tri.area = triangles[i].Area;
                }

                // Set the triangle's vertices.
                tri.orient = 0;
                tri.SetOrg(mesh.vertices[corner[0]]);
                tri.SetDest(mesh.vertices[corner[1]]);
                tri.SetApex(mesh.vertices[corner[2]]);

                // Try linking the triangle to others that share these vertices.
                for (tri.orient = 0; tri.orient < 3; tri.orient++)
                {
                    // Take the number for the origin of triangleloop.
                    aroundvertex = corner[tri.orient];

                    int index = vertexarray[aroundvertex].Count - 1;

                    // Look for other triangles having this vertex.
                    nexttri = vertexarray[aroundvertex][index];

                    // Push the current triangle onto the stack.
                    vertexarray[aroundvertex].Add(tri);

                    checktri = nexttri;

                    if (checktri.tri.id != Mesh.DUMMY)
                    {
                        tdest = tri.Dest();
                        tapex = tri.Apex();

                        // Look for other triangles that share an edge.
                        do
                        {
                            checkdest = checktri.Dest();
                            checkapex = checktri.Apex();

                            if (tapex == checkdest)
                            {
                                // The two triangles share an edge; bond them together.
                                tri.Lprev(ref triangleleft);
                                triangleleft.Bond(ref checktri);
                            }
                            if (tdest == checkapex)
                            {
                                // The two triangles share an edge; bond them together.
                                checktri.Lprev(ref checkleft);
                                tri.Bond(ref checkleft);
                            }
                            // Find the next triangle in the stack.
                            index--;
                            nexttri = vertexarray[aroundvertex][index];

                            checktri = nexttri;
                        } while (checktri.tri.id != Mesh.DUMMY);
                    }
                }

                i++;
            }

            return vertexarray;
        }
示例#32
0
        /// <summary>
        /// Makes the actual mesh
        /// </summary>
        protected void _redraw()
        {
            if (lines.Count > 0)
            {
                Polygon = new List <DCurve3>();
                foreach (Dataline ring in lines)
                {
                    foreach (VertexLookup v in ring.VertexTable)
                    {
                        VertexTable.Add(v);
                    }
                    DCurve3 curve = new DCurve3();
                    curve.Vector3(ring.GetVertexPositions(), true);
                    Polygon.Add(curve);
                }
            }

            MeshFilter mf = Shape.GetComponent <MeshFilter>();

            MeshCollider[] mc = Shape.GetComponents <MeshCollider>();
            mf.mesh = null;
            Mesh mesh  = new Mesh();
            Mesh imesh = new Mesh();

            mesh.indexFormat  = UnityEngine.Rendering.IndexFormat.UInt32;
            imesh.indexFormat = UnityEngine.Rendering.IndexFormat.UInt32;
            Frame3f frame = new Frame3f();

            Vector3[]        vertices;
            GeneralPolygon2d polygon2d;
            Delaunator       delaunator;
            List <int>       triangles = new List <int>();

            try {
                //
                // Map 3d Polygon to the bext fit 2d polygon and also return the frame used for the mapping
                //
                polygon2d = Polygon.ToPolygon(ref frame);

                //
                // calculate the dalaunay triangulation of the 2d polygon
                //
                delaunator = new Delaunator(polygon2d.AllVerticesItr().ToPoints());

                IEnumerable <Vector2d> vlist = delaunator.Points.ToVectors2d();
                vertices = new Vector3[vlist.Count()];

                //
                // for each vertex in the dalaunay triangulatin - map back to a 3d point and also populate the vertex table
                //
                for (int i = 0; i < vlist.Count(); i++)
                {
                    Vector2d v = vlist.ElementAt(i);
                    try {
                        Vector3d v1 = Polygon.AllVertexItr().Find(item => v.Distance(frame.ToPlaneUV((Vector3f)item, 2)) < 0.001);
                        vertices[i] = Shape.transform.InverseTransformPoint((Vector3)v1);
                        VertexLookup vl = VertexTable.Find(item => v1.Distance(item.Com.transform.position) < 0.001);
                        if (vl != null)
                        {
                            vl.pVertex = i;
                        }
                    } catch {
                        Debug.Log("Mesh Error");
                    }
                }

                //
                // eaxtract the triangles from the delaunay triangulation
                //
                IEnumerable <ITriangle> tris = delaunator.GetTriangles();
                for (int i = 0; i < tris.Count(); i++)
                {
                    ITriangle tri = tris.ElementAt(i);

                    if (polygon2d.Contains(tri.CetIncenter()))
                    {
                        int index = 3 * i;
                        triangles.Add(delaunator.Triangles[index]);
                        triangles.Add(delaunator.Triangles[index + 1]);
                        triangles.Add(delaunator.Triangles[index + 2]);
                    }
                }
            } catch (Exception e) {
                throw new Exception("feature is not a valid Polygon : " + e.ToString());
            }

            //
            // build the mesh entity
            //
            mesh.vertices  = vertices;
            mesh.triangles = triangles.ToArray();
            mesh.uv        = BuildUVs(vertices);

            mesh.RecalculateBounds();
            mesh.RecalculateNormals();

            imesh.vertices  = mesh.vertices;
            imesh.triangles = triangles.Reverse <int>().ToArray();
            imesh.uv        = mesh.uv;

            imesh.RecalculateBounds();
            imesh.RecalculateNormals();

            mf.mesh = mesh;
            try {
                mc[0].sharedMesh = mesh;
                mc[1].sharedMesh = imesh;
            } catch (Exception e) {
                Debug.Log(e.ToString());
            }
        }
示例#33
0
 public void Init()
 {
     _triangle = Triangle.CreateTriangle(4, 2, 3);
     //_rectTriangle = (RectangularTriangle)RectangularTriangle.CreateTriangle(15, 12, 9);
 }
        private double GetSearchRadius(ITriangle dragPlane, double dragSpeed)
        {
            // Get the difference from the camera to the drag plane, this will determine how far out to look for items
            // Use plane distance as a rough estimate of how far the camera can see side to side
            double planeDistance = Math.Abs(Math3D.DistanceFromPlane(dragPlane, _camera.Position));
            planeDistance *= .5d;

            // Drag speed is tiny, so just return what the camera can see
            return planeDistance;



            //double dragScale = dragSpeed * 10;

            //if (dragScale < planeDistance)
            //{
            //    // They are dragging slowly, don't project too far
            //    return dragScale;
            //}
            //else
            //{
            //    // Doesn't matter how fast they're dragging.  Don't project farther than they can see
            //    return planeDistance;
            //}
        }
示例#35
0
        /// <summary>
        /// This can be used to visualize a plane.  Drawing a single square is difficult to visualize the perspective, so this draws
        /// a set of tiles, and a border.  It's always square to also help visualize perspective.  Also, wpf doesn't deal with semi
        /// transparency very well, so that's why this model is mostly gaps
        /// NOTE: Most of the methods return meshes, this returns an entire model
        /// </summary>
        /// <param name="center">
        /// This gives a chance to be explicit about the center of the drawn plane.  There is no check to be sure center lies on the plane,
        /// but it should.  (this was added because Math3D.GetPlane() doesn't build a triangle centered on the point passed in)
        /// If this is left null, then the center of the triangle will be used
        /// </param>
        public static Model3D GetPlane(ITriangle plane, double size, Color color, Color? reflectiveColor = null, int numCells = 12, Point3D? center = null)
        {
            double halfSize = size / 2;

            double cellSize = size / numCells;

            double tileSizeHalf = cellSize / (4d * 2d);

            Model3DGroup retVal = new Model3DGroup();

            #region Border

            var segments = new[]
                {
                    Tuple.Create(new Point3D(-halfSize, -halfSize, 0), new Point3D(halfSize, -halfSize, 0)),
                    Tuple.Create(new Point3D(halfSize, -halfSize, 0), new Point3D(halfSize, halfSize, 0)),
                    Tuple.Create(new Point3D(halfSize, halfSize, 0), new Point3D(-halfSize, halfSize, 0)),
                    Tuple.Create(new Point3D(-halfSize, halfSize, 0), new Point3D(-halfSize, -halfSize, 0)),
                };

            Color lineColor = Color.FromArgb(96, color.R, color.G, color.B);
            //double lineThickness = .015;
            double lineThickness = size / 666.666666667d;

            foreach (var segment in segments)
            {
                retVal.Children.Add(new Game.HelperClassesWPF.Primitives3D.BillboardLine3D() { Color = lineColor, IsReflectiveColor = false, Thickness = lineThickness, FromPoint = segment.Item1, ToPoint = segment.Item2 }.Model);
            }

            #endregion

            #region Tiles

            // Material
            MaterialGroup materials = new MaterialGroup();
            materials.Children.Add(new DiffuseMaterial(new SolidColorBrush(Color.FromArgb(48, color.R, color.G, color.B))));
            if (reflectiveColor != null)
            {
                materials.Children.Add(new SpecularMaterial(new SolidColorBrush(Color.FromArgb(96, reflectiveColor.Value.R, reflectiveColor.Value.G, reflectiveColor.Value.B)), 5d));
            }

            // Tiles
            for (int xCntr = 0; xCntr <= numCells; xCntr++)
            {
                double x = -halfSize + (xCntr * cellSize);
                double left = xCntr == 0 ? 0 : -tileSizeHalf;
                double right = xCntr == numCells ? 0 : tileSizeHalf;

                for (int yCntr = 0; yCntr <= numCells; yCntr++)
                {
                    double y = -halfSize + (yCntr * cellSize);
                    double up = yCntr == 0 ? 0 : -tileSizeHalf;
                    double down = yCntr == numCells ? 0 : tileSizeHalf;

                    // Geometry Model
                    GeometryModel3D geometry = new GeometryModel3D();
                    geometry.Material = materials;
                    geometry.BackMaterial = materials;
                    geometry.Geometry = UtilityWPF.GetSquare2D(new Point(x + left, y + up), new Point(x + right, y + down));

                    retVal.Children.Add(geometry);
                }
            }

            #endregion

            Transform3DGroup transform = new Transform3DGroup();
            transform.Children.Add(new RotateTransform3D(new QuaternionRotation3D(Math3D.GetRotation(new Vector3D(0, 0, 1), plane.Normal))));
            if (center == null)
            {
                transform.Children.Add(new TranslateTransform3D(plane.GetCenterPoint().ToVector()));
            }
            else
            {
                transform.Children.Add(new TranslateTransform3D(center.Value.ToVector()));
            }
            retVal.Transform = transform;

            return retVal;
        }
        private static Tuple<Point3D, Vector3D>[] GetFilteredNearby(Point3D[] nearby, Point3D position, Vector3D dragVelocity, ITriangle dragPlane, double minDot_LeftRight, double minDot_UpDown)
        {
            List<Tuple<Point3D, Vector3D>> retVal = new List<Tuple<Point3D, Vector3D>>();

            // Get the portion of the drag velocity that is along the plane, then convert to a unit vector            
            Vector3D? velocity = GetVectorAlongPlaneUnit(dragVelocity, dragPlane);
            if (velocity == null)
            {
                return retVal.ToArray();
            }

            for (int cntr = 0; cntr < nearby.Length; cntr++)
            {
                Vector3D directionToPoint = nearby[cntr] - position;

                DoubleVector directionSplit = Math3D.SplitVector(directionToPoint, dragPlane);

                #region Left/Right

                if (Math3D.IsNearZero(directionSplit.Standard))
                {
                    continue;
                }

                Vector3D directionAlongPlaneUnit = directionSplit.Standard.ToUnit();

                // Compare left/right (it's more restrictive)
                double dotLeftRight = Vector3D.DotProduct(directionAlongPlaneUnit, velocity.Value);
                if (dotLeftRight < minDot_LeftRight)
                {
                    continue;
                }

                #endregion
                #region Up/Down

                // Get the portion along the velocity, then add the portion away from the plane (which eliminates the left/right part)
                Vector3D directionUpDownUnit = directionToPoint.GetProjectedVector(velocity.Value) + directionSplit.Orth;
                if (Math3D.IsNearZero(directionUpDownUnit))
                {
                    continue;
                }

                directionUpDownUnit.Normalize();

                // Compare up/down
                double dotUpDown = Vector3D.DotProduct(directionUpDownUnit, velocity.Value);
                if (dotUpDown < minDot_UpDown)
                {
                    continue;
                }

                #endregion

                // Add it (only storing the up/down portion, because that's all that's needed)
                retVal.Add(Tuple.Create(nearby[cntr], directionUpDownUnit));
            }

            return retVal.ToArray();
        }
 /// <summary>
 /// Constructor given a run-off triangle.
 /// </summary>
 /// <param name="triangle">Run-off triangle to be developed by this method.</param>
 protected FactorBasedMethod(ITriangle triangle)
 {
     Triangle    = triangle.AsReadOnly();
     _projection = new Lazy <IReadOnlySquare>(CalculateProjection);
 }
        private static Vector3D? GetVectorAlongPlaneUnit(Vector3D vector, ITriangle plane)
        {
            DoubleVector split = Math3D.SplitVector(vector, plane);

            if (Math3D.IsNearZero(split.Standard))
            {
                return null;
            }

            return split.Standard.ToUnit();
        }
 /// <summary>
 /// Test whether a given point lies inside a triangle or not.
 /// </summary>
 /// <param name="triangle">Triangle instance.</param>
 /// <param name="p">Point to locate.</param>
 /// <returns>True, if point is inside or on the edge of this triangle.</returns>
 public static bool Contains(this ITriangle triangle, Point p)
 {
     return(Contains(triangle, p.X, p.Y));
 }
示例#40
0
        public void GetShape_Plane(out ITriangle plane)
        {
            if (_shape != ShapeType.Plane)
            {
                throw new InvalidOperationException("This class isn't set up for a plane: " + _shape.ToString());
            }

            plane = _plane;
        }
示例#41
0
 private void TriangleTypes_Load(object sender, EventArgs e)
 {
     //when form is loaded, all dependant class objects are created here using simple factory pattern
     TriangleObj = FactoryTriangle.Create();
 }
示例#42
0
 public void SetShape_Plane(ITriangle plane)
 {
     _shape = ShapeType.Plane;
     _plane = plane;
 }
        private Point3D? GetOffsetDirection(ITriangle dragPlane, Point3D prevPoint, Point3D curPoint, Vector3D slopeUnit)
        {
            Vector3D velocity = curPoint - prevPoint;
            if (Math3D.IsNearZero(velocity))
            {
                return null;
            }

            // Divide it up (doesn't matter what the orth part is, that's throw away.  Only keeping the part along the plane)
            DoubleVector velocitySplit = Math3D.SplitVector(velocity, dragPlane);

            Vector3D slopeScaled = slopeUnit * velocity.Length;     // slope is already a unit vector
            DoubleVector slopeSplit = Math3D.SplitVector(slopeScaled, dragPlane);

            // Rebuild so that the returned point has the appropriate slope away from the plane

            Vector3D velocityNew = velocitySplit.Standard + slopeSplit.Orth;

            return prevPoint + velocityNew;
        }
示例#44
0
        private List <Vertex[]> GetOpenEdges(ITriangle triangle)
        {
            List <ITriangle> neighbours = new List <ITriangle>();

            for (int i = 0; i < 3; i++)
            {
                if (triangle.GetNeighbor(i) != null)
                {
                    neighbours.Add(triangle.GetNeighbor(i));
                }
            }

            List <Vertex[]> openEdges = new List <Vertex[]>()
            {
                new Vertex[2] {
                    triangle.GetVertex(0), triangle.GetVertex(1)
                },
                new Vertex[2] {
                    triangle.GetVertex(1), triangle.GetVertex(2)
                },
                new Vertex[2] {
                    triangle.GetVertex(2), triangle.GetVertex(0)
                },
            };

            foreach (var neighbour in neighbours)
            {
                List <Vertex[]> neighbourEdges = new List <Vertex[]>()
                {
                    new Vertex[2] {
                        neighbour.GetVertex(0), neighbour.GetVertex(1)
                    },
                    new Vertex[2] {
                        neighbour.GetVertex(1), neighbour.GetVertex(2)
                    },
                    new Vertex[2] {
                        neighbour.GetVertex(2), neighbour.GetVertex(0)
                    },
                };

                List <int> edgesToRemove = new List <int>();

                for (int i = 0; i < openEdges.Count; i++)
                {
                    for (int j = 0; j < neighbourEdges.Count; j++)
                    {
                        if (openEdges[i][0] == neighbourEdges[j][0] && openEdges[i][1] == neighbourEdges[j][1] ||
                            openEdges[i][0] == neighbourEdges[j][1] && openEdges[i][1] == neighbourEdges[j][0])
                        {
                            edgesToRemove.Add(i);
                        }
                    }
                }

                for (int i = 0; i < edgesToRemove.Count; i++)
                {
                    openEdges.RemoveAt(edgesToRemove[i] - i);
                }
            }

            return(openEdges);
        }
示例#45
0
        public void GetShape_Circle(out ITriangle plane, out Point3D center, out double radius)
        {
            if (_shape != ShapeType.Circle)
            {
                throw new InvalidOperationException("This class isn't set up for a circle: " + _shape.ToString());
            }

            plane = _plane;
            center = _point;
            radius = _radius;
        }
        private static Tuple<Vector3D?, Vector3D?> SplitVectorUnit(Vector3D vector, ITriangle plane)
        {
            DoubleVector split = Math3D.SplitVector(vector, plane);

            Vector3D? standardUnit = null;
            if (!Math3D.IsNearZero(split.Standard))
            {
                standardUnit = split.Standard.ToUnit();
            }

            Vector3D? orthUnit = null;
            if (!Math3D.IsNearZero(split.Orth))
            {
                orthUnit = split.Orth.ToUnit();
            }

            return Tuple.Create(standardUnit, orthUnit);
        }
示例#47
0
 public void SetShape_Circle(ITriangle plane, Point3D center, double radius)
 {
     _shape = ShapeType.Circle;
     _plane = plane;
     _point = center;
     _radius = radius;
 }
示例#48
0
 private void AddTriangleVertex(ITriangle triangle, IDictionary <string, IJoint> joints, string line)
 {
     string[] parts  = line.Split(' ');
     string[] values = parts[1].Split(',');
     triangle.AddVertex(joints[parts[0]], new PointF(Convert.ToSingle(values[0]), Convert.ToSingle(values[1])));
 }
示例#49
0
        private static Point3D? CastRay_Plane(ITriangle plane, RayHitTestParameters mouseDownClickRay, RayHitTestParameters mouseDownCenterRay, RayHitTestParameters currentClickRay)
        {
            // This is the offset along the drag plane from the center to mouse down click
            Vector3D offset;

            Point3D? mouseDownClickPoint = Math3D.GetIntersection_Plane_Line(plane, mouseDownClickRay.Origin, mouseDownClickRay.Direction);
            Point3D? mouseDownCenterPoint = Math3D.GetIntersection_Plane_Line(plane, mouseDownCenterRay.Origin, mouseDownCenterRay.Direction);

            if (mouseDownClickPoint != null && mouseDownCenterPoint != null)
            {
                offset = mouseDownCenterPoint.Value - mouseDownClickPoint.Value;
            }
            else
            {
                // The click ray is parallel to the drag plane.  This should be extremely rare
                offset = new Vector3D(0, 0, 0);
            }

            // Now that the offset is known, project the current click ray onto the drag plane
            Point3D? retVal = Math3D.GetIntersection_Plane_Line(plane, currentClickRay.Origin, currentClickRay.Direction);

            if (retVal != null)
            {
                return retVal.Value + offset;
            }
            else
            {
                return null;
            }
        }
示例#50
0
文件: testWork.cs 项目: Demorgl/hello
        public double CalcTriangleSquare(ITriangle triangle)
        {
            double p = (triangle.SideA + triangle.SideB + triangle.SideC) / 2;

            return Math.Sqrt(p * (p - triangle.SideA) * (p - triangle.SideB) * (p - triangle.SideC));
        }
示例#51
0
        private static Point3D? CastRay_PlaneLimited(ITriangle plane, RayHitTestParameters mouseDownClickRay, RayHitTestParameters mouseDownCenterRay, RayHitTestParameters currentClickRay, RayHitTestParameters cameraLook)
        {
            // They are looking along the plane, so snap to a line instead of a plane
            RayHitTestParameters snapLine = CastRay_PlaneLimitedSprtGetSnapLine(plane, cameraLook.Direction);		// the returned vector is used like 3 bools, with only one axis set to true
            if (snapLine == null)
            {
                return null;
            }

            double dummy1;
            return CastRay_Line(out dummy1, snapLine.Origin, snapLine.Direction, mouseDownClickRay, mouseDownCenterRay, currentClickRay);
        }
示例#52
0
 public ITriangle[] Process(ITriangle triangle)
 {
     return(TriangleFun(ClipPolygon(triangle.points)));
 }
示例#53
0
 /// <summary>
 /// Constructor of a chain-ladder model given a run-off triangle.
 /// </summary>
 /// <param name="triangle">Cumulative triangle to be developed.</param>
 public ChainLadder(ITriangle triangle)
     : base(TriangleConverter <CumulativeTriangle> .Convert(triangle))
 {
     _factors = new Lazy <IReadOnlyList <decimal> >(CalculateFactors);
 }
示例#54
0
 public SierpinskiFractalController(ILogger <SierpinskiFractalController> logger, ITriangle triangleFractal)
 {
     _logger          = logger;
     _triangleFractal = triangleFractal;
 }
示例#55
0
 public NamedTriangle(ITriangle triangle, string name)
 {
     Triangle = triangle;
     Name     = name;
 }
        private static Tuple<Point3D, Point3D> GetHit(ITriangle[] convexHull, Point3D shotStart, Vector3D shotDirection, double percent)
        {
            var intersections = Math3D.GetIntersection_Hull_Ray(convexHull, shotStart, shotDirection);

            if (intersections.Length != 2)
            {
                return (Tuple<Point3D, Point3D>)null;
            }

            Vector3D penetrate = (intersections[1].Item1 - intersections[0].Item1) * percent;

            return Tuple.Create(intersections[0].Item1, intersections[0].Item1 + penetrate);
        }
        private void grdViewPort_MouseDown(object sender, MouseButtonEventArgs e)
        {
            const double CLICKDISTANCE = BOUNDRYSIZE / 8;

            try
            {
                if (e.ChangedButton != MouseButton.Left)
                {
                    // All the special logic in this method is for the left button
                    return;
                }

                // Fire a ray at the mouse point
                Point clickPoint2D = e.GetPosition(grdViewPort);

                RayHitTestParameters clickRay;
                List<MyHitTestResult> hits = UtilityWPF.CastRay(out clickRay, clickPoint2D, _viewport, _camera, _viewport, false);

                // Figure out where to place the point
                Point3D clickPoint3D;
                ITriangle clickPlane = null;
                if (hits != null && hits.Count > 0)
                {
                    // They clicked on something, so use that
                    clickPoint3D = hits[0].Point;
                }
                else
                {
                    //TODO: If there is a mothership, choose a point in a plane that goes through it (orth to the click ray)
                    //
                    // If there isn't, but they click near a swarm, use that plane
                    //
                    // Or if they click near something (like an asteroid)

                    double? clickDistNearSwarm = GetClickDistanceNearSwarm(clickRay);

                    double clickDist;
                    if (clickDistNearSwarm == null)
                    {
                        clickDist = Math.Max(CLICKDISTANCE, _camera.Position.ToVector().Length / 1.1);
                    }
                    else
                    {
                        clickDist = clickDistNearSwarm.Value;
                    }

                    clickPoint3D = clickRay.Origin + clickRay.Direction.ToUnit(false) * clickDist;
                }

                // Update the click plane
                if (clickPlane == null)
                {
                    Vector3D standard = Math3D.GetArbitraryOrhonganal(clickRay.Direction);
                    Vector3D orth = Vector3D.CrossProduct(standard, clickRay.Direction);
                    clickPlane = new Triangle(clickPoint3D, clickPoint3D + standard, clickPoint3D + orth);
                }

                // Store the point and plane
                _strokes.AddPointToStroke(clickPoint3D);
                _clickPlane = clickPlane;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString(), this.Title, MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }
 public RectangleAdapter(ITriangle triangle)
 {
     this.triangle = triangle;
 }
 public bool Detector(ITriangle concreteTriangle)
 {
     triangle = concreteTriangle;
     return(triangle.IsTriangle());
 }
        private void grdViewPort_MouseUp(object sender, MouseButtonEventArgs e)
        {
            try
            {
                if (e.ChangedButton != MouseButton.Left)
                {
                    // All the special logic in this method is for the left button
                    return;
                }

                _clickPlane = null;
                _strokes.StopStroke();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString(), this.Title, MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }