All Downloads are FREE. Search and download functionalities are using the official Maven repository.

sim.util.Int3D Maven / Gradle / Ivy

Go to download

MASON is a fast discrete-event multiagent simulation library core in Java, designed to be the foundation for large custom-purpose Java simulations, and also to provide more than enough functionality for many lightweight simulation needs. MASON contains both a model library and an optional suite of visualization tools in 2D and 3D.

The newest version!
/*
  Copyright 2006 by Sean Luke and George Mason University
  Licensed under the Academic Free License version 3.0
  See the file "LICENSE" for more information
*/

package sim.util;

/**
   Int3D stores three values (x, y, and z) but it is immutable: once the x and y and z values are set, they cannot be changed (they're final).  Like the others, Int3D is immutable primarily to prevent hash tables from breaking.

   

One day in the far future, Int3D should also be HIGHLY efficient; since it is immutable, it can be passed by value rather than by pointer by a smart compiler. Not today, though. But it's not bad.

This class has an elaborate hash code generation that is much more random than Sun's standard generator, but takes more time. For very large numbers of objects, this is a good idea, but we may change it to a simpler version in the future.

Int3D.equals(...) can compare by value against other Int3Ds, MutableInt2Ds, and Double3Ds. */ public final class Int3D implements java.io.Serializable { private static final long serialVersionUID = 1; public final int x; public final int y; public final int z; public Int3D() { x = 0; y = 0; z = 0;} public Int3D(final int x, final int y, final int z) { this.x = x; this.y = y; this.z = z;} /** Explicitly assumes the z value is set to 0 */ public Int3D(final Int2D p) { x = p.x; y = p.y; z = 0; } public Int3D(final Int2D p, final int z) { x = p.x; y = p.y; this.z = z; } public Int3D(final MutableInt2D p) { x = p.x; y = p.y; z = 0; } public Int3D(final MutableInt2D p, final int z) { x = p.x; y = p.y; this.z = z; } public final int getX() { return x; } public final int getY() { return y; } public final int getZ() { return z; } public String toString() { return "Int3D["+x+","+y+","+z+"]"; } public String toCoordinates() { return "(" + x + ", " + y + ", " + z + ")"; } public int hashCode() { int z = this.z; // basically we need to randomly disperse --> int // I do that as x ^ hash(y ^ hash(z) + 17 [or whatever]). Hash function // taken from http://www.cris.com/~Ttwang/tech/inthash.htm // Some further discussion. Sun's moved to a new hash table scheme // which has (of all things!) tables with lengths that are powers of two! // Normally hash table lengths should be prime numbers, in order to // compensate for bad hashcodes. To fix matters, Sun now is // pre-shuffling the hashcodes with the following algorithm (which // is short but not too bad -- should we adopt it? Dunno). See // http://developer.java.sun.com/developer/bugParade/bugs/4669519.html // key += ~(key << 9); // key ^= (key >>> 14); // key += (key << 4); // key ^= (key >>> 10); // This is good for us because Int2D, Int3D, Double2D, and Double3D // have hashcodes well distributed with regard to y and z, but when // you mix in x, they're just linear in x. We could do a final // shuffle I guess. In Java 1.3, they DON'T do a pre-shuffle, so // it may be suboptimal. Since we're all moving to 1.4.x, it's not // a big deal since 1.4.x is shuffling the final result using the // Sun shuffler above. But I'd appreciate some tests on our method // below, and suggestions as to whether or not we should adopt the // shorter, likely suboptimal but faster Sun shuffler instead // for y and z values. -- Sean z += ~(z << 15); z ^= (z >>> 10); z += (z << 3); z ^= (z >>> 6); z += ~(z << 11); z ^= (z >>> 16); z ^= y; z += 17; // a little prime number shifting -- waving a dead chicken? dunno z += ~(z << 15); z ^= (z >>> 10); z += (z << 3); z ^= (z >>> 6); z += ~(z << 11); z ^= (z >>> 16); // nifty! Now mix in x return x ^ z; } // can't have separate equals(...) methods as the // argument isn't virtual public boolean equals(final Object obj) { if (obj==null) return false; else if (obj instanceof Int3D) // do Int3D first { Int3D other = (Int3D) obj; return (other.x == x && other.y == y && other.z == z); } else if (obj instanceof MutableInt3D) { MutableInt3D other = (MutableInt3D) obj; return (other.x == x && other.y == y && other.z == z); } else if (obj instanceof Double3D) { Double3D other = (Double3D) obj; return (other.x == x && other.y == y && other.z == z); } else if (obj instanceof MutableDouble3D) { MutableDouble3D other = (MutableDouble3D) obj; return (other.x == x && other.y == y && other.z == z); } else return false; } /** Returns the distance FROM this Int3D TO the specified point */ public double distance(final double x, final double y, final double z) { final double dx = (double)this.x - x; final double dy = (double)this.y - y; final double dz = (double)this.z - z; return Math.sqrt(dx*dx+dy*dy+dz*dz); } /** Returns the distance FROM this Int3D TO the specified point. */ public double distance(final Double3D p) { final double dx = (double)this.x - p.x; final double dy = (double)this.y - p.y; final double dz = (double)this.z - p.z; return Math.sqrt(dx*dx+dy*dy+dz*dz); } /** Returns the distance FROM this Int3D TO the specified point. */ public double distance(final MutableInt3D p) { final double dx = (double)this.x - p.x; final double dy = (double)this.y - p.y; final double dz = (double)this.z - p.z; return Math.sqrt(dx*dx+dy*dy+dz*dz); } /** Returns the distance FROM this Int3D TO the specified point. */ public double distance(final Int3D p) { final double dx = (double)this.x - p.x; final double dy = (double)this.y - p.y; final double dz = (double)this.z - p.z; return Math.sqrt(dx*dx+dy*dy+dz*dz); } /** Returns the squared distance FROM this Int3D TO the specified point */ public double distanceSq(final double x, final double y, final double z) { final double dx = (double)this.x - x; final double dy = (double)this.y - y; final double dz = (double)this.z - z; return (dx*dx+dy*dy+dz*dz); } /** Returns the squared distance FROM this Int3D TO the specified point. */ public double distanceSq(final Double3D p) { final double dx = (double)this.x - p.x; final double dy = (double)this.y - p.y; final double dz = (double)this.z - p.z; return (dx*dx+dy*dy+dz*dz); } /** Returns the squared distance FROM this Int3D TO the specified point. */ public double distanceSq(final MutableInt3D p) { final double dx = (double)this.x - p.x; final double dy = (double)this.y - p.y; final double dz = (double)this.z - p.z; return (dx*dx+dy*dy+dz*dz); } /** Returns the squared distance FROM this Int3D TO the specified point. */ public double distanceSq(final Int3D p) { final double dx = (double)this.x - p.x; final double dy = (double)this.y - p.y; final double dz = (double)this.z - p.z; return (dx*dx+dy*dy+dz*dz); } /** Returns the manhattan distance FROM this Int3D TO the specified point. */ public long manhattanDistance(final int x, final int y, final int z) { return Math.abs((long)this.x-x) + Math.abs((long)this.y-y) + Math.abs((long)this.z-z); } /** Returns the manhattan distance FROM this Int3D TO the specified point. */ public long manhattanDistance(final MutableInt3D p) { return Math.abs((long)this.x-p.x) + Math.abs((long)this.y-p.y) + Math.abs((long)this.z-p.z); } /** Returns the manhattan distance FROM this Int3D TO the specified point. */ public long manhattanDistance(final Int3D p) { return Math.abs((long)this.x-p.x) + Math.abs((long)this.y-p.y) + Math.abs((long)this.z-p.z); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy