Пример #1
0
        /// <summary>
        /// Funkcja obliczająca pole teoriomnogościowej sumy prostokątów
        /// </summary>
        /// <returns>Pole teoriomnogościowej sumy prostokątów</returns>
        /// <param name="rectangles">Tablica z prostokątami, których teoriomnogościowej sumy pole należy policzyć</param>
        /// Każdy prostokąt opisany jest przez cztery wartości: minimalna współrzędna X, minimalna współrzędna Y,
        /// maksymalna współrzędna X, maksymalna współrzędna Y.
        /// </param>
        public double RectanglesUnionArea(Geometry.Rectangle[] rectangles)
        {
            // int - indeks odcinka, bool - lewy bok (true), pawy bok (false)
            List <Tuple <Geometry.Segment, bool> >          segments = new List <Tuple <Geometry.Segment, bool> >();
            Dictionary <Geometry.Segment, Geometry.Segment> Dict     = new Dictionary <Geometry.Segment, Geometry.Segment>();

            foreach (Geometry.Rectangle rectange in rectangles)
            {
                Geometry.Segment s1 = new Geometry.Segment(new Geometry.Point(rectange.MinX, rectange.MinY),
                                                           new Geometry.Point(rectange.MinX, rectange.MaxY));
                Geometry.Segment s2 = new Geometry.Segment(new Geometry.Point(rectange.MaxX, rectange.MinY),
                                                           new Geometry.Point(rectange.MaxX, rectange.MaxY));
                segments.Add(new Tuple <Geometry.Segment, bool>(s1, true));
                segments.Add(new Tuple <Geometry.Segment, bool>(s2, false));
                //if (!Dict.ContainsKey(s2))
                Dict.Add(s2, s1);
            }
            segments.Sort((s1, s2) => s1.Item1.ps.x.CompareTo(s2.Item1.ps.x));
            List <Geometry.Segment> ptr = new List <Geometry.Segment>();

            ptr.Add(segments[0].Item1);
            double rectanglesUnionArea = 0;
            double x1 = segments[0].Item1.ps.x;

            for (int i = 1; i < segments.Count; i++)
            {
                double x2 = segments[i].Item1.ps.x;
                double D  = 0;
                if (ptr.Count > 0)
                {
                    D = VerticalSegmentsUnionLength(ptr.ToArray());
                    rectanglesUnionArea += Math.Abs(x2 - x1) * D;
                    x1 = x2;
                }
                if (segments[i].Item2)
                {
                    x1 = segments[i].Item1.ps.x;
                    ptr.Add(segments[i].Item1);
                }
                else
                {
                    //int nrTmp = dict2[segments[i].Item1];
                    //Geometry.Segment tmpSegment = dict[nrTmp];
                    Geometry.Segment tmpSegment = Dict[segments[i].Item1];
                    ptr.Remove(tmpSegment);
                }
            }
            return(rectanglesUnionArea);
        }
Пример #2
0
        /// <summary>
        /// Funkcja obliczająca pole teoriomnogościowej sumy prostokątów
        /// </summary>
        /// <returns>Pole teoriomnogościowej sumy prostokątów</returns>
        /// <param name="rectangles">Tablica z prostokątami, których teoriomnogościowej sumy pole należy policzyć.
        /// Każdy prostokąt opisany jest przez cztery wartości: minimalna współrzędna X, minimalna współrzędna Y,
        /// maksymalna współrzędna X, maksymalna współrzędna Y.
        /// </param>
        public double RectanglesUnionArea(Geometry.Rectangle[] rectangles)
        {
            var    events = new List <SweepEvent>();
            var    lines  = new Dictionary <int, Geometry.Segment>();
            double xCoord = 0;
            double area   = 0;
            double D      = 0;

            for (int i = 0; i < rectangles.Length; i++)
            {
                events.Add(new SweepEvent(rectangles[i].MinX, true, i));
                events.Add(new SweepEvent(rectangles[i].MaxX, false, i));
            }
            events.Sort();

            foreach (var e in events)
            {
                area += (e.Coord - xCoord) * D;
                if (e.IsStartingPoint)
                {
                    var seg = new Geometry.Segment
                              (
                        new Geometry.Point(e.Coord, rectangles[e.Idx].MinY),
                        new Geometry.Point(e.Coord, rectangles[e.Idx].MaxY)
                              );
                    lines.Add(e.Idx, seg);
                }
                else
                {
                    lines.Remove(e.Idx);
                }
                xCoord = e.Coord;
                D      = VerticalSegmentsUnionLength(lines.Values.ToArray());
            }

            return(area);
        }