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}