So i'm given to crop out points that are not inside my rectangle or points that lie on the boundrey line. The rectangle is made up of the two points that are taken in by the method p1, p2. so for example if you have the points [(3.0,1.0), (2.0,2.0), (1.5,1.5), (3.0,0.0)] after the crop you should have [(3.0,1.0), (3.0,0.0)] so basically the method should remove all points that are out side the given points..
I solved it this way. But i get some weird errors when it comes to negative numbers..
public void crop(Point p1, Point p2) {
double highX = 0;
double lowX = 0;
double highY = 0;
double lowY = 0;
if (p1.getX() > p2.getX()) {
highX = p1.getX();
lowX = p2.getX();
} else {
highX = p2.getX();
lowX = p1.getX();
}
if (p1.getY() > p2.getY()) {
highY = p1.getY();
lowY = p2.getY();
} else {
highY = p2.getY();
lowY = p1.getY();
}
for (int i = 0; i < points.size(); i++) {
Point P = points.get(i);
if (Math.abs(P.getX() - lowX) < Point.EPSILON
|| Math.abs(P.getX() - highX) < Point.EPSILON
|| Math.abs(P.getY() - lowY) < Point.EPSILON
|| Math.abs(P.getY() - highY) < Point.EPSILON) {
System.out.println(Math.abs(P.getX() - highX) < Point.EPSILON);
System.out.println("Keeping: " + points.get(i));
// keep
} else {
System.out.println("Remvoing: " + points.get(i));
points.remove(i);
}
if (P.getX() < lowX || P.getX() > highX || P.getY() < lowY
|| P.getY() > highY) {
System.out.println("Removing: " + points.get(i));
points.remove(i);
}
}
}
any help solving this problem would be nice i've been stuck for a while now
There is the java.awt.Rectangle for integer and java.awt.Rectangle2D class with the method contains(x, y).
This will solve the case when the points is inside the Rectangle or on the left or upper border.
For good reasons you should not treat points on the right and lower border as beeing inside.
Talk with the person that demandend that.
Otherwise you may get points that are inside both of two touching rectangles, and this is not a good solution.
Further ist is usual to specify: "If a point is exactly at the border, the method may return true or false".
However for axe-parallel rectangles the "to-be-inside-or-on-the-border" task is easy to solve. Look at the src of that java methods and change < to <=. (or similar)
I eventually came up with this as a solution to the problem
public void crop(Point p1, Point p2) {
double highX = 0;
double lowX = 0;
double highY = 0;
double lowY = 0;
ArrayList<Point> list = new ArrayList<Point>();
if (p1.getX() > p2.getX()) {
highX = p1.getX();
lowX = p2.getX();
} else {
highX = p2.getX();
lowX = p1.getX();
}
if (p1.getY() > p2.getY()) {
highY = p1.getY();
lowY = p2.getY();
} else {
highY = p2.getY();
lowY = p1.getY();
}
if (p1.equals(p2)) {
list.add(p1);
points = list;
return;
}
double i = 0;
while (i < points.size()) {
Point P = points.get((int) i);
if (P.getX() < highX + EPSILON && P.getX() > lowX - EPSILON
&& P.getY() < highY + EPSILON && P.getY() > lowY - EPSILON) {
list.add(P);
}
i++;
}//thank god
points = list;
}
Related
I'm trying to get my code to recreate a random x and y value if there is already another object occupying the chosen value. But for some reason, the loop just keeps giving me the same float value causing it to loop forever instead of creating new value and then checking that one against previous x and y variables. Here's the code. Let me know if you need anymore.
static int numberOfDots = 5;
static int windowSize = 400;
float[] pos = new float[2];
float[] vel = new float[2];
float[] acc = new float[2];
float dotSize = 0;
float dotMass = 0;
float dotWidth = 0;
float dotRadius = 0;
float[] centrePos = new float[2];
float[][] dots = new float[numberOfDots][10];
//for making dots
boolean first = true;
boolean creationCollision = false;
boolean dotCollision = false;
// pos means x and y positions
// vel means x and y velocity
// centrePos means centre of the dot x and y
// dotMass isnt implemented yet
public boolean collisionOnCreate() {
//compare all dots
for (int i = 0; i < dots.length; i++) {
//against any dots later in the array
// since they will already have compared themselves to dots previous in the array
// - dont need to loop over them again
for (int a = i + 1; a < dots.length; a++) {
if (dots[a][0] != 0) {
creationCollision = dots[i][1] + dots[i][8] > dots[a][1] && dots[i][1] + dots[i][8] < dots[a][1] + dots[a][8] || dots[i][1] > dots[a][1] && dots[i][1] < dots[a][1] + dots[a][8] || dots[i][0] > dots[a][0] && dots[i][0] < dots[a][0] + dots[a][8] || dots[i][0] + dots[i][8] > dots[a][0] && dots[i][0] + dots[i][8] < dots[a][0] + dots[a][8];
System.out.println(dots[a][0] + " " + dots[a][1]);
}
//check if the left-most part of the dot is anywhere between the leftmost and right most part of another dot
//check if the rightmost part of the dot is anywhere between the left most and right most part of another dot
//check if the top part of the dot is anywhere between the top and bottom part of another dot
//check if the bottom of the dot is anywhere between the top and bottom part of another dot
// I know its long but its easier then running a bunch of if statements to do the same task
}
}
return creationCollision;
}
public void createDots(int i) {
pos[0] = r.nextFloat() * 300;
pos[1] = r.nextFloat() * 300;
dotWidth = r.nextFloat() * 30;
if (dotWidth < 5) {
dotWidth *= 10;
}
dotRadius = dotWidth / 2;
dotMass = r.nextFloat() / 10;
centrePos[0] = centrePos[0] + dotRadius;
centrePos[1] = pos[1] + dotRadius;
vel[0] = r.nextFloat() / 10;
vel[1] = r.nextFloat() / 10;
check(i);
}
public void check(int i) {
collisionOnCreate();
if (creationCollision) {
createDots(i);
System.out.println("collision on creation");
} else {
setValues(i);
System.out.println("dot number " + i + " is created");
}
}
public void setValues(int i) {
dots[i][0] = pos[0];
dots[i][1] = pos[1];
dots[i][2] = vel[0];
dots[i][3] = vel[1];
dots[i][4] = dotRadius;
dots[i][5] = centrePos[0];
dots[i][6] = centrePos[1];
dots[i][7] = dotMass;
dots[i][8] = dotWidth;
}
//create an array of dots and assign them values for x, y, radius, etc.
public float[][] Dots() {
if (first == true) {
for (int i = 0; i < numberOfDots; i++) {
createDots(i);
}
first = false;
} else {
for (int i = 0; i < numberOfDots; i++) {
// update values
dots[i][0] = dots[i][0] + dots[i][2];
dots[i][1] = dots[i][1] + dots[i][3];
centrePos[0] = dots[i][0] + dots[i][4];
centrePos[1] = dots[i][1] + dots[i][4];
dots[i][5] = centrePos[0];
dots[i][6] = centrePos[1];
collisionOnWall(i);
}
}
repaint();
return dots;
}
I don't think the problem is with random number generation. Instead there is something wrong with the logic of creation / checking.
It seems that first, inside of createDots(), you assign values to some variables that are meant to represent a new dot (why don't make a dedicated class for that?). Then you don't add that new dot to dots array but instead you go straight to checking if there are any collisions.
However, you only check the values that are already present in the dots array, without taking into account the newly created one.
Another thing, that creationCollision condition is really unreadable to me. You should use some parentheses just for the clarity. Plus make sure it is actually doing what you want it to.
You don't appear to ever set dots[i] to your new values here:
public void createDots(int i) {
pos[0] = r.nextFloat() * 300;
pos[1] = r.nextFloat() * 300;
dotWidth = r.nextFloat() * 30;
if (dotWidth < 5) {
dotWidth *= 10;
}
dotRadius = dotWidth / 2;
dotMass = r.nextFloat() / 10;
centrePos[0] = centrePos[0] + dotRadius;
centrePos[1] = pos[1] + dotRadius;
vel[0] = r.nextFloat() / 10;
vel[1] = r.nextFloat() / 10;
check(i);
}
Looks like you want to call setValues(i) at the end, just before check(i).
I have this method:
public boolean moveTowardsPoint(Point p, double stepSize, double minDistance, ArrayList<GameBodyObject> objects, boolean shouldStepInto, AStar astar) {
ArrayList<GameBodyObject> others = (ArrayList<GameBodyObject>) objects.clone();
others.remove(this);
if(aStarPath == null || lastPointToMove == null || !lastPointToMove.isAlmostTheSame(p, 0.01)) {
try {
astar.getGrid().unsetObstacleForObject(this);
aStarPath = astar.process(this, p, objects);
Collections.reverse(aStarPath);
currentIndex = 0;
current = null;
astar.getGrid().reset();
} catch(Exception e) {
e.printStackTrace();
}
}
lastPointToMove = p.clone();
double dx = p.getX() - getPosition().getX();
double dy = p.getY() - getPosition().getY();
Point lastPosition = getPosition().clone();
boolean isClose = false;
double dist = Math.sqrt(dx * dx + dy * dy);
if (dist < Math.max(minDistance, stepSize)) {
isClose = true;
} else {
if(aStarPath.indexOf(current) >= aStarPath.size() - 1) {
if(shouldStepInto && dist <= stepSize) {
setPosition(p.clone());
}
} else if(aStarPath != null && aStarPath.size() > 0) {
if (current == null) {
currentIndex = 0;
current = aStarPath.get((int)currentIndex);
}
double mss = stepSize / current.getWidth();
Spot p2 = aStarPath.get(Math.min((int)Math.ceil(currentIndex + mss), aStarPath.size() - 1));
Spot p1 = current;
if(!p1.equals(p2)) {
Vector v = new Vector(p2.getX() - p1.getX(), p2.getY() - p1.getY()).normalize();
getPosition().moveByVector(v.mult(stepSize));
setRotation(v.getAngle());
}
currentIndex = Math.min(currentIndex + mss, aStarPath.size() - 1);
current = aStarPath.get((int)currentIndex);
}
}
return isClose;
}
It's a GameBodyObject's method.
It should calculate A* path and move towards a point on that path however it does move slower than a current(currentIndex) moves forward through the path. I have there some distance checking at the beginning but that's not important. I move currentIndex by the amount of stepSize divided by the grid cell size. In my case it's 0.6. Then I have a moveByVector method which simply moves a Point by the vector.
How to make it synchronous so that it moves as fast as current(currentIndex)? Is it even possible?
EDIT
Here are my variables definitions:
private List<Spot> aStarPath = null;
private Spot current = null;
private double currentIndex = -1;
private Point lastPointToMove;
There was a one mistake in that solution. On diagonals the currentIndex growed faster than the player moved. So you have to take in account the angle in which the player is moving along that path. Concretely this:
double coef = Math.max(Math.abs(Math.cos(angle)),Math.abs(Math.sin(angle)));
double mss = stepSize / (current.getWidth() / coef);
The full method now looks like this and works like a charm:
public boolean moveTowardsPoint(Point p, double stepSize, double minDistance, ArrayList<GameBodyObject> objects, boolean shouldStepInto, AStar astar) {
ArrayList<GameBodyObject> others = (ArrayList<GameBodyObject>) objects.clone();
others.remove(this);
if(aStarPath == null || lastPointToMove == null || !lastPointToMove.isAlmostTheSame(p, 0.01)) {
try {
astar.getGrid().unsetObstacleForObject(this);
aStarPath = astar.process(this, p, objects);
Collections.reverse(aStarPath);
currentIndex = 0;
current = null;
astar.getGrid().reset();
} catch(Exception e) {
e.printStackTrace();
}
}
lastPointToMove = p.clone();
double dx = p.getX() - getPosition().getX();
double dy = p.getY() - getPosition().getY();
Point lastPosition = getPosition().clone();
boolean isClose = false;
double dist = Math.sqrt(dx * dx + dy * dy);
if (dist < Math.max(minDistance, stepSize)) {
isClose = true;
} else {
if(aStarPath.indexOf(current) >= aStarPath.size() - 1) {
if(shouldStepInto && dist <= stepSize) {
setPosition(p.clone());
}
} else if(aStarPath != null && aStarPath.size() > 0) {
if (current == null) {
currentIndex = 0;
current = aStarPath.get((int)currentIndex);
}
Spot c1 = aStarPath.get((int)currentIndex);
Spot c2 = aStarPath.get(Math.min((int)currentIndex + 1, aStarPath.size() - 1));
double angle = new Vector(c2.getX() - c1.getX(),c2.getY() - c1.getY()).getAngle();
double coef = Math.max(Math.abs(Math.cos(angle)),Math.abs(Math.sin(angle)));
double mss = stepSize / (current.getWidth() / coef);
Spot p2 = aStarPath.get(Math.min((int)Math.ceil(currentIndex + mss), aStarPath.size() - 1));
Spot p1 = current;
if(!p1.equals(p2)) {
Vector v = new Vector(p2.getX() - p1.getX(), p2.getY() - p1.getY()).normalize();
getPosition().moveByVector(v.mult(stepSize));
setRotation(v.getAngle());
}
currentIndex = Math.min(currentIndex + mss, aStarPath.size() - 1);
current = aStarPath.get((int)currentIndex);
}
}
return isClose;
}
Hello :) I'm totally lost. I have two balls on the screen, floating. Also I have a method that checks is there is a collision and a method name 'collide' that collides :)
When both balls goes in a straight line on each other it collides well. The problem is shown on the picture:
So, the methods are:
public final float ball_radius = 2.4f; // ball image has 48 width
public boolean isColliding(Ball ball)
{
distance = Math.sqrt((ball.image_center_x - this.image_center_x)*(ball.image_center_x - this.image_center_x)+(ball.image_center_y - this.image_center_y)*(ball.image_center_y - this.image_center_y));
if(distance <= 2*ball_radius)
return true;
/*
float sumRadius = 9.6f;
float sqrRadius = sumRadius * sumRadius;
float distSqr = (xd * xd) + (yd * yd);
if (distSqr <= sqrRadius)
{
return true;
}*/
return false;
}
void Collide(Ball ball1, Ball ball2)
{
double dx = (ball1.x - ball2.x) + dt * (ball1.vx - ball2.vx);
double dy = (ball1.y - ball2.y) + dt * (ball1.vy - ball2.vy);
// if collision swap velocities
if (Math.sqrt(dx * dx + dy * dy) <= 2*ball_radius) {
double tempx = ball1.vx;
double tempy = ball1.vy;
ball1.vx = ball2.vx;
ball1.vy = ball2.vy;
ball2.vx = tempx;
ball2.vy = tempy;
}
}
private void moveBalls(){
for (int i = 0; i < balls.size(); i++) {
Ball ball1 = balls.get(i);
for (int a = i + 1; a < balls.size(); a++) {
Ball ball2 = balls.get(a);
if(ball1.isColliding(ball2)) {
ball1.Collide(ball1, ball2);
checkHealthAndChangeColor(ball1, ball2);
}
//catchMP.start();
}
}
for (int i = 0; i < balls.size(); i++) {
balls.get(i).step();
}
}
I currently loop through all my sprites checking if they intersect with each other like this:
for (Sprite s : sprites) {
if (s.dead) {
dead.add(s);
}
for (Sprite sprite : sprites) {
if (!sprite.equals(s)) {
s.collide(sprite, maxX, maxY);
}
}
s.run();
}
and the sprite checks using the Rect.intersects() method like so:
if (getRect().intersects(s.getRect()))
But sometimes it just completely ignores a collision, and the objects just pass through each other.
Any ideas?
You should try changing the code to
if(getRect().intersects(s.getRect()) || s.getRect().intersects(getRect()))
{
// They have intersected
}
The reason for this being, the intersection method check is unique for each rectangle. Performing an intersection check to see if rectangle a intersects rectangle b, is different than performing an intersection check to see if rectangle b intersects rectangle a.
Other than this, can you give me more information on your rectangles? Are they rotating? How fast are they moving? How large are they? Other information would be use full as well, I can try to think of other reasons for why they are not colliding.
I fixed it by making it create a rectangle for the area that it covers between frames like so:
private void checkForNextCollision() {
double boundsWidth = width + dX ;
if(dX < 0){
boundsWidth= width - dX ;
}
double boundsHeight = height + dY ;
if(dY < 0){
boundsHeight = height - dY ;
}
double boundx = xWorld + dX ;
double boundy = yWorld + dY ;
betweenRect = new Rectangle((int)(boundx),(int)(boundy),(int)(boundsWidth), (int)(boundsHeight));
}
This rectangle is then checked against the rectangle created in the other sprites to check if there should be a collision in the next frame:
public void collide(Sprite s, int maxX, int maxY) {
maxWX = maxX;
maxWY = maxY;
//check for collision with borders
if (xWorld <= 0) {
dX = -dX;
xWorld += 2;
if(xWorld < -1000){
dX = 0;
xWorld += 10;
}
}
if (yWorld <= 0) {
dY = -dY;
yWorld += 2;
if(yWorld < -1000){
dX = 0;
yWorld += 10;
}
}
if (xWorld + width >= maxX) {
dX = -dX;
xWorld -= 2;
if(xWorld+width > maxX + 1000){
dX = 0;
xWorld -= 10;
}
}
if (yWorld + height >= maxY) {
dY = -dY;
yWorld -= 2;
if(yWorld+height > maxY + 1000){
dY = 0;
yWorld -= 10;
}
}
//check for collision with borders
if(betweenRect.intersects(s.betweenRect)){
willIntersect = true;
}else{
willIntersect = false;
}
// Use all checks to see if they should collide
if (getRect().intersects(s.getRect()) || s.getRect().intersects(getRect()) || willIntersect || (xWorld + width > s.xWorld && xWorld < s.xWorld + s.width && yWorld < s.yWorld+s.height && yWorld + height > s.yWorld) ) {
double lastDy = dY;
double lastsDy = s.dY;
double lastDx = dX;
double lastsDx = s.dX;
dY = (((weight - s.weight) / (weight + s.weight)) * lastDy)
+ (((2.0 * s.weight) / (weight + s.weight)) * lastsDy);
s.dY = (((s.weight - weight) / (weight + s.weight)) * lastsDy)
+ (((2.0 * weight) / (weight + s.weight)) * lastDy);
dX = (((weight - s.weight) / (weight + s.weight)) * lastDx)
+ (((2.0 * s.weight) / (weight + s.weight)) * lastsDx);
s.dX = (((s.weight - weight) / (weight + s.weight)) * lastsDx)
+ (((2.0 * weight) / (weight + s.weight)) * lastDx);
if(willIntersect){
willIntersect = false;
//s.willIntersect = false;
}
}
}
I want to know how to get the bounds of an QuadCurve2D. I found a method to get the bounds from a CubicCurve2D.
Using this methods is possible to change it to use QuadCurve2D?
private static void ProcessMonotonicCubic(double[] coords, double[] bbox ) {
if (bbox[0] > coords[0]) bbox[0] = coords[0];
if (bbox[1] > coords[1]) bbox[1] = coords[1];
if (bbox[2] < coords[0]) bbox[2] = coords[0];
if (bbox[3] < coords[1]) bbox[3] = coords[1];
if (bbox[0] > coords[6]) bbox[0] = coords[6];
if (bbox[1] > coords[7]) bbox[1] = coords[7];
if (bbox[2] < coords[6]) bbox[2] = coords[6];
if (bbox[3] < coords[7]) bbox[3] = coords[7];
}
/*
* Bite the piece of the cubic curve from start point till the point
* corresponding to the specified parameter then call ProcessCubic for the
* bitten part.
* Note: coords array will be changed
*/
private static void ProcessFirstMonotonicPartOfCubic(double[] coords,
double[] bbox,
double t)
{
double[] coords1 = new double[8];
double tx, ty;
coords1[0] = coords[0];
coords1[1] = coords[1];
tx = coords[2] + t*(coords[4] - coords[2]);
ty = coords[3] + t*(coords[5] - coords[3]);
coords1[2] = coords[0] + t*(coords[2] - coords[0]);
coords1[3] = coords[1] + t*(coords[3] - coords[1]);
coords1[4] = coords1[2] + t*(tx - coords1[2]);
coords1[5] = coords1[3] + t*(ty - coords1[3]);
coords[4] = coords[4] + t*(coords[6] - coords[4]);
coords[5] = coords[5] + t*(coords[7] - coords[5]);
coords[2] = tx + t*(coords[4] - tx);
coords[3] = ty + t*(coords[5] - ty);
coords[0]=coords1[6]=coords1[4] + t*(coords[2] - coords1[4]);
coords[1]=coords1[7]=coords1[5] + t*(coords[3] - coords1[5]);
ProcessMonotonicCubic(coords1, bbox);
}
/*
* Split cubic curve into monotonic in X and Y parts. Calling
* ProcessMonotonicCubic for each monotonic piece of the curve.
*
* Note: coords array could be changed
*/
private static void ProcessCubic(double[] coords, double[] bbox) {
/* Temporary array for holding parameters corresponding to the extreme
* in X and Y points
*/
double params[] = new double[4];
double eqn[] = new double[3];
double res[] = new double[2];
int cnt = 0;
/* Simple check for monotonicity in X before searching for the extreme
* points of the X(t) function. We first check if the curve is
* monotonic in X by seeing if all of the X coordinates are strongly
* ordered.
*/
if ((coords[0] > coords[2] || coords[2] > coords[4] ||
coords[4] > coords[6]) &&
(coords[0] < coords[2] || coords[2] < coords[4] ||
coords[4] < coords[6]))
{
/* Searching for extreme points of the X(t) function by solving
* dX(t)
* ---- = 0 equation
* dt
*/
eqn[2] = -coords[0] + 3*coords[2] - 3*coords[4] + coords[6];
eqn[1] = 2*(coords[0] - 2*coords[2] + coords[4]);
eqn[0] = -coords[0] + coords[2];
int nr = QuadCurve2D.solveQuadratic(eqn, res);
/* Following code also correctly works in degenerate case of
* the quadratic equation (nr = -1) because we do not need
* splitting in this case.
*/
for (int i = 0; i < nr; i++) {
if (res[i] > 0 && res[i] < 1) {
params[cnt++] = res[i];
}
}
}
/* Simple check for monotonicity in Y before searching for the extreme
* points of the Y(t) function. We first check if the curve is
* monotonic in Y by seeing if all of the Y coordinates are strongly
* ordered.
*/
if ((coords[1] > coords[3] || coords[3] > coords[5] ||
coords[5] > coords[7]) &&
(coords[1] < coords[3] || coords[3] < coords[5] ||
coords[5] < coords[7]))
{
/* Searching for extreme points of the Y(t) function by solving
* dY(t)
* ----- = 0 equation
* dt
*/
eqn[2] = -coords[1] + 3*coords[3] - 3*coords[5] + coords[7];
eqn[1] = 2*(coords[1] - 2*coords[3] + coords[5]);
eqn[0] = -coords[1] + coords[3];
int nr = QuadCurve2D.solveQuadratic(eqn, res);
/* Following code also correctly works in degenerate case of
* the quadratic equation (nr = -1) because we do not need
* splitting in this case.
*/
for (int i = 0; i < nr; i++) {
if (res[i] > 0 && res[i] < 1) {
params[cnt++] = res[i];
}
}
}
if (cnt > 0) {
/* Sorting parameter values corresponding to the extreme points
* of the curve
*/
Arrays.sort(params, 0, cnt);
/* Processing obtained monotonic parts */
ProcessFirstMonotonicPartOfCubic(coords, bbox,
(float)params[0]);
for (int i = 1; i < cnt; i++) {
double param = params[i] - params[i-1];
if (param > 0) {
ProcessFirstMonotonicPartOfCubic(coords, bbox,
/* Scale parameter to match with rest of the curve */
(float)(param/(1.0 - params[i - 1])));
}
}
}
ProcessMonotonicCubic(coords, bbox);
}
private Rectangle2D.Double getCurveBounds(CubicCurve2D curve) {
double minX = Double.MAX_VALUE, minY = Double.MAX_VALUE;
double maxX = Double.MIN_VALUE, maxY = Double.MIN_VALUE;
double [] bbox = new double[] {Double.MAX_VALUE, Double.MAX_VALUE, Double.MIN_VALUE, Double.MIN_VALUE};
ProcessCubic(new double[] {curve.getP1().getX(), curve.getP1().getY(),
curve.getCtrlP1().getX(), curve.getCtrlP1().getY(), curve.getCtrlP2().getX(),
curve.getCtrlP2().getY(), curve.getP2().getX(), curve.getP2().getY()}, bbox);
return new Rectangle2D.Double(bbox[0], bbox[1], bbox[2] - bbox[0], bbox[3] - bbox[1]);
}
"How does your use of the term "bounds" differ from the result of getBounds()?"
Get bounds 2D grab the control points, i want an rectangle that doesn't wrap the control points.
well testing a little i found another method in the same site that can be changed to use QuadCurve2D.
Here is the code:
private Rectangle2D.Double getCurveBounds(QuadCurve2D.Double curve) {
double flatness = 0.01;
PathIterator pit = curve.getPathIterator(null, flatness);
double[] coords = new double[2];
double minX = Double.MAX_VALUE, minY = Double.MAX_VALUE;
double maxX = Double.MIN_VALUE, maxY = Double.MIN_VALUE;
while(!pit.isDone()) {
int type = pit.currentSegment(coords);
switch(type) {
case PathIterator.SEG_MOVETO:
// fall through
case PathIterator.SEG_LINETO:
if(coords[0] < minX) minX = coords[0];
if(coords[0] > maxX) maxX = coords[0];
if(coords[1] < minY) minY = coords[1];
if(coords[1] > maxY) maxY = coords[1];
break;
}
pit.next();
}
return new Rectangle2D.Double(minX, minY, maxX-minX, maxY-minY);
}
hope it helps someone. :D