001/*
002 * To change this template, choose Tools | Templates
003 * and open the template in the editor.
004 */
005package sec.sun.awt.geom;
006
007/**
008 *
009 * @author Michael Deutch
010 */
011public class EvenOdd {
012
013    public static final boolean debug = false;
014    int limit = 0;
015    double yranges[] = new double[10];
016    double xlo, ylo, xhi, yhi;
017
018    public EvenOdd(double xlo, double ylo, double xhi, double yhi) {
019        //super(xlo, ylo, xhi, yhi);
020        this.xlo = xlo;
021        this.ylo = ylo;
022        this.xhi = xhi;
023        this.yhi = yhi;
024    }
025
026    public final boolean covers(double ystart, double yend) {
027        return (limit == 2 && yranges[0] <= ystart && yranges[1] >= yend);
028    }
029
030    public void record(double ystart, double yend, int direction) {
031        if (ystart >= yend) {
032            return;
033        }
034        int from = 0;
035        // Quickly jump over all pairs that are completely "above"
036        while (from < limit && ystart > yranges[from + 1]) {
037            from += 2;
038        }
039        int to = from;
040        while (from < limit) {
041            double yrlo = yranges[from++];
042            double yrhi = yranges[from++];
043            if (yend < yrlo) {
044                // Quickly handle insertion of the new range
045                yranges[to++] = ystart;
046                yranges[to++] = yend;
047                ystart = yrlo;
048                yend = yrhi;
049                continue;
050            }
051            // The ranges overlap - sort, collapse, insert, iterate
052            double yll, ylh, yhl, yhh;
053            if (ystart < yrlo) {
054                yll = ystart;
055                ylh = yrlo;
056            } else {
057                yll = yrlo;
058                ylh = ystart;
059            }
060            if (yend < yrhi) {
061                yhl = yend;
062                yhh = yrhi;
063            } else {
064                yhl = yrhi;
065                yhh = yend;
066            }
067            if (ylh == yhl) {
068                ystart = yll;
069                yend = yhh;
070            } else {
071                if (ylh > yhl) {
072                    ystart = yhl;
073                    yhl = ylh;
074                    ylh = ystart;
075                }
076                if (yll != ylh) {
077                    yranges[to++] = yll;
078                    yranges[to++] = ylh;
079                }
080                ystart = yhl;
081                yend = yhh;
082            }
083            if (ystart >= yend) {
084                break;
085            }
086        }
087        if (to < from && from < limit) {
088            System.arraycopy(yranges, from, yranges, to, limit - from);
089        }
090        to += (limit - from);
091        if (ystart < yend) {
092            if (to >= yranges.length) {
093                double newranges[] = new double[to + 10];
094                System.arraycopy(yranges, 0, newranges, 0, to);
095                yranges = newranges;
096            }
097            yranges[to++] = ystart;
098            yranges[to++] = yend;
099        }
100        limit = to;
101    }
102
103    public final double getXLo() {
104        return xlo;
105    }
106
107    public final double getYLo() {
108        return ylo;
109    }
110
111    public final double getXHi() {
112        return xhi;
113    }
114
115    public final double getYHi() {
116        return yhi;
117    }
118
119    public final boolean isEmpty() {
120        return (limit == 0);
121    }
122
123    public boolean accumulateLine(double x0, double y0,
124            double x1, double y1) {
125        if (y0 <= y1) {
126            return accumulateLine2(x0, y0, x1, y1, 1);
127        } else {
128            return accumulateLine2(x1, y1, x0, y0, -1);
129        }
130    }
131
132    public boolean accumulateLine2(double x0, double y0,
133            double x1, double y1,
134            int direction) {
135        if (yhi <= y0 || ylo >= y1) {
136            return false;
137        }
138        if (x0 >= xhi && x1 >= xhi) {
139            return false;
140        }
141        if (y0 == y1) {
142            return (x0 >= xlo || x1 >= xlo);
143        }
144        double xstart, ystart, xend, yend;
145        double dx = (x1 - x0);
146        double dy = (y1 - y0);
147        if (y0 < ylo) {
148            xstart = x0 + (ylo - y0) * dx / dy;
149            ystart = ylo;
150        } else {
151            xstart = x0;
152            ystart = y0;
153        }
154        if (yhi < y1) {
155            xend = x0 + (yhi - y0) * dx / dy;
156            yend = yhi;
157        } else {
158            xend = x1;
159            yend = y1;
160        }
161        if (xstart >= xhi && xend >= xhi) {
162            return false;
163        }
164        if (xstart > xlo || xend > xlo) {
165            return true;
166        }
167        record(ystart, yend, direction);
168        return false;
169    }
170}