package cn.academy.core.util; public class Plotter { enum Axis {X, Y, Z} final Axis axis; // The main axis which we incr(decr) through final double dyx, dzx; final int dirflag; int x0, y0, z0; int x, y, z; public Plotter(int _x0, int _y0, int _z0, double dx, double dy, double dz) { x0 = _x0; y0 = _y0; z0 = _z0; // Determine which direction to increment to // and swap the values so we are always thinking we are incrementing via x+ double adx = Math.abs(dx), ady = Math.abs(dy), adz = Math.abs(dz); int itemp; double dtemp; if(adz > ady && adz > adx) { dtemp = dz; dz = dx; dx = dtemp; itemp = z0; z0 = x0; x0 = itemp; axis = Axis.Z; } else if(ady > adx) { dtemp = dy; dy = dx; dx = dtemp; itemp = y0; y0 = x0; x0 = itemp; axis = Axis.Y; } else if(adx > 0) { axis = Axis.X; } else throw new RuntimeException("Zero slope vector"); x = x0; y = y0; z = z0; dyx = dy / dx; dzx = dz / dx; dirflag = dx > 0 ? 1 : -1; } public int[] next() { int nextX = x + dirflag; double valy = y0 + (nextX - x0) * dyx; double valz = z0 + (nextX - x0) * dzx; if(Math.abs(valy - y) > 0.5) { y += Math.signum(dyx) * dirflag; } else if(Math.abs(valz - z) > 0.5) { z += Math.signum(dzx) * dirflag; } else { x = nextX; } switch(axis) { case X: return new int[] {x, y, z}; case Y: return new int[] {y, x, z}; case Z: return new int[] {z, y, x}; } throw new IllegalStateException("Never reach here"); } }