001package icy.math; 002 003import java.awt.geom.Line2D; 004import java.awt.geom.Point2D; 005import java.util.Iterator; 006 007/** 008 * Line2D iterator (iterate over Line2D points given a wanted step). 009 * 010 * @author Stephane Dallongeville 011 */ 012public class Line2DIterator implements Iterator<Point2D> 013{ 014 final static protected double DEFAULT_STEP = 1d; 015 016 protected boolean done; 017 protected int count; 018 final protected boolean forceLast; 019 020 final protected Point2D pos; 021 final protected Point2D last; 022 023 protected double sx, sy; 024 025 /** 026 * Create the Line2D Iterator. 027 * 028 * @param line 029 * the lien we want to iterate points 030 * @param step 031 * step between each point (default = 1d) 032 * @param forceLastPoint 033 * set to <i>true</i> if you want the last point to match the end line position 034 */ 035 public Line2DIterator(Line2D line, double step, boolean forceLastPoint) 036 { 037 super(); 038 039 pos = line.getP1(); 040 last = line.getP2(); 041 done = false; 042 forceLast = forceLastPoint; 043 044 final double dx = line.getX2() - line.getX1(); 045 final double dy = line.getY2() - line.getY1(); 046 final double adx = Math.abs(dx); 047 final double ady = Math.abs(dy); 048 049 final double adjStep = (step <= 0d) ? 1d : step; 050 051 // step on X axis 052 if (adx > ady) 053 { 054 count = (int) (adx / adjStep); 055 sx = adjStep; 056 sy = (ady / adx) * adjStep; 057 } 058 // step on Y axis 059 else 060 { 061 if (ady == 0d) 062 { 063 count = 0; 064 sx = 0; 065 } 066 else 067 { 068 count = (int) (ady / adjStep); 069 sx = (adx / ady) * adjStep; 070 } 071 sy = adjStep; 072 } 073 // for initial position 074 count++; 075 076 // reverse step if needed 077 if (dx < 0) 078 sx = -sx; 079 if (dy < 0) 080 sy = -sy; 081 } 082 083 /** 084 * Create the Line2D Iterator. 085 * 086 * @param line 087 * the lien we want to iterate points 088 * @param step 089 * step between each point (default = 1d) 090 */ 091 public Line2DIterator(Line2D line, double step) 092 { 093 this(line, step, true); 094 } 095 096 /** 097 * Create the Line2D Iterator. 098 * 099 * @param line 100 * the lien we want to iterate points 101 */ 102 public Line2DIterator(Line2D line) 103 { 104 this(line, DEFAULT_STEP, true); 105 } 106 107 @Override 108 public boolean hasNext() 109 { 110 return !done; 111 } 112 113 @Override 114 public Point2D next() 115 { 116 final Point2D result = (Point2D) pos.clone(); 117 118 // done ? 119 if (--count <= 0) 120 { 121 if (forceLast) 122 { 123 // consider done only if pos is equal to last 124 done = pos.equals(last); 125 // force equality with last position 126 pos.setLocation(last); 127 } 128 else 129 done = true; 130 } 131 else 132 pos.setLocation(pos.getX() + sx, pos.getY() + sy); 133 134 return result; 135 } 136 137 @Override 138 public void remove() 139 { 140 throw new UnsupportedOperationException(); 141 } 142}