コード例 #1
0
ファイル: Line3.cs プロジェクト: Sunlighter/RationalGeometry
 public bool Contains(Vertex3 pt)
 {
     return(direction.IsParallelTo(pt - origin));
 }
コード例 #2
0
ファイル: Line3.cs プロジェクト: Sunlighter/RationalGeometry
 public Vertex3 NearestPointTo(Vertex3 pt)
 {
     return(origin + ((pt - origin).ComponentAlong(direction)));
 }
コード例 #3
0
 public CH_LineSegment(Vertex3 v1, Vertex3 v2)
 {
     this.v1 = v1;
     this.v2 = v2;
 }
コード例 #4
0
ファイル: Line3.cs プロジェクト: Sunlighter/RationalGeometry
 public Line3(Vertex3 origin, Vector3 direction)
 {
     this.origin    = origin;
     this.direction = direction;
 }
コード例 #5
0
        public static CH_Polyhedron Make(ImmutableList <CH_Polygon> facesAway, Vertex3 v)
        {
            ImmutableList <CH_Polygon> facesAway1 = facesAway;

            foreach (CH_Polygon face in facesAway1)
            {
                if (!(face.Plane.Includes(v)))
                {
                    throw new ArgumentException("Polygons must face away from new point");
                }
            }

            DualIndexedSet <Tuple <Vertex3, Vertex3> > edgeMap    = new DualIndexedSet <Tuple <Vertex3, Vertex3> >(x => new Tuple <Vertex3, Vertex3>(x.Item2, x.Item1));
            ImmutableDictionary <int, int>             edgeToFace = ImmutableDictionary <int, int> .Empty;
            int iEnd = facesAway1.Count;

            for (int i = 0; i < iEnd; ++i)
            {
                foreach (CH_Polygon.Edge edge in facesAway1[i].Edges)
                {
                    var(edgeMap2, eIndex, isNew) = edgeMap.EnsureAdded(new Tuple <Vertex3, Vertex3>(edge.Start, edge.End));
                    edgeMap = edgeMap2;
                    if (edgeToFace.ContainsKey(eIndex))
                    {
                        throw new ArgumentException("Invalid polyhedron (edge traversed in same direction by more than one face)");
                    }
                    edgeToFace = edgeToFace.Add(eIndex, i);
                }
            }
            ImmutableDictionary <Vertex3, int> startToEdge = ImmutableDictionary <Vertex3, int> .Empty;
            int iEnd2 = edgeMap.Count;

            for (int i = 0; i < iEnd2; ++i)
            {
                if (!(edgeToFace.ContainsKey(i)))
                {
                    startToEdge = startToEdge.Add(edgeMap[i].Item1, i);
                }
                if (!(edgeToFace.ContainsKey(~i)))
                {
                    startToEdge = startToEdge.Add(edgeMap[~i].Item1, ~i);
                }
            }

            ImmutableList <int> edges = ImmutableList <int> .Empty;

            edges = edges.Add(startToEdge.First().Value);
            int sentinel = startToEdge.Count;

            while (true)
            {
                Vertex3 end = edgeMap[edges[edges.Count - 1]].Item2;
                if (!(startToEdge.ContainsKey(end)))
                {
                    throw new ArgumentException("Unable to walk loose edges");
                }
                int nextEdge = startToEdge[end];
                if (nextEdge == edges[0])
                {
                    break;
                }
                edges = edges.Add(nextEdge);
                --sentinel;
                if (sentinel < 0)
                {
                    throw new InvalidOperationException("Loose edges don't loop properly");
                }
            }
            if (edges.Count != startToEdge.Count)
            {
                throw new InvalidOperationException("Not all loose edges were used");
            }

            sentinel = edges.Count;
            Func <int, int, bool> inSamePlane = delegate(int edge1, int edge2)
            {
                Tuple <Vertex3, Vertex3> e1 = edgeMap[edge1];
                Tuple <Vertex3, Vertex3> e2 = edgeMap[edge2];
                Plane3 p = Plane3.FromThreePoints(e1.Item1, e1.Item2, v);
                return(p.Contains(e2.Item1) && p.Contains(e2.Item2));
            };

            while (true)
            {
                if (!inSamePlane(edges[0], edges[edges.Count - 1]))
                {
                    break;
                }
                int x = edges[0];
                edges = edges.RemoveAt(0).Add(x);
                --sentinel;
                if (sentinel < 0)
                {
                    throw new InvalidOperationException("Loose edges all lie in the same plane as the vertex (?!)");
                }
            }

            ImmutableList <CH_Polygon> newPolys = ImmutableList <CH_Polygon> .Empty;
            ImmutableList <Vertex3>    corners  = ImmutableList <Vertex3> .Empty;
            int?lastEdge = null;

            Action flush = delegate()
            {
                corners  = corners.Add(edgeMap[lastEdge.Value].Item2).Add(v);
                newPolys = newPolys.Add(new CH_Polygon(corners));
            };

            Action <int> addEdge = delegate(int edge)
            {
                if (lastEdge == null || inSamePlane(edge, lastEdge.Value))
                {
                    corners  = corners.Add(edgeMap[edge].Item1);
                    lastEdge = edge;
                }
                else
                {
                    flush();
                    corners = ImmutableList <Vertex3> .Empty
                              .Add(edgeMap[edge].Item1);

                    lastEdge = edge;
                }
            };

            foreach (int edge in edges)
            {
                addEdge(edge);
            }
            flush();

            return(new CH_Polyhedron(newPolys.AddRange(facesAway1)));
        }
コード例 #6
0
 public CH_SinglePoint(Vertex3 vertex)
 {
     this.vertex = vertex;
 }
コード例 #7
0
 public override PointStatus GetPointStatus(Vertex3 vt)
 {
     return(PointStatus.Outside);
 }
コード例 #8
0
ファイル: Plane3.cs プロジェクト: Sunlighter/RationalGeometry
 public bool Contains(Vertex3 pt)
 {
     return(normal.IsPerpendicularTo(pt - origin));
 }
コード例 #9
0
 public abstract PointStatus GetPointStatus(Vertex3 vt);
コード例 #10
0
 public abstract ConvexHull Add(Vertex3 vt);
コード例 #11
0
ファイル: Plane3.cs プロジェクト: Sunlighter/RationalGeometry
 public bool Excludes(Vertex3 pt)
 {
     return(this.ScaledDistanceTo(pt) > BigRational.Zero);
 }
コード例 #12
0
ファイル: Plane3.cs プロジェクト: Sunlighter/RationalGeometry
 public BigRational ScaledDistanceTo(Vertex3 pt)
 {
     return((pt - origin).ScaledLengthAlong(normal));
 }
コード例 #13
0
ファイル: Plane3.cs プロジェクト: Sunlighter/RationalGeometry
 public Vertex3 NearestPointTo(Vertex3 pt)
 {
     return(origin + ((pt - origin).ComponentOrtho(normal)));
 }
コード例 #14
0
ファイル: Line3.cs プロジェクト: Sunlighter/RationalGeometry
 public BigRational ScaledCoordinateOf(Vertex3 pt)
 {
     return((pt - origin).ScaledLengthAlong(direction));
 }
コード例 #15
0
 public override ConvexHull Add(Vertex3 vt)
 {
     return(new CH_SinglePoint(vt));
 }
コード例 #16
0
ファイル: Line3.cs プロジェクト: Sunlighter/RationalGeometry
 public static Line3 FromTwoPoints(Vertex3 a, Vertex3 b)
 {
     return(new Line3(a, b - a));
 }
コード例 #17
0
ファイル: Plane3.cs プロジェクト: Sunlighter/RationalGeometry
 public Plane3(Vertex3 origin, Vector3 normal)
 {
     this.origin = origin;
     this.normal = normal;
 }