Esempio n. 1
0
        private KeyValuePair <HalfEdge, LinesIntersection2>?FindFirstIntersection(Seed seed, float length)
        {
            Contract.Requires(seed != null);
            Contract.Ensures(!Contract.Result <KeyValuePair <HalfEdge, LinesIntersection2>?>().HasValue || Contract.Result <KeyValuePair <HalfEdge, LinesIntersection2>?>().Value.Key != null);

            //Create the bounds of this new line (inflated slightly, just in case it's perfectly axis aligned)
            var a       = seed.Origin.Position;
            var b       = seed.Origin.Position + seed.Direction * length;
            var bounds  = new BoundingRectangle(Vector2.Min(a, b), Vector2.Max(a, b)).Inflate(0.2f);
            var segment = new LineSegment2(a, b);

            //Find all edges which intersect this bounds, then test them one by one for intersection
            var results = _mesh
                          .FindEdges(bounds)
                          .Select(e => new KeyValuePair <HalfEdge, LinesIntersection2?>(e, e.Segment.Intersects(segment)))
                          .Where(i => i.Value.HasValue)
                          .Select(i => new KeyValuePair <HalfEdge, LinesIntersection2>(i.Key, i.Value.Value));

            //Find the first intersection from all the results
            KeyValuePair <HalfEdge, LinesIntersection2>?result = null;

            foreach (var candidate in results)
            {
                if (result == null || candidate.Value.DistanceAlongB < result.Value.Value.DistanceAlongB)
                {
                    result = candidate;
                }
            }
            return(result);
        }
Esempio n. 2
0
        private KeyValuePair <HalfEdge, float>?FindFirstParallelEdge(Seed seed, float length, float distance, float parallelThreshold)
        {
            Contract.Requires(seed != null);

            var start   = seed.Origin.Position;
            var end     = seed.Origin.Position + seed.Direction * length;
            var segment = new LineSegment2(start, end);

            //Calculate the expanded bounds to query. This is as wide as the parallel check distance
            var p           = seed.Direction.Perpendicular() * distance / 2;
            var a           = start + p;
            var b           = start - p;
            var c           = end + p;
            var d           = end - p;
            var queryBounds = new BoundingRectangle(
                Vector2.Min(Vector2.Min(a, b), Vector2.Min(c, d)),
                Vector2.Max(Vector2.Max(a, b), Vector2.Max(c, d))
                );

            //now get all lines which intersect this bounds and check them for parallelism
            var candidates = _mesh.FindEdges(queryBounds);

            KeyValuePair <HalfEdge, float>?firstParallel = null;

            foreach (var candidate in candidates)
            {
                var dirCandidate = candidate.Segment.Line.Direction;
                var dir          = segment.Line.Direction;

                //Dot product directions of lines to check parallelism (compare with threshold)
                var dot = Math.Abs(Vector2.Dot(dir, dirCandidate));
                if (dot > parallelThreshold)
                {
                    //Our query bounds were larger than the actual area we wanted to query (because we're limited to axis aligned bounds)
                    //Check that this line enters the smaller OABB area
                    //We'll do this check by checking if the line segment intersects any of the four OABB segments (AB, BC, CD, DA)

                    if (new LineSegment2(a, b).Intersects(candidate.Segment).HasValue ||
                        new LineSegment2(b, c).Intersects(candidate.Segment).HasValue ||
                        new LineSegment2(c, d).Intersects(candidate.Segment).HasValue ||
                        new LineSegment2(d, a).Intersects(candidate.Segment).HasValue)
                    {
                        //check how far along this segment the parallelism starts

                        var startDist = segment.ClosestPointDistanceAlongSegment(candidate.StartVertex.Position);
                        var endDist   = segment.ClosestPointDistanceAlongSegment(candidate.EndVertex.Position);
                        var minDist   = Math.Min(startDist, endDist);

                        if (firstParallel == null || minDist < firstParallel.Value.Value)
                        {
                            firstParallel = new KeyValuePair <HalfEdge, float>(candidate, minDist);
                        }
                    }
                }
            }

            return(firstParallel);
        }
Esempio n. 3
0
        public BitmapBounds(System.Numerics.Matrix3x2 srcXform, float srcW, float srcH)
        {
            var a = srcXform.Translation;
            var b = XY.Transform(new XY(srcW, 0), srcXform);
            var c = XY.Transform(new XY(srcW, srcH), srcXform);
            var d = XY.Transform(new XY(0, srcH), srcXform);

            var min = XY.Min(XY.Min(XY.Min(a, b), c), d);
            var max = XY.Max(XY.Max(XY.Max(a, b), c), d);

            this.X = (int)min.X;
            this.Y = (int)min.Y;

            this.Width  = (int)max.X + 1 - this.X;
            this.Height = (int)max.Y + 1 - this.Y;
        }