Added version of getTile() that takes a rectangle into which to write the results.

git-svn-id: svn+ssh://src.earth.threerings.net/nenya/trunk@282 ed5b42cb-e716-0410-a449-f6a68f950b19
This commit is contained in:
Michael Bayne
2007-08-03 21:10:48 +00:00
parent 205d57a7fe
commit bbd5dd284e
+58 -63
View File
@@ -40,14 +40,12 @@ public class GeomUtil
*/
public static int dot (Point v1s, Point v1e, Point v2s, Point v2e)
{
return ((v1e.x - v1s.x) * (v2e.x - v2s.x) +
(v1e.y - v1s.y) * (v2e.y - v2s.y));
return ((v1e.x - v1s.x) * (v2e.x - v2s.x) + (v1e.y - v1s.y) * (v2e.y - v2s.y));
}
/**
* Computes and returns the dot product of the two vectors. See
* {@link #dot(Point,Point,Point,Point)} for an explanation of the
* arguments
* Computes and returns the dot product of the two vectors. See {@link
* #dot(Point,Point,Point,Point)} for an explanation of the arguments
*/
public static int dot (int v1sx, int v1sy, int v1ex, int v1ey,
int v2sx, int v2sy, int v2ex, int v2ey)
@@ -56,9 +54,8 @@ public class GeomUtil
}
/**
* Computes and returns the dot product of the two vectors. The
* vectors are assumed to start with the same coordinate and end with
* different coordinates.
* Computes and returns the dot product of the two vectors. The vectors are assumed to start
* with the same coordinate and end with different coordinates.
*
* @param vs the starting point of both vectors.
* @param v1e the ending point of the first vector.
@@ -66,40 +63,35 @@ public class GeomUtil
*/
public static int dot (Point vs, Point v1e, Point v2e)
{
return ((v1e.x - vs.x) * (v2e.x - vs.x) +
(v1e.y - vs.y) * (v2e.y - vs.y));
return ((v1e.x - vs.x) * (v2e.x - vs.x) + (v1e.y - vs.y) * (v2e.y - vs.y));
}
/**
* Computes and returns the dot product of the two vectors.
* See {@link #dot(Point,Point,Point)} for an explanation of the
* arguments
* Computes and returns the dot product of the two vectors. See {@link
* #dot(Point,Point,Point)} for an explanation of the arguments
*/
public static int dot (int vsx, int vsy, int v1ex, int v1ey,
int v2ex, int v2ey)
public static int dot (int vsx, int vsy, int v1ex, int v1ey, int v2ex, int v2ey)
{
return ((v1ex - vsx) * (v2ex - vsx) + (v1ey - vsy) * (v2ey - vsy));
}
/**
* Computes the point nearest to the specified point <code>p3</code>
* on the line defined by the two points <code>p1</code> and
* <code>p2</code>. The computed point is stored into <code>n</code>.
* <em>Note:</em> <code>p1</code> and <code>p2</code> must not be
* coincident.
* Computes the point nearest to the specified point <code>p3</code> on the line defined by the
* two points <code>p1</code> and <code>p2</code>. The computed point is stored into
* <code>n</code>. <em>Note:</em> <code>p1</code> and <code>p2</code> must not be coincident.
*
* @param p1 one point on the line.
* @param p2 another point on the line (not equal to <code>p1</code>).
* @param p3 the point to which we wish to be most near.
* @param n the point on the line defined by <code>p1</code> and
* <code>p2</code> that is nearest to <code>p</code>.
* @param n the point on the line defined by <code>p1</code> and <code>p2</code> that is
* nearest to <code>p</code>.
*
* @return the point object supplied via <code>n</code>.
*/
public static Point nearestToLine (Point p1, Point p2, Point p3, Point n)
{
// see http://astronomy.swin.edu.au/~pbourke/geometry/pointline/
// for a (not very good) explanation of the math
// see http://astronomy.swin.edu.au/~pbourke/geometry/pointline/ for a (not very good)
// explanation of the math
int Ax = p2.x - p1.x, Ay = p2.y - p1.y;
float u = (p3.x - p1.x) * Ax + (p3.y - p1.y) * Ay;
u /= (Ax * Ax + Ay * Ay);
@@ -109,25 +101,21 @@ public class GeomUtil
}
/**
* Calculate the intersection of two lines. Either line may be
* considered as a line segment, and the intersecting point
* is only considered valid if it lies upon the segment.
* Note that Point extends Point2D.
* Calculate the intersection of two lines. Either line may be considered as a line segment,
* and the intersecting point is only considered valid if it lies upon the segment. Note that
* Point extends Point2D.
*
* @param p1 and p2 the coordinates of the first line.
* @param seg1 if the first line should be considered a segment.
* @param p3 and p4 the coordinates of the second line.
* @param seg2 if the second line should be considered a segment.
* @param result the point that will be filled in with the intersecting
* point.
* @param result the point that will be filled in with the intersecting point.
*
* @return true if result was filled in, or false if the lines
* are parallel or the point of intersection lies outside of a
* segment.
* @return true if result was filled in, or false if the lines are parallel or the point of
* intersection lies outside of a segment.
*/
public static boolean lineIntersection (
Point2D p1, Point2D p2, boolean seg1,
Point2D p3, Point2D p4, boolean seg2, Point2D result)
public static boolean lineIntersection (Point2D p1, Point2D p2, boolean seg1,
Point2D p3, Point2D p4, boolean seg2, Point2D result)
{
// see http://astronomy.swin.edu.au/~pbourke/geometry/lineline2d/
double y43 = p4.getY() - p3.getY();
@@ -160,11 +148,10 @@ public class GeomUtil
}
/**
* Returns less than zero if <code>p2</code> is on the left hand side
* of the line created by <code>p1</code> and <code>theta</code> and
* greater than zero if it is on the right hand side. In theory, it
* will return zero if the point is on the line, but due to rounding
* errors it almost always decides that it's not exactly on the line.
* Returns less than zero if <code>p2</code> is on the left hand side of the line created by
* <code>p1</code> and <code>theta</code> and greater than zero if it is on the right hand
* side. In theory, it will return zero if the point is on the line, but due to rounding errors
* it almost always decides that it's not exactly on the line.
*
* @param p1 the point on the line whose side we're checking.
* @param theta the (logical) angle defining the line.
@@ -177,17 +164,16 @@ public class GeomUtil
int x = p1.x + (int)Math.round(1000*Math.cos(theta)),
y = p1.y + (int)Math.round(1000*Math.sin(theta));
// now dot the vector from p1->p2 with the vector from p1->N, if
// it's positive, we're on the right hand side, if it's negative
// we're on the left hand side and if it's zero, we're on the line
// now dot the vector from p1->p2 with the vector from p1->N, if it's positive, we're on
// the right hand side, if it's negative we're on the left hand side and if it's zero,
// we're on the line
return dot(p1.x, p1.y, p2.x, p2.y, x, y);
}
/**
* Shifts the position of the <code>tainer</code> rectangle to ensure
* that it contains the <code>tained</code> rectangle. The
* <code>tainer</code> rectangle must be larger than or equal to the
* size of the <code>tained</code> rectangle.
* Shifts the position of the <code>tainer</code> rectangle to ensure that it contains the
* <code>tained</code> rectangle. The <code>tainer</code> rectangle must be larger than or
* equal to the size of the <code>tained</code> rectangle.
*/
public static void shiftToContain (Rectangle tainer, Rectangle tained)
{
@@ -206,17 +192,15 @@ public class GeomUtil
}
/**
* Adds the target rectangle to the bounds of the source rectangle. If
* the source rectangle is null, a new rectangle is created that is the
* size of the target rectangle.
* Adds the target rectangle to the bounds of the source rectangle. If the source rectangle is
* null, a new rectangle is created that is the size of the target rectangle.
*
* @return the source rectangle.
*/
public static Rectangle grow (Rectangle source, Rectangle target)
{
if (target == null) {
Log.warning("Can't grow with null rectangle [src=" + source +
", tgt=" + target + "].");
Log.warning("Can't grow with null rectangle [src=" + source + ", tgt=" + target + "].");
Thread.dumpStack();
} else if (source == null) {
source = new Rectangle(target);
@@ -227,25 +211,36 @@ public class GeomUtil
}
/**
* Returns the rectangle containing the specified tile in the supplied
* larger rectangle. Tiles go from left to right, top to bottom.
* Returns the rectangle containing the specified tile in the supplied larger rectangle. Tiles
* go from left to right, top to bottom.
*/
public static Rectangle getTile (
int width, int height, int tileWidth, int tileHeight, int tileIndex)
{
Rectangle bounds = new Rectangle();
getTile(width, height, tileWidth, tileHeight, tileIndex, bounds);
return bounds;
}
/**
* Fills in the bounds of the specified tile in the supplied larger rectangle. Tiles go from
* left to right, top to bottom.
*/
public static void getTile (int width, int height, int tileWidth, int tileHeight, int tileIndex,
Rectangle bounds)
{
// figure out from whence to crop the tile
int tilesPerRow = width / tileWidth;
// if we got a bogus region, return bogus tile bounds
if (tilesPerRow == 0) {
return new Rectangle(0, 0, width, height);
bounds.setBounds(0, 0, width, height);
} else {
int row = tileIndex / tilesPerRow;
int col = tileIndex % tilesPerRow;
// crop the tile-sized image chunk from the full image
bounds.setBounds(tileWidth*col, tileHeight*row, tileWidth, tileHeight);
}
int row = tileIndex / tilesPerRow;
int col = tileIndex % tilesPerRow;
// crop the tile-sized image chunk from the full image
return new Rectangle(
tileWidth*col, tileHeight*row, tileWidth, tileHeight);
}
}