Difference between revisions of "User:Chase-san/GeomTools"

From Robowiki
Jump to navigation Jump to search
m (minor fix)
m
Line 163: Line 163:
 
 
 
public static final Point2D[] intersectCircleLine(Point2D c, double r, Line2D p1) {
 
public static final Point2D[] intersectCircleLine(Point2D c, double r, Line2D p1) {
    double dx = c.getX() - p1.getX1();
+
double dx = c.getX() - p1.getX1();
    double dy = c.getY() - p1.getY1();
+
double dy = c.getY() - p1.getY1();
 
 
    double dirx = p1.getX2() - p1.getX1();
+
double dirx = p1.getX2() - p1.getX1();
    double diry = p1.getY2() - p1.getY1();
+
double diry = p1.getY2() - p1.getY1();
    double a0 = Math.sqrt(dirx*dirx+diry*diry);
+
double a0 = Math.sqrt(dirx*dirx+diry*diry);
    dirx /= a0;
+
dirx /= a0;
    diry /= a0;
+
diry /= a0;
  
    a0 = dx*dx + dy*dy - r*r;
+
a0 = dx*dx + dy*dy - r*r;
    double a1 = dx*dirx + dy*diry;
+
double a1 = dx*dirx + dy*diry;
    double discr = a1*a1 - a0;
+
double discr = a1*a1 - a0;
 
 
    double m1 = 0;
+
double m1 = 0;
    double m2 = 0;
+
double m2 = 0;
 
 
    if (discr > 0) {
+
if (discr > 0) {
        discr = Math.sqrt(discr);
+
discr = Math.sqrt(discr);
        m1 = a1 - discr;
+
m1 = a1 - discr;
        m2 = a1 + discr;
+
m2 = a1 + discr;
        return new Point2D[]{
+
return new Point2D[]{
 
        new Point2D.Double( p1.getX1() + m1*dirx, p1.getY1() + m1*diry ),
 
        new Point2D.Double( p1.getX1() + m1*dirx, p1.getY1() + m1*diry ),
 
        new Point2D.Double( p1.getX1() + m2*dirx, p1.getY1() + m2*diry )
 
        new Point2D.Double( p1.getX1() + m2*dirx, p1.getY1() + m2*diry )
        };
+
        };
    } else if(discr == 0) {
+
} else if(discr == 0) {
        m1 = a1;
+
m1 = a1;
        return new Point2D[]{
+
return new Point2D[]{
 
        new Point2D.Double( p1.getX1() + m1*dirx, p1.getY1() + m1*diry )
 
        new Point2D.Double( p1.getX1() + m1*dirx, p1.getY1() + m1*diry )
        };
+
        };
    }
+
}
    return new Point2D[0];
+
return new Point2D[0];
 
}
 
}
 
 
Line 207: Line 207:
 
double length = p1.getP1().distance(p1.getP2());
 
double length = p1.getP1().distance(p1.getP2());
  
    a0 = dx*dx + dy*dy - r*r;
+
a0 = dx*dx + dy*dy - r*r;
 
double a1 = dx*dirx + dy*diry;
 
double a1 = dx*dirx + dy*diry;
    double discr = a1*a1 - a0;
+
double discr = a1*a1 - a0;
 
 
 
double m1 = 0;
 
double m1 = 0;
 
double m2 = 0;
 
double m2 = 0;
 
 
    if (discr > 0) {
+
if (discr > 0) {
        discr = Math.sqrt(discr);
+
discr = Math.sqrt(discr);
        m1 = a1 - discr;
+
m1 = a1 - discr;
        m2 = a1 + discr;
+
m2 = a1 + discr;
        if(m1 > 0 && m1 < length && m2 > 0 && m2 < length)
+
if(m1 > 0 && m1 < length && m2 > 0 && m2 < length)
        return new Point2D[]{
+
        return new Point2D[]{
 
        new Point2D.Double( p1.getX1() + m1*dirx, p1.getY1() + m1*diry ),
 
        new Point2D.Double( p1.getX1() + m1*dirx, p1.getY1() + m1*diry ),
 
        new Point2D.Double( p1.getX1() + m2*dirx, p1.getY1() + m2*diry )
 
        new Point2D.Double( p1.getX1() + m2*dirx, p1.getY1() + m2*diry )
        };
+
        };
        else if(m1 > 0 && m1 < length)
+
        else if(m1 > 0 && m1 < length)
        return new Point2D[]{
+
        return new Point2D[]{
 
        new Point2D.Double( p1.getX1() + m1*dirx, p1.getY1() + m1*diry ),
 
        new Point2D.Double( p1.getX1() + m1*dirx, p1.getY1() + m1*diry ),
 
        };
 
        };
        else if(m2 > 0 && m2 < length)
+
        else if(m2 > 0 && m2 < length)
        return new Point2D[]{
+
        return new Point2D[]{
        new Point2D.Double( p1.getX1() + m2*dirx, p1.getY1() + m2*diry ),
+
        new Point2D.Double( p1.getX1() + m2*dirx, p1.getY1() + m2*diry ),
        };
+
        };
    } else if(discr == 0) {
+
} else if(discr == 0) {
    //Its a tangent
+
//Its a tangent
        m1 = a1;
+
m1 = a1;
        if(m1 > 0 && m1 < length)
+
if(m1 > 0 && m1 < length)
        return new Point2D[]{
+
return new Point2D[]{
 
        new Point2D.Double( p1.getX1() + m1*dirx, p1.getY1() + m1*diry )
 
        new Point2D.Double( p1.getX1() + m1*dirx, p1.getY1() + m1*diry )
 
        };
 
        };
    }
+
}
    return new Point2D[0];
+
return new Point2D[0];
 
}
 
}
 
 

Revision as of 03:18, 8 July 2010

My set of geometry based tools.

import java.awt.geom.*;
import java.util.ArrayList;

/**
 * I honestly wrote all these from scratch!
 * 
 * @author Chase
 */
public final class GeomTools {
	private GeomTools() {}
	public static final Line2D[] rectToLines(Rectangle2D rect) {
		Line2D[] lines = new Line2D[4];
		//Left, Right, Bottom, Top
		lines[0] = new Line2D.Double(rect.getMinX(),rect.getMinY(),rect.getMinX(),rect.getMaxY());
		lines[1] = new Line2D.Double(rect.getMaxX(),rect.getMinY(),rect.getMaxX(),rect.getMaxY());
		lines[2] = new Line2D.Double(rect.getMinX(),rect.getMinY(),rect.getMaxX(),rect.getMinY());
		lines[3] = new Line2D.Double(rect.getMinX(),rect.getMaxY(),rect.getMaxX(),rect.getMaxY());
		return lines;
	}
	/**
	 * Gets intersections between a rectangle and a line 
	 * @param rect Rectangle
	 * @param line Line
	 * @return The points that it intesects with, or a zero length array if
	 * 		no intersections occur.
	 */
	public static final Point2D[] intersectRectLine(Rectangle2D rect, Line2D line) {
		ArrayList<Point2D> points = new ArrayList<Point2D>();
		Line2D[] r = rectToLines(rect);
		for(Line2D edge : r) {
			Point2D sec = intersectSegLine(edge, line);
			if(sec != null)
				points.add(sec);
		}
		Point2D[] ps = new Point2D[points.size()];
		points.toArray(ps);
		return ps;
	}
	
	/**
	 * Gets intersections between a rectangle and a line 
	 * @param rect Rectangle
	 * @param line Line
	 * @return The points that it intesects with, or a zero length array if
	 * 		no intersections occur.
	 */
	public static final Point2D[] intersectRectCircle(Rectangle2D rect, Point2D c, double r) {
		ArrayList<Point2D> points = new ArrayList<Point2D>();
		Line2D[] rct = rectToLines(rect);
		for(Line2D edge : rct) {
			Point2D sec[] = intersectCircleSeg(c, r, edge);
			for(Point2D p : sec)
				points.add(p);
		}
		Point2D[] ps = new Point2D[points.size()];
		points.toArray(ps);
		return ps;
	}
	
	/**
	 * Gets intersections between a rectangle and a line segment
	 * @param rect Rectangle
	 * @param line Line Segment
	 * @return The points that it intesects with, or a zero length array if
	 * 		no intersections occur.
	 */
	public static final Point2D[] intersectRectSeg(Rectangle2D rect, Line2D line) {
		ArrayList<Point2D> points = new ArrayList<Point2D>();
		Line2D[] r = rectToLines(rect);
		for(Line2D edge : r) {
			Point2D sec = intersectSegSeg(edge, line);
			if(sec != null) {
				points.add(sec);
			}
		}
		Point2D[] ps = new Point2D[points.size()];
		points.toArray(ps);
		return ps;
	}
	public static final Point2D intersectLineLine(Line2D p1, Line2D p2) {
		double dom = (p2.getY2()-p2.getY1())*(p1.getX2()-p1.getX1())
					-(p2.getX2()-p2.getX1())*(p1.getY2()-p1.getY1());
		double ua = (p2.getX2()-p2.getX1())*(p1.getY1()-p2.getY1())
					-(p2.getY2()-p2.getY1())*(p1.getX1()-p2.getX1());
		//If dom is 0 then they are parallel
		if(Math.abs(dom) < 0.0001)
			return null;
		
		ua /= dom;

		Point2D P = new Point2D.Double(
				p1.getX1() + ua*(p1.getX2()-p1.getX1()),
				p1.getY1() + ua*(p1.getY2()-p1.getY1()));
		
		return P;
	}
	
	public static final Point2D intersectLineSeg(Line2D p1, Line2D p2) {
		double dom = (p2.getY2()-p2.getY1())*(p1.getX2()-p1.getX1())
					-(p2.getX2()-p2.getX1())*(p1.getY2()-p1.getY1());
		double ub = (p1.getX2()-p1.getX1())*(p1.getY1()-p2.getY1())
					-(p1.getY2()-p1.getY1())*(p1.getX1()-p2.getX1());
		//If dom is 0 then they are parallel
		//If ua and ub are also 0, then they are coincident
		if(Math.abs(dom) < 0.0001)
			return null;
		ub /= dom;
		if(ub >= 0.0 && ub <= 1.0) {
			Point2D P = new Point2D.Double(
					p1.getX1() + ub*(p1.getX2()-p1.getX1()),
					p1.getY1() + ub*(p1.getY2()-p1.getY1()));
			return P;
		}
		return null;
	}
	
	public static final Point2D intersectSegLine(Line2D p1, Line2D p2) {
		double dom = (p2.getY2()-p2.getY1())*(p1.getX2()-p1.getX1())
					-(p2.getX2()-p2.getX1())*(p1.getY2()-p1.getY1());
		double ua = (p2.getX2()-p2.getX1())*(p1.getY1()-p2.getY1())
					-(p2.getY2()-p2.getY1())*(p1.getX1()-p2.getX1());
		//If dom is 0 then they are parallel
		//If ua and ub are also 0, then they are coincident
		if(Math.abs(dom) < 0.0001)
			return null;
		ua /= dom;
		if(ua >= 0.0 && ua <= 1.0) {
			Point2D P = new Point2D.Double(
					p1.getX1() + ua*(p1.getX2()-p1.getX1()),
					p1.getY1() + ua*(p1.getY2()-p1.getY1()));
			return P;
		}
		return null;
	}
	
	public static final Point2D intersectSegSeg(Line2D p1, Line2D p2) {
		double dom = (p2.getY2()-p2.getY1())*(p1.getX2()-p1.getX1())
					-(p2.getX2()-p2.getX1())*(p1.getY2()-p1.getY1());
		double ua = (p2.getX2()-p2.getX1())*(p1.getY1()-p2.getY1())
					-(p2.getY2()-p2.getY1())*(p1.getX1()-p2.getX1());
		double ub = (p1.getX2()-p1.getX1())*(p1.getY1()-p2.getY1())
					-(p1.getY2()-p1.getY1())*(p1.getX1()-p2.getX1());
		//If dom is 0 then they are parallel
		//If ua and ub are also 0, then they are coincident
		if(Math.abs(dom) < 0.0001)
			return null;
		ua /= dom;
		ub /= dom;
		if(ua >= 0.0 && ua <= 1.0
		&& ub >= 0.0 && ub <= 1.0) {
			
			Point2D P = new Point2D.Double(
					p1.getX1() + ua*(p1.getX2()-p1.getX1()),
					p1.getY1() + ua*(p1.getY2()-p1.getY1()));
			return P;
		}
		return null;
	}
	
	public static final Point2D[] intersectCircleLine(Point2D c, double r, Line2D p1) {
		double dx = c.getX() - p1.getX1();
		double dy = c.getY() - p1.getY1();
		
		double dirx = p1.getX2() - p1.getX1();
		double diry = p1.getY2() - p1.getY1();
		double a0 = Math.sqrt(dirx*dirx+diry*diry);
		dirx /= a0;
		diry /= a0;

		a0 = dx*dx + dy*dy - r*r;
		double a1 = dx*dirx + dy*diry;
		double discr = a1*a1 - a0;
		
		double m1 = 0;
		double m2 = 0;
		
		if (discr > 0) {
			discr = Math.sqrt(discr);
			m1 = a1 - discr;
			m2 = a1 + discr;
			return new Point2D[]{
	        		new Point2D.Double( p1.getX1() + m1*dirx, p1.getY1() + m1*diry ),
	        		new Point2D.Double( p1.getX1() + m2*dirx, p1.getY1() + m2*diry )
	        	};
		} else if(discr == 0) {
			m1 = a1;
			return new Point2D[]{
	        		new Point2D.Double( p1.getX1() + m1*dirx, p1.getY1() + m1*diry )
	        	};
		}
		return new Point2D[0];
	}
	
	public static final Point2D[] intersectCircleSeg(Point2D c, double r, Line2D p1) {
		double dx = c.getX() - p1.getX1();
		double dy = c.getY() - p1.getY1();
		
		double dirx = p1.getX2() - p1.getX1();
		double diry = p1.getY2() - p1.getY1();
		double a0 = Math.sqrt(dirx*dirx+diry*diry);
		dirx /= a0;
		diry /= a0;
		double length = p1.getP1().distance(p1.getP2());

		a0 = dx*dx + dy*dy - r*r;
		double a1 = dx*dirx + dy*diry;
		double discr = a1*a1 - a0;
		
		double m1 = 0;
		double m2 = 0;
		
		if (discr > 0) {
			discr = Math.sqrt(discr);
			m1 = a1 - discr;
			m2 = a1 + discr;
			if(m1 > 0 && m1 < length && m2 > 0 && m2 < length)
		        	return new Point2D[]{
	        			new Point2D.Double( p1.getX1() + m1*dirx, p1.getY1() + m1*diry ),
	        			new Point2D.Double( p1.getX1() + m2*dirx, p1.getY1() + m2*diry )
		        	};
		        else if(m1 > 0 && m1 < length)
		        	return new Point2D[]{
	        			new Point2D.Double( p1.getX1() + m1*dirx, p1.getY1() + m1*diry ),
	        		};
		        else if(m2 > 0 && m2 < length)
		        	return new Point2D[]{
			        	new Point2D.Double( p1.getX1() + m2*dirx, p1.getY1() + m2*diry ),
			        };
		} else if(discr == 0) {
			//Its a tangent
			m1 = a1;
			if(m1 > 0 && m1 < length)
				return new Point2D[]{
	        			new Point2D.Double( p1.getX1() + m1*dirx, p1.getY1() + m1*diry )
	        		};
		}
		return new Point2D[0];
	}
	
	public static final boolean testCircle(Point2D s1, double r1, Point2D s2, double r2) {
		return s1.distanceSq(s2) < r1*r1+r2*r2; 
	}
	
	/**
	 * Tests two moving circles, with directional vectors <s1x,s1y> and <s2x,s2y>
	 */
	public static final boolean testCircle(Point2D s1, double r1, Point2D s2, double r2,
			double s1x, double s1y, double s2x, double s2y, int time) {
		double rVx = s1x - s2x;
		double rVy = s1y - s2y;
		double a = rVx*rVx + rVy*rVy;
		double dx = s1.getX() - s2.getX();
		double dy = s1.getY() - s2.getY();
		double c = dx*dx+dy*dy;
		double rSum = r1 + r2;
		double rSumSqr = rSum * rSum;
		if(a > 0.0) {
			double b = dx*rVx+dy*rVy;
			if(b <= 0.0) {
				if(-time * a <= b)
					return a * c - b * b <= a * rSumSqr;
				return time * (time * a + 2.0 * b) + c <= rSumSqr;
			}
		}
		return c <= rSumSqr;
	}
	
	public static final Point2D[] getCorners(Rectangle2D rect) {
		Point2D[] corner = new Point2D[4];
		corner[0] = new Point2D.Double(rect.getMinX(),rect.getMinY());
		corner[1] = new Point2D.Double(rect.getMinX(),rect.getMaxY());
		corner[2] = new Point2D.Double(rect.getMaxX(),rect.getMinY());
		corner[3] = new Point2D.Double(rect.getMaxX(),rect.getMaxY());
		return corner;
	}
	
	public static final Point2D between(Point2D p1, Point2D p2) {
		double x = p1.getX() + p2.getX();
		double y = p1.getY() + p2.getY();
		return new Point2D.Double(x/2.0,y/2.0);
	}
}