コード例 #1
0
ファイル: GraphPoint.cs プロジェクト: danm36/CLRGraph
        public GraphPoint(GraphPoint other)
        {
            if (other == null)
                return;

            index = DataSeries_Funcs.GetCurrentDataSeries().GetPointCount();

            pos = other.pos;

            if (other.pendingEdges != null)
            {
                foreach (int edge in other.pendingEdges)
                    AddEdge(edge);
            }

            if (other.edges != null)
            {
                foreach (GraphPoint edge in other.edges)
                    AddEdge(edge);
            }
        }
コード例 #2
0
ファイル: DataSeries.cs プロジェクト: danm36/CLRGraph
        public GraphPoint[] GetEdgemostPoints(bool returnClones = false)
        {
            if(DataPoints.Count == 0)
                return null;

            GraphPoint[] ret = new GraphPoint[] { (GraphPoint)DataPoints[0], (GraphPoint)DataPoints[0], (GraphPoint)DataPoints[0], (GraphPoint)DataPoints[0], (GraphPoint)DataPoints[0], (GraphPoint)DataPoints[0] };
            GraphPoint curPoint = null;

            for (int i = 0; i < DataPoints.Count; i++)
            {
                curPoint = (GraphPoint)DataPoints[i];

                if (curPoint.pos.X < ret[0].pos.X)
                    ret[0] = curPoint;
                if (curPoint.pos.X > ret[1].pos.X)
                    ret[1] = curPoint;

                if (curPoint.pos.Y < ret[2].pos.Y)
                    ret[2] = curPoint;
                if (curPoint.pos.Y > ret[3].pos.Y)
                    ret[3] = curPoint;

                if (curPoint.pos.Z < ret[4].pos.Z)
                    ret[4] = curPoint;
                if (curPoint.pos.Z > ret[5].pos.Z)
                    ret[5] = curPoint;

            }

            if (returnClones)
            {
                for (int i = 0; i < ret.Length; i++)
                    ret[i] = new GraphPoint(ret[i]);
            }

            return ret;
        }
コード例 #3
0
ファイル: GraphPoint.cs プロジェクト: danm36/CLRGraph
        public List<uint> FormTrianglesWith(GraphPoint other, List<GraphPoint> alreadyMadeEdgesWith, bool bForQuadRendering = false)
        {
            List<uint> results = new List<uint>();
            if (edges == null || other.edges == null || other.hasSetIndices)
                return results;

            List<GraphPoint> intersection = edges.Intersect(other.edges).ToList();

            for (int i = 0; i < intersection.Count; i++)
            {
                if (intersection[i].hasSetIndices || intersection[i] == this || intersection[i] == other || alreadyMadeEdgesWith.Contains(intersection[i]))
                    continue;

                if (bForQuadRendering)
                    results.Add((uint)index);
                results.Add((uint)index);
                results.Add((uint)other.index);
                results.Add((uint)intersection[i].index);
            }

            return results;
        }
コード例 #4
0
ファイル: GraphPoint.cs プロジェクト: danm36/CLRGraph
 public double DistanceFromSq(GraphPoint other)
 {
     return (pos - other.pos).LengthSquared;
 }
コード例 #5
0
ファイル: GraphPoint.cs プロジェクト: danm36/CLRGraph
        public List<uint> FormQuadsWith(GraphPoint other)
        {
            List<uint> results = new List<uint>();
            if (edges == null || other.hasSetIndices)
                return results;

            foreach (GraphPoint edge1 in edges)
            {
                if (edge1.edges == null)
                    continue;

                foreach (GraphPoint edge2 in edges)
                {
                    if (edge1 == edge2 || edge2.edges == null)
                        continue;

                    List<GraphPoint> intersection = edge1.edges.Intersect(edge2.edges).ToList();

                    if (intersection.Count > 0)
                    {
                        for (int i = 0; i < intersection.Count; i++)
                        {
                            if (intersection[i].hasSetIndices || intersection[i] == this || intersection[i] == edge1 || intersection[i] == edge2)
                                continue;

                            results.Add((uint)index);
                            results.Add((uint)edge1.index);
                            results.Add((uint)intersection[i].index);
                            results.Add((uint)edge2.index);
                        }
                    }
                    else if (edge1.edges.Contains(edge2)) //Add a tri instead if possible
                    {
                        results.Add((uint)index);
                        results.Add((uint)index);
                        results.Add((uint)edge1.index);
                        results.Add((uint)edge2.index);
                    }
                }
            }

            return results;
        }
コード例 #6
0
ファイル: GraphPoint.cs プロジェクト: danm36/CLRGraph
 public double DistanceFrom(GraphPoint other)
 {
     return (pos - other.pos).Length;
 }
コード例 #7
0
ファイル: GraphPoint.cs プロジェクト: danm36/CLRGraph
        public double DistanceFromLineSegSq(GraphPoint segA, GraphPoint segB)
        {
            Vector3 ta = (segA.pos - this.pos);
            Vector3 tb = (segB.pos - this.pos);
            Vector3 ab = (segB.pos - segA.pos);

            float e = Vector3.Dot(tb, ta);

            if (e < 0)
                return Vector3.Dot(tb, tb);

            float f = Vector3.Dot(ta, ta);

            if (e >= f)
                return Vector3.Dot(ab, ab);

            return Vector3.Dot(tb, tb) - e * e / f;
        }
コード例 #8
0
ファイル: GraphPoint.cs プロジェクト: danm36/CLRGraph
 public static GraphPoint GetMidpoint(GraphPoint a, GraphPoint b)
 {
     return new GraphPoint(a.pos + (b.pos - a.pos) * 0.5f);
 }
コード例 #9
0
ファイル: GraphPoint.cs プロジェクト: danm36/CLRGraph
        public void AddEdge(GraphPoint edge)
        {
            if (edges == null)
                edges = new List<GraphPoint>();

            if (!edges.Contains(edge))
                edges.Add(edge);
        }
コード例 #10
0
ファイル: HullGenerator.cs プロジェクト: danm36/CLRGraph
        public static DataSeries CreateHullFromSeries(DataSeries source, int iterationCount)
        {
            GraphPoint[] edges = source.GetEdgemostPoints(true);

            if (edges == null)
                return null;

            MaxIterationCount = iterationCount;

            for (int i = 0; i < edges.Length; i++)
                edges[i] = new GraphPoint(edges[i]);

            PendingFaces.Clear();
            ActiveFaces.Clear();

            List<GraphPoint> AvailablePoints = new List<GraphPoint>();
            foreach (object point in source.DataPoints)
                AvailablePoints.Add(new GraphPoint((GraphPoint)point));

            //DataSeries hullSeries = new DataSeries(source.Name + "_Hull", source.DrawColor);
            DataSeries hullSeries = new DataSeries(source.Name + "_Hull", null);
            GraphPoint baseLine1 = null, baseLine2 = null, farthestBaseLine = null, farthestBaseFace = null;

            double bestDist = 0, curDist = 0;
            for (int i = 0; i < edges.Length; i++)
            {
                for (int j = 1; j < edges.Length; j++)
                {
                    if (i == j)
                        continue;

                    curDist = edges[i].DistanceFromSq(edges[j]);
                    if (curDist > bestDist)
                    {
                        baseLine1 = edges[i];
                        baseLine2 = edges[j];
                        bestDist = curDist;
                    }
                }
            }

            bestDist = 0;
            for (int i = 0; i < edges.Length; i++)
            {
                if (edges[i].pos == baseLine1.pos || edges[i].pos == baseLine2.pos)
                    continue;

                curDist = edges[i].DistanceFromLineSegSq(baseLine1, baseLine2);
                if (curDist > bestDist)
                {
                    farthestBaseLine = edges[i];
                    bestDist = curDist;
                }
            }

            Vector3 triangleNormal = GetTriangleNormal(baseLine1.pos, baseLine2.pos, farthestBaseLine.pos);
            Vector3 triangleCenter = GetTriangleCenter(baseLine1.pos, baseLine2.pos, farthestBaseLine.pos);
            float triangleDot = Vector3.Dot(triangleNormal, baseLine1.pos);
            bestDist = 0;

            bool bFlipWinding = false;

            for (int i = 0; i < AvailablePoints.Count; i++)
            {
                if (AvailablePoints[i] == baseLine1 || AvailablePoints[i] == baseLine2 || AvailablePoints[i] == farthestBaseLine)
                    continue;

                //curDist = (AvailablePoints[i].pos - triangleCenter).LengthSquared;
                curDist = Math.Abs(Vector3.Dot(AvailablePoints[i].pos, triangleNormal) - triangleDot);
                if (curDist > bestDist)
                {
                    farthestBaseFace = AvailablePoints[i];
                    bestDist = curDist;

                    bFlipWinding = Vector3.Dot(triangleNormal, (AvailablePoints[i].pos - triangleCenter).Normalized()) > 0;
                }
            }

            if (farthestBaseFace == null) //2D series
            {
                ClojureEngine.Log("[HULL BUILD] Series is 2D, and the hull builder cannot currently work with 2D data sets");
                return null;
            }

            if (bFlipWinding)
            {
                GraphPoint temp = baseLine1;
                baseLine1 = baseLine2;
                baseLine2 = temp;
            }

            List<HullFace> initialFaces = new List<HullFace>() {
                new HullFace(baseLine2, baseLine1, farthestBaseLine),
                new HullFace(baseLine1, baseLine2, farthestBaseFace),
                new HullFace(baseLine1, farthestBaseFace, farthestBaseLine),
                new HullFace(baseLine2, farthestBaseLine, farthestBaseFace),
             };

            AssignPointsToFaces(AvailablePoints, initialFaces);

            for (int i = 0; i < initialFaces.Count; i++)
            {
                ActiveFaces.Add(initialFaces[i]);
                if(initialFaces[i].points.Count > 0)
                    PendingFaces.Add(initialFaces[i]);
            }

            BuildFromStack(0);

            int unassignedPoints = 0;
            for (int i = 0; i < ActiveFaces.Count; i++)
            {
                ActiveFaces[i].a.AddEdges(ActiveFaces[i].b, ActiveFaces[i].c);
                ActiveFaces[i].b.AddEdges(ActiveFaces[i].a, ActiveFaces[i].c);
                ActiveFaces[i].c.AddEdges(ActiveFaces[i].a, ActiveFaces[i].b);

                hullSeries.AddDataPoints(new List<GraphPoint>() { ActiveFaces[i].a, ActiveFaces[i].b, ActiveFaces[i].c });

                unassignedPoints += ActiveFaces[i].points.Count;

                //if(ActiveFaces[i].points.Count > 0)
                //    new DataSeries(PersistentVector.create1(ActiveFaces[i].points));
            }

            if(unassignedPoints > 0)
                ClojureEngine.Log("[HULL BUILD] " + unassignedPoints + " points remain outside the hull");
            else
                ClojureEngine.Log("[HULL BUILD] All points are contained within the hull");

            hullSeries.SetDrawMode(DrawMode.Triangles);
            return hullSeries;
        }
コード例 #11
0
ファイル: HullGenerator.cs プロジェクト: danm36/CLRGraph
 public bool IsAVertex(GraphPoint p)
 {
     return p == a || p == b || p == c;
 }
コード例 #12
0
ファイル: HullGenerator.cs プロジェクト: danm36/CLRGraph
 public HullFace(GraphPoint nA, GraphPoint nB, GraphPoint nC, List<GraphPoint> nMyPoints)
     : this(nA, nB, nC)
 {
     points = nMyPoints;
 }
コード例 #13
0
ファイル: HullGenerator.cs プロジェクト: danm36/CLRGraph
            public HullFace(GraphPoint nA, GraphPoint nB, GraphPoint nC)
            {
                a = nA;
                b = nB;
                c = nC;

                ab = new HullEdge(a, b);
                bc = new HullEdge(b, c);
                ca = new HullEdge(c, a);

                normal = GetTriangleNormal(a.pos, b.pos, c.pos);
                center = GetTriangleCenter(a.pos, b.pos, c.pos);

                points = new List<GraphPoint>();
            }
コード例 #14
0
ファイル: HullGenerator.cs プロジェクト: danm36/CLRGraph
 public HullEdge(GraphPoint nA, GraphPoint nB)
 {
     a = nA;
     b = nB;
 }