多边形最大内接矩形算法C# java

java版

/*
 * Swing version.
 */

import javax.swing.*;
import javax.swing.border.Border;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*; //Vector
import java.lang.*; //Math

/*
 * Displays a framed area.  When the user clicks within
 * the area, this program displays a filled rectangle
 * and a string indicating the coordinates where the
 * click occurred.
 */

public class RectangleFind extends JApplet {
    JLabel label;
    JPanel buttonPane;
    JButton b1;
    JButton b2;
    JButton b3;
    JButton b4;

    ConvexHull polygon;
    RectangleArea rectangleArea;
    MyListener myListener;

    // Called only when this is run as an applet.
    public void init() {
        buildUI(getContentPane());
    }

    void buildUI(final Container container) {
        container.setLayout(new BoxLayout(container, BoxLayout.Y_AXIS));

        label = new JLabel("Click within the framed area.");
        container.add(label);

        polygon = new ConvexHull();

        rectangleArea = new RectangleArea(this);

        myListener = new MyListener(this);
        rectangleArea.addMouseListener(myListener);

        // addMouseListener(this);

        container.add(rectangleArea);

        buttonPane = new JPanel();
        // buttonPane.setPreferredSize(new Dimension(100, 25));
        buttonPane.setLayout(new BoxLayout(buttonPane, BoxLayout.X_AXIS));
        buttonPane.setBorder(BorderFactory.createEmptyBorder(1, 1, 1, 1));

        b1 = new JButton("Reset");
        b1.addActionListener(new ActionListener() {
            public void actionPerformed(final ActionEvent e) {
                polygon = new ConvexHull();
                rectangleArea.repaint();
                updateLabel(0);
            }
        });
        b2 = new JButton("Find Largest Rectangle");
        // b2.setEnabled(false );
        b2.addActionListener(new ActionListener() {
            public void actionPerformed(final ActionEvent e) {
                // polygon = new ConvexHull();
                polygon.computeLargestRectangle();
                rectangleArea.displayedRect = 6;
                polygon.status = 16;
                rectangleArea.repaint();
                // updateLabel(16);
                // label.setText("16");
            }
        });

        b3 = new JButton("Step");
        b3.addActionListener(new ActionListener() {
            public void actionPerformed(final ActionEvent e) {
                if (polygon.changed) {
                    // System.out.println("caught");
                    polygon.computeLargestRectangle();
                }
                // System.out.println(polygon.changed);
                rectangleArea.displayedRect++;
                if (rectangleArea.displayedRect >= 7) {
                    rectangleArea.displayedRect = 0;
                }
                polygon.status = rectangleArea.displayedRect + 10;
                rectangleArea.repaint();
            }
        });
        b4 = new JButton("Test");
        b4.addActionListener(new ActionListener() {
            public void actionPerformed(final ActionEvent e) {
                polygon.RectList.add(new Rectangle(100, 100, 50, 100));
                rectangleArea.displayedRect = 7;
                rectangleArea.repaint();
            }
        });
        buttonPane.add(b1);
        buttonPane.add(Box.createHorizontalStrut(10)); // createHorizontalGlue();
        buttonPane.add(b2);
        buttonPane.add(b3);
        buttonPane.add(b4);

        container.add(buttonPane);

        // Align the left edges of the components.
        rectangleArea.setAlignmentX(LEFT_ALIGNMENT);
        label.setAlignmentX(LEFT_ALIGNMENT); // unnecessary, but doesn't hurt
        buttonPane.setAlignmentX(LEFT_ALIGNMENT);
    }

    /* display a predefined message for a given msg state */
    public void updateLabel(final int msg) {
        if (msg == 0) {
            label.setText("Click within the framed area to add points");
        } else if (msg == 1) {
            label.setText("Point added, click to add more points");
        } else if (msg == 2) {
            label.setText("point added to polygon");
        } else if (msg == 3) {
            label.setText("point inside not added");
        } else if (msg == 10) {
            label.setText("Largest rectangle with corners on A and C only");
        } else if (msg == 11) {
            label.setText("Largest rectangle with corners on B and D only");
        } else if (msg == 12) {
            label.setText("Largest rectangle with corners on A,B and C");
        } else if (msg == 13) {
            label.setText("Largest rectangle with corners on A,B and D");
        } else if (msg == 14) {
            label.setText("Largest rectangle with corners on A,C and D");
        } else if (msg == 15) {
            label.setText("Largest rectangle with corners on B,C and D");
        } else if (msg == 16) {
            label.setText("Largest rectangle in polygon");
        } else {
            label.setText("Click to add points");
        }

    }

    // Called only when this is run as an application.
    public static void main(final String[] args) {
        final JFrame f = new JFrame("RectangleFind");
        f.addWindowListener(new WindowAdapter() {
            public void windowClosing(final WindowEvent e) {
                System.exit(0);
            }
        });
        final RectangleFind controller = new RectangleFind();
        controller.buildUI(f.getContentPane());
        f.pack();
        f.setVisible(true);
    }

}

class MyListener extends MouseInputAdapter {
    RectangleFind rf;

    public MyListener(final RectangleFind rf) {
        this.rf = rf;
    }

    public void mousePressed(final MouseEvent e) {

        final int x = e.getX();
        final int y = e.getY();

        final GeomPoint p = new GeomPoint(x, y);

        // this.polygon.add(p);
        if (this.rf.polygon.size() < 2) {
            this.rf.polygon.add(p);
            this.rf.polygon.status = 1;
            this.rf.polygon.changed = true;
        }

        else if (this.rf.polygon.size() == 2) {
            final GeomPoint ha = (GeomPoint) this.rf.polygon.elementAt(0);
            final GeomPoint hb = (GeomPoint) this.rf.polygon.elementAt(1);
            if (this.rf.polygon.onLeft(ha, hb, p)) {
                this.rf.polygon.add(p);
                this.rf.polygon.status = 2;
                this.rf.polygon.changed = true;
            } else {
                this.rf.polygon.insertElementAt(p, 1);
                this.rf.polygon.status = 2;
            }
        } else {
            if (this.rf.polygon.addPointToHull(p)) {
                this.rf.polygon.status = 2;
            } else {
                this.rf.polygon.status = 3;
            }
        }

        this.rf.rectangleArea.repaint();
        // this.rectangleArea.paintComponent(g);

    }

    public void mouseClicked(final MouseEvent e) {
    }

    public void mouseEntered(final MouseEvent e) {
    }

    public void mouseExited(final MouseEvent e) {
    }

    public void mouseReleased(final MouseEvent e) {
    }

}

class RectangleArea extends JPanel {

    // ConvexHull hull = new ConvexHull();
    RectangleFind controller;
    Dimension preferredSize = new Dimension(600, 450);
    int rectWidth = 50;
    int rectHeight = 50;
    public int displayedRect = 6;

    public RectangleArea(final RectangleFind controller) {
        this.controller = controller;

        final Border raisedBevel = BorderFactory.createRaisedBevelBorder();
        final Border loweredBevel = BorderFactory.createLoweredBevelBorder();
        final Border compound = BorderFactory.createCompoundBorder(raisedBevel, loweredBevel);
        setBorder(compound);

    }

    public Dimension getPreferredSize() {
        return preferredSize;
    }

    public void paintComponent(final Graphics g) {
        super.paintComponent(g); // paint background

        final ConvexHull hull = this.controller.polygon;

        GeomPoint point = null;
        GeomPoint prevPoint = null;

        for (int i = 0; i < hull.size(); i++) {

            if (i == 0) {
                prevPoint = (GeomPoint) hull.elementAt(hull.size() - 1);
            }

            point = (GeomPoint) hull.elementAt(i);

            g.setColor(Color.black);
            g.fillOval(point.x - 2, point.y - 2, 5, 5);

            if (prevPoint != null) {
                g.fillOval(prevPoint.x - 2, prevPoint.y - 2, 5, 5);
                g.drawLine(point.x, point.y, prevPoint.x, prevPoint.y);
            }
            prevPoint = point;
        }
        if (hull.rectp != null) {
            if (displayedRect == 6) {
                g.setColor(Color.red);
            } else {
                g.setColor(Color.magenta);
            }
            final Rectangle lr = (Rectangle) hull.RectList.elementAt(displayedRect);

            g.drawRect(lr.x, lr.y, lr.width, lr.height);
            g.fillRect(lr.x, lr.y, lr.width, lr.height);
        }

        controller.updateLabel(hull.status);

    }
}

class GeomPoint extends Point {

    public GeomPoint(final int ptx, final int pty) {
        this.x = ptx;
        this.y = pty;
    }

    int min(final int a, final int b) {
        if (a <= b)
            return a;
        else
            return b;
    }

    int max(final int a, final int b) {
        if (a >= b)
            return a;
        else
            return b;
    }
}

class GeomEdge {

    int xmin, xmax; /* horiz, +x is right */
    int ymin, ymax; /* vertical, +y is down */
    double m, b; /* y = mx + b */
    boolean isTop, isRight; /* position of edge w.r.t. hull */

    public GeomEdge(final GeomPoint p, final GeomPoint q) {
        this.xmin = p.min(p.x, q.x);
        this.xmax = p.max(p.x, q.x);
        this.ymin = p.min(p.y, q.y);
        this.ymax = p.max(p.y, q.y);
        this.m = ((double) (q.y - p.y)) / ((double) (q.x - p.x));
        this.b = p.y - m * (p.x);
        this.isTop = p.x > q.x; // edge from right to left (ccw)
        this.isRight = p.y > q.y; // edge from bottom to top (ccw)
    }
}

class ConvexHull extends Vector {

    int status;
    private int start, stop; // tangents for iterative convex hull
    private int xmin, xmax, ymin, ymax; // position of hull
    int yxmax; // y coord of xmax
    GeomPoint rectp;
    int recth, rectw;
    boolean changed;

    /* largest rectangles with corners on AC, BD, ABC, ABD, ACD, BCD */
    Vector RectList;

    /* fixed aspect ratio */
    private final boolean fixed;
    private final int fixedX, fixedY;

    public ConvexHull() {
        this.fixed = false;
        this.fixedX = 1;
        this.fixedY = 1;
        RectList = new Vector();
    }

    /*
     * position of point w.r.t. hull edge sign of twice the area of triangle abc
     */
    boolean onLeft(final GeomPoint a, final GeomPoint b, final GeomPoint c) {
        final int area = (b.x - a.x) * (c.y - a.y) - (c.x - a.x) * (b.y - a.y);
        return (area < 0);
    }

    /*
     * check if point is outside true is point is on right of all vertices finds
     * tangents if point is outside
     */
    boolean pointOutside(final GeomPoint p) {// , int start, int stop){

        boolean ptIn = true, currIn, prevIn = true;

        GeomPoint a = (GeomPoint) this.elementAt(0);
        GeomPoint b;

        for (int i = 0; i < this.size(); i++) {

            b = (GeomPoint) this.elementAt((i + 1) % this.size());
            currIn = onLeft(a, b, p);
            ptIn = ptIn && currIn;
            a = b;

            if (prevIn && !currIn) {
                start = i;
            } /* next point outside, 1st tangent found */
            if (!prevIn && currIn) {
                stop = i;
            } /* 2nd tangent */
            prevIn = currIn;

        }
        return !ptIn;
    }

    /* check if point is outside, insert it, maintaining general position */
    boolean addPointToHull(final GeomPoint p) {

        /* index of tangents */
        start = 0;
        stop = 0;

        if (!pointOutside(p)) {
            return false;
        }

        /* insert point */
        int numRemove;

        if (stop > start) {
            numRemove = stop - start - 1;
            if (numRemove > 0) {
                this.removeRange(start + 1, stop);
            }
            this.insertElementAt(p, start + 1); // insertElmentAt(p, start+1);
        } else {
            numRemove = stop + this.size() - start - 1;
            if (numRemove > 0) {
                if (start + 1 < this.size()) {
                    this.removeRange(start + 1, this.size());
                }
                if (stop - 1 >= 0) {
                    this.removeRange(0, stop);
                }
            }
            this.add(p);

        }
        System.out.println("changing");
        this.changed = true;
        return true;
    } // addPointToHull

    /*
     * compute edge list set xmin, xmax used to find largest rectangle by scanning
     * horizontally
     */
    Vector computeEdgeList() {
        final Vector l = new Vector();
        GeomPoint a, b;
        GeomEdge e;
        a = (GeomPoint) this.elementAt(this.size() - 1);
        for (int i = 0; i < this.size(); i++) {
            b = (GeomPoint) this.elementAt(i);
            // b = (GeomPoint)this.elementAt(i+1);

            if (i == 0) {
                this.xmin = a.x;
                this.xmax = a.x;
                this.ymin = a.y;
                this.ymax = a.y;
            } else {
                if (a.x < this.xmin) {
                    this.xmin = a.x;
                }
                if (a.x > this.xmax) {
                    this.xmax = a.x;
                    this.yxmax = a.y;
                }
                if (a.y < this.ymin) {
                    this.ymin = a.y;
                }
                if (a.y > this.ymax) {
                    this.ymax = a.y;
                }
            }
            e = new GeomEdge(a, b);
            l.add(e);
            a = b;
        } // for
          // b = (GeomPoint)this.elementAt(this.size()-1);
          // a = (GeomPoint)this.elementAt(0);
          // e = new GeomEdge(b,a);
          // l.add(e);
        return l;
    }

    /*
     * compute y intersection with an edge first pixel completely inside ceil
     * function if edge is on top, floor otherwise (+y is down)
     */
    int yIntersect(final int xi, final GeomEdge e) {

        int y;
        final double yfirst = (e.m) * (xi - 0.5) + e.b;
        final double ylast = (e.m) * (xi + 0.5) + e.b;

        if (!e.isTop) {
            y = (int) Math.floor(Math.min(yfirst, ylast));
        } else {
            y = (int) Math.ceil(Math.max(yfirst, ylast));
        }
        return y;
    }

    /*
     * find largest pixel completely inside look through all edges for intersection
     */
    int xIntersect(final int y, final Vector l) {
        int x = 0;
        double x0 = 0, x1 = 0;
        for (int i = 0; i < this.size(); i++) {
            final GeomEdge e = (GeomEdge) l.elementAt(i);
            if (e.isRight && e.ymin <= y && e.ymax >= y) {
                x0 = (double) (y + 0.5 - e.b) / e.m;
                x1 = (double) (y - 0.5 - e.b) / e.m;
            }
        }
        x = (int) Math.floor(Math.min(x0, x1));
        // System.out.println("xIntersect, x is " + x);
        return x;
    }

    GeomEdge findEdge(final int x, final boolean isTop, final Vector l) {
        GeomEdge e, emax = (GeomEdge) l.elementAt(0);
        // int count = 0;
        for (int i = 0; i < this.size(); i++) {
            e = (GeomEdge) l.elementAt(i);
            if (e.xmin == x) {
                // count++;
                // if (count == 1){
                // emax = e;
                // }
                // else{
                if (e.xmax != e.xmin) {
                    if ((e.isTop && isTop) || (!e.isTop && !isTop)) {
                        emax = e;
                    }
                }
            }

        }
        return emax;
    }

    /*
     * compute 3 top and bottom 3 corner rectangle for each xi find largest 2 corner
     * rectangle
     */
    int computeLargestRectangle() {

        this.changed = false;
        final Vector edgeList = computeEdgeList();
        this.RectList = new Vector();

        GeomEdge top, bottom;
        int ymax, ymin, xright, xlo, xhi;
        int area, maxArea = 0;
        final int maxAreaAC = 0, maxAreaBD = 0, maxAreaABC = 0, maxAreaABD = 0, maxAreaACD = 0, maxAreaBCD = 0;
        int width, height, maxh = 0, maxw = 0;

        /* all 2-corner and 3-corner largest rectangles */
        int aAC = 0, aBD = 0, aABC = 0, aABD = 0, aACD = 0, aBCD = 0;
        GeomPoint pAC, pBD, pABC, pABD, pACD, pBCD;
        int hAC = 0, wAC = 0, hBD = 0, wBD = 0, hABC = 0, wABC = 0, hABD = 0, wABD = 0, hACD = 0, wACD = 0, hBCD = 0,
                wBCD = 0;
        boolean onA, onB, onC, onD;

        GeomPoint maxp = new GeomPoint(0, 0);
        pAC = maxp;
        pBD = maxp;
        pABC = maxp;
        pABD = maxp;
        pACD = maxp;
        pBCD = maxp;

        final Vector xint = new Vector();

        for (int i = 0; i < this.ymax; i++) {
            final int x = xIntersect(i, edgeList);
            final GeomPoint px = new GeomPoint(x, i);
            xint.add(px);
        }
        // find first top and bottom edges
        top = findEdge(this.xmin, true, edgeList);
        bottom = findEdge(this.xmin, false, edgeList);

        // scan for rectangle left position
        for (int xi = this.xmin; xi < this.xmax; xi++) {

            ymin = yIntersect(xi, top);
            ymax = yIntersect(xi, bottom);

            for (int ylo = ymax; ylo >= ymin; ylo--) {// ylo from to to bottom

                for (int yhi = ymin; yhi <= ymax; yhi++) {

                    if (yhi > ylo) {

                        onA = (yhi == ymax && !bottom.isRight);
                        onD = (ylo == ymin && !top.isRight);

                        xlo = (int) ((GeomPoint) xint.elementAt(ylo)).x;// xIntersect(ylo,edgeList);
                        xhi = (int) ((GeomPoint) xint.elementAt(yhi)).x;// xIntersect(yhi,edgeList);

                        xright = maxp.min(xlo, xhi);
                        onC = (xright == xlo && this.yxmax >= ylo);
                        onB = (xright == xhi && this.yxmax <= yhi);

                        height = yhi - ylo;
                        width = xright - xi;

                        if (!this.fixed) {
                            // System.out.println("!fixed");
                        } // !fixed
                        else {
                            final int fixedWidth = (int) Math
                                    .ceil(((double) height * this.fixedX) / ((double) this.fixedY));
                            if (fixedWidth <= width) {
                                width = fixedWidth;
                            } else {
                                width = 0;
                            }
                        }
                        area = width * height;
                        // AC
                        if (onA && onC && !onB && !onD) {
                            if (area > aAC) {
                                aAC = area;
                                pAC = new GeomPoint(xi, ylo);
                                hAC = height;
                                wAC = width;
                            }
                        }
                        // BD
                        if (onB && onD && !onA && !onC) {
                            if (area > aBD) {
                                aBD = area;
                                pBD = new GeomPoint(xi, ylo);
                                hBD = height;
                                wBD = width;
                            }
                        }
                        // ABC
                        if (onA && onB && onC) {
                            if (area > aABC) {
                                aABC = area;
                                pABC = new GeomPoint(xi, ylo);
                                hABC = height;
                                wABC = width;
                            }
                        }
                        // ABD
                        if (onA && onB && onD) {
                            if (area > aABD) {
                                aABD = area;
                                pABD = new GeomPoint(xi, ylo);
                                hABD = height;
                                wABD = width;
                            }
                        }
                        // ACD
                        if (onA && onC && onD) {
                            if (area > aACD) {
                                aACD = area;
                                pACD = new GeomPoint(xi, ylo);
                                hACD = height;
                                wACD = width;
                            }
                        }
                        // BCD
                        if (onB && onC && onD) {
                            if (area > aBCD) {
                                aBCD = area;
                                pBCD = new GeomPoint(xi, ylo);
                                hBCD = height;
                                wBCD = width;
                            }
                        }

                        if (area > maxArea) {
                            maxArea = area;
                            maxp = new GeomPoint(xi, ylo);
                            maxw = width;
                            maxh = height;
                            // System.out.println(onA + " " + onB + " " + onC + " " + onD);
                        }
                    } // yhi > ylo
                } // for yhi
            } // for ylo
            if (xi == top.xmax) {
                top = findEdge(xi, true, edgeList);
            }
            if (xi == bottom.xmax) {
                bottom = findEdge(xi, false, edgeList);
            }
        } // xi
        this.rectp = maxp;
        this.recth = maxh;
        this.rectw = maxw;

        this.RectList.add(new Rectangle(pAC.x, pAC.y, wAC, hAC));
        this.RectList.add(new Rectangle(pBD.x, pBD.y, wBD, hBD));
        this.RectList.add(new Rectangle(pABC.x, pABC.y, wABC, hABC));
        this.RectList.add(new Rectangle(pABD.x, pABD.y, wABD, hABD));
        this.RectList.add(new Rectangle(pACD.x, pACD.y, wACD, hACD));
        this.RectList.add(new Rectangle(pBCD.x, pBCD.y, wBCD, hBCD));
        this.RectList.add(new Rectangle(maxp.x, maxp.y, maxw, maxh));
        return 0;

    }

}

 Polygon.cs

      /* compute y intersection with an edge
    * first pixel completely inside
    * ceil function if edge is on top, floor otherwise
    * (+y is down)
    */
        int yIntersect(float xi, Line2 e)
        {

            int y;
            double yfirst = (e.m) * (xi - 0.5) + e.b;
            double ylast = (e.m) * (xi + 0.5) + e.b;

            if (!e.isTop)
            {
                y = (int)Math.Floor(Math.Min(yfirst, ylast));
            }
            else
            {
                y = (int)Math.Ceiling(Math.Max(yfirst, ylast));
            }
            return y;
        }

        /* find largest pixel completely inside
         * look through all edges for intersection
         */
        int xIntersect(float y, IEnumerable<Line2> l)
        {
            int x = 0;
            double x0 = 0, x1 = 0;
            var enumerable = l.ToList();
            for (int i = 0; i < enumerable.Count(); i++)
            {
                Line2 e = enumerable.ElementAt(i);
                if (e.isRight && e.ymin <= y && e.ymax >= y)
                {
                    x0 = (double)(y + 0.5 - e.b) / e.m;
                    x1 = (double)(y - 0.5 - e.b) / e.m;
                }
            }
            x = (int)Math.Floor(Math.Min(x0, x1));
            //System.out.println("xIntersect, x is " + x);
            return x;
        }


        Line2 findEdge(float x, bool isTop, IEnumerable<Line2> l)
        {
            Line2 e, emax = (Line2)l.ElementAt(0);
            //int count = 0;
            for (int i = 0; i < l.Count(); i++)
            {
                e = l.ElementAt(i);
                if (e.xmin == x)
                {
                    //count++;
                    //if (count == 1){
                    //    emax = e;
                    //}
                    //else{
                    if (e.xmax != e.xmin)
                    {
                        if ((e.isTop && isTop) || (!e.isTop && !isTop))
                        {
                            emax = e;
                        }
                    }
                }

            }
            return emax;
        }

        /*
     * compute 3 top and bottom 3 corner rectangle for each xi find largest 2 corner
     * rectangle
     */
        List<AxisAlignedBox2f> computeLargestRectangle()
        {
            float yxmax = vertices[0].y;
            float maxX = vertices[0].x;
            foreach (var v in vertices)
            {
                if (v.x > maxX)
                {
                    maxX = v.x;
                    yxmax = v.y;
                }
            }
            var edgeList = this.SegmentItr();
            var rectList = new List<AxisAlignedBox2f>();
            var box = this.GetBounds();
            var thisxmin = box.Min.x;
            var thisxmax = box.Max.x;
            var thisymin = box.Min.y;
            var thisymax = box.Max.y;
            Line2 top, bottom;
            int ymax, ymin, xright, xlo, xhi;
            float area, maxArea = 0;
            int maxAreaAC = 0, maxAreaBD = 0, maxAreaABC = 0, maxAreaABD = 0, maxAreaACD = 0, maxAreaBCD = 0;
            float width, height, maxh = 0, maxw = 0;

            /* all 2-corner and 3-corner largest rectangles */
            float aAC = 0, aBD = 0, aABC = 0, aABD = 0, aACD = 0, aBCD = 0;
            Vector2 pAC, pBD, pABC, pABD, pACD, pBCD;
            float hAC = 0, wAC = 0, hBD = 0, wBD = 0, hABC = 0, wABC = 0, hABD = 0, wABD = 0, hACD = 0, wACD = 0, hBCD = 0,
                    wBCD = 0;
            bool onA, onB, onC, onD;

            Vector2 maxp = new Vector2(0, 0);
            pAC = maxp;
            pBD = maxp;
            pABC = maxp;
            pABD = maxp;
            pACD = maxp;
            pBCD = maxp;

            List<Vector2> xint = new List<Vector2>();

            for (var i = thisymin; i < thisymax; i++)
            {
                int x = xIntersect(i, edgeList);
                Vector2 px = new Vector2(x, i);
                xint.Add(px);
            }
            // find first top and bottom edges
            top = findEdge(thisxmin, true, edgeList);
            bottom = findEdge(thisxmin, false, edgeList);

            // scan for rectangle left position
            for (var xi = thisxmin; xi < thisxmax; xi++)
            {

                ymin = yIntersect(xi, top);
                ymax = yIntersect(xi, bottom);

                for (int ylo = ymax; ylo >= ymin; ylo--)
                {// ylo from to to bottom

                    for (var yhi = ymin; yhi <= ymax; yhi++)
                    {

                        if (yhi > ylo)
                        {

                            onA = (yhi == ymax && !bottom.isRight);
                            onD = (ylo == ymin && !top.isRight);

                            xlo = (int)((Vector2)xint.ElementAt(ylo)).x;// xIntersect(ylo,edgeList);
                            xhi = (int)((Vector2)xint.ElementAt(yhi)).x;// xIntersect(yhi,edgeList);

                            xright = Math.Min(xlo, xhi);
                            onC = (xright == xlo && yxmax >= ylo);
                            onB = (xright == xhi && yxmax <= yhi);

                            height = yhi - ylo;
                            width = xright - xi;
                            area = width * height;
                            // AC
                            if (onA && onC && !onB && !onD)
                            {
                                if (area > aAC)
                                {
                                    aAC = area;
                                    pAC = new Vector2(xi, ylo);
                                    hAC = height;
                                    wAC = width;
                                }
                            }
                            // BD
                            if (onB && onD && !onA && !onC)
                            {
                                if (area > aBD)
                                {
                                    aBD = area;
                                    pBD = new Vector2(xi, ylo);
                                    hBD = height;
                                    wBD = width;
                                }
                            }
                            // ABC
                            if (onA && onB && onC)
                            {
                                if (area > aABC)
                                {
                                    aABC = area;
                                    pABC = new Vector2(xi, ylo);
                                    hABC = height;
                                    wABC = width;
                                }
                            }
                            // ABD
                            if (onA && onB && onD)
                            {
                                if (area > aABD)
                                {
                                    aABD = area;
                                    pABD = new Vector2(xi, ylo);
                                    hABD = height;
                                    wABD = width;
                                }
                            }
                            // ACD
                            if (onA && onC && onD)
                            {
                                if (area > aACD)
                                {
                                    aACD = area;
                                    pACD = new Vector2(xi, ylo);
                                    hACD = height;
                                    wACD = width;
                                }
                            }
                            // BCD
                            if (onB && onC && onD)
                            {
                                if (area > aBCD)
                                {
                                    aBCD = area;
                                    pBCD = new Vector2(xi, ylo);
                                    hBCD = height;
                                    wBCD = width;
                                }
                            }

                            if (area > maxArea)
                            {
                                maxArea = area;
                                maxp = new Vector2(xi, ylo);
                                maxw = width;
                                maxh = height;
                                // System.out.println(onA + " " + onB + " " + onC + " " + onD);
                            }
                        } // yhi > ylo
                    } // for yhi
                } // for ylo
                if (xi == top.xmax)
                {
                    top = findEdge(xi, true, edgeList);
                }
                if (xi == bottom.xmax)
                {
                    bottom = findEdge(xi, false, edgeList);
                }
            } // xi

            rectList.Add(new AxisAlignedBox2f(new Vector2(pAC.x, pAC.y), wAC, hAC));
            rectList.Add(new AxisAlignedBox2f(new Vector2(pBD.x, pBD.y), wBD, hBD));
            rectList.Add(new AxisAlignedBox2f(new Vector2(pABC.x, pABC.y), wABC, hABC));
            rectList.Add(new AxisAlignedBox2f(new Vector2(pABD.x, pABD.y), wABD, hABD));
            rectList.Add(new AxisAlignedBox2f(new Vector2(pACD.x, pACD.y), wACD, hACD));
            rectList.Add(new AxisAlignedBox2f(new Vector2(pBCD.x, pBCD.y), wBCD, hBCD));
            rectList.Add(new AxisAlignedBox2f(new Vector2(maxp.x, maxp.y), maxw, maxh));
            return rectList;
        }

 

Line2.cs

  public float xmin, xmax; /* horiz, +x is right */
        public float ymin, ymax; /* vertical, +y is down */
        public double m, b; /* y = mx + b */
        public bool isTop, isRight; /* position of edge w.r.t. hull */


        public Line2(Vector2 p0, Vector2 p1)
        {
            //update_from_endpoints(p0, p1);
            Center = 0.5f * (p0 + p1);
            Direction = p1 - p0;
            Extent = 0.5f * Direction.Normalize();

            this.xmin = Math.Min(p0.x, p1.x);
            this.xmax = Math.Max(p0.x, p1.x);
            this.ymin = Math.Min(p0.y, p1.y);
            this.ymax = Math.Max(p0.y, p1.y);
            this.m = ((double)(p1.y - p0.y)) / ((double)(p1.x - p0.x));
            this.b = p0.y - m * (p0.x);
            this.isTop = p0.x > p1.x; //edge from right to left (ccw)
            this.isRight = p0.y > p1.y; //edge from bottom to top (ccw)
        }

 

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值