I want to generate some randoms polygon but I want it to be more or less centered in the middle of the given window coordinates.
Here is my code, it generates a random polygon but most of the time it's on the bottom of the window and I'd like to have it a bit more centered:
private static final double CORNER_MARGIN = 100.0; // max offset for a corner of the field, to randomize the polygon
private static double[] standardPolygon(double x1, double x2, double y1, double y2) {
// minX maxX minY maxY --> it's the coordinate of the window
double centerX = (x1 + x2) / 2;
double centerY = (y1 + y2) / 2;
// this is a standard polygon "centered" in the middle of the program window
return new double[]{
x1 - (x2 - x1) * RANDOM.nextDouble(), y2 + (y2 - y1) *RANDOM.nextDouble() * CORNER_MARGIN,
x2 + (x2 - x1) * RANDOM.nextDouble(), y2 + (y2 - y1) *RANDOM.nextDouble() * CORNER_MARGIN,
x2 + (x2 - x1) * RANDOM.nextDouble(), y1 - (y2 - y1) *RANDOM.nextDouble() * CORNER_MARGIN,
x1 - (x2 - x1) * RANDOM.nextDouble(), y1 - (y2 - y1) *RANDOM.nextDouble() * CORNER_MARGIN,
};
/*return new double[]{
x1 - RANDOM.nextDouble() * CORNER_MARGIN, y2 + RANDOM.nextDouble() * CORNER_MARGIN, // up left
x2 + RANDOM.nextDouble() * CORNER_MARGIN, y2 + RANDOM.nextDouble() * CORNER_MARGIN, // up right
x2 + RANDOM.nextDouble() * CORNER_MARGIN, y1 - RANDOM.nextDouble() * CORNER_MARGIN, // down right
x1 - RANDOM.nextDouble() * CORNER_MARGIN, y1 - RANDOM.nextDouble() * CORNER_MARGIN, // down left
};*/
}
The code in comment is working but now I tried to center it but I only get some rectangles/squares. How can I manage to keep random polygon forms but a bit more centered ?
[EDIT]
Here is how I draw the area of the polygon :
private void drawZone(Group group, IGameParameters gameParameters) {
Polygon polygon = new Polygon();
double[] points = gameParameters.dronePadDeliveryZonePolygon();
List<Double> pointsList = new ArrayList<>();
for (double point : points) pointsList.add(point);
polygon.getPoints().addAll(pointsList);
polygon.setFill(Color.ANTIQUEWHITE);
group.getChildren().add(polygon);
}```
You calculated the center but don't use it anywhere. Just so I understand correctly, this is a 4-sided polygon only and the corners randomly positioned at most 100 from the corner of the window?
I'm not 100% sure on how you want the polygon to be shaped but give this a try. Logically it works in my head, but I don't have a way to test the code right now.
private static final double CORNER_MARGIN = 100.0;
private static double[] standardPolygon(double x1, double x2, double y1, double y2) {
double centerX = (x1 + x2) / 2;
double centerY = (y1 + y2) / 2;
// Get the corner offsets
ox1 = x1 + CORNER_MARGIN * RANDOM.nextDouble(); // top left
oy1 = y1 + CORNER_MARGIN * RANDOM.nextDouble();
ox2 = x2 - CORNER_MARGIN * RANDOM.nextDouble(); // top right
oy2 = y1 + CORNER_MARGIN * RANDOM.nextDouble();
ox3 = x1 + CORNER_MARGIN * RANDOM.nextDouble(); // bottom left
oy3 = y2 - CORNER_MARGIN * RANDOM.nextDouble();
ox4 = x2 - CORNER_MARGIN * RANDOM.nextDouble(); // bottom right
oy4 = y2 - CORNER_MARGIN * RANDOM.nextDouble();
// Calculate the center of the polygon
double cx = (ox2 - ox1) / 2;
double cy = (oy2 - oy1) / 2;
// difference between window's center and polygon
double offsetX = centerX - cx;
double offsetY = centerY - cy;
// offset the calculated points so the polygon's center matches the window
ox1 += offsetX;
oy1 += offsetY;
ox2 += offsetX;
oy2 += offsetY;
ox3 += offsetX;
oy3 += offsetY;
ox4 += offsetX;
oy4 += offsetY;
// this is a standard polygon "centered" in the middle of the program window
return new double[]{
ox1, oy1,
ox2, oy2,
ox3, oy3,
ox4, oy4
};
}
Related
I have modified some code in the Intersector class in libgdx to find the intersection between a line and a polygon. However, I am unsure how to calculate the normal of the point of collision. Below is some code that I have.
public static Vector2 intersectSegmentPolygon (Vector2 p1, Vector2 p2, Polygon polygon) {
float[] vertices = polygon.getTransformedVertices();
float x1 = p1.x, y1 = p1.y, x2 = p2.x, y2 = p2.y;
int n = vertices.length;
float x3 = vertices[n - 2], y3 = vertices[n - 1];
for (int i = 0; i < n; i += 2) {
float x4 = vertices[i], y4 = vertices[i + 1];
float d = (y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1);
if (d != 0) {
float yd = y1 - y3;
float xd = x1 - x3;
float ua = ((x4 - x3) * yd - (y4 - y3) * xd) / d;
if (ua >= 0 && ua <= 1) {
float ub = ((x2 - x1) * yd - (y2 - y1) * xd) / d;
if (ub >= 0 && ub <= 1) {
return new Vector2(x1 + (x2 - x1) * ua, y1 + (y2 - y1) * ua);
}
}
}
x3 = x4;
y3 = y4;
}
return null;
}
I am trying to draw an arc on Jpanel in swing from user input having the center of arc, starting point and end point of arc.
here is my current
int x1 = 300; //start point
int y1 = 300;
int x2 = 350; //center point of arc
int y2 = 350;
int x3 = 300; //end point of arc
int y3 = 400;
int h1 = y1 - y2; //calculate with and height from start-center and center-end
int d1 = x2 - x1;
int h2 = y2 - y3;
int d2 = x3 - x2;
int startangle = (int)(Math.atan(h1 / d1) * 180 / Math.PI);
if (x2 > x1 && y2 > y1) {
startangle = 180 - startangle;
} else if (x2 < x1) {
//change sign
} else if (y1 < y2) {
//change sign
}
System.out.println("x1,y1\n" + x1 + "\n" + y1 + "\n" + d2 / h2 + "\n" + Math.atan(d2 / h2) * 180 / Math.PI);
int endangle = (int)(Math.atan2(x3, y3) * 180 / Math.PI);
System.out.println("args: " + "\n" + x2 + "\n" + y2 + "\n" + startangle + "\n" + endangle + "\n");
g2.drawArc(x1, y1, d1, h1, startangle, startangle);
g2.drawArc(x2, y2, d2, h2, 0, endangle);
However i am not getting the arc on screen, literally nothing related to it (other shapes work but not this one). No errors or exceptions were thrown.
Edit: Thanks to #MadProgrammer's comment, i am getting a shape but not what i expect.
What i get:
What i expect from the same set of coordinates:
Edit 2: managed to make it work by using a bezier curve instead of an arc
It worked by using a bezier curve and drawing quadcurve in two phases (start-middle,middle-end) using the calculated control points instead of the drawArc method.
I think the bounding rectangle of drawarc is the height and width of the ellipse that your arc is part of.
I have a point (x1, y1, z1) in a 3D dimensional space
And a line (x2,y2,z2)(x3,y3,z3)
I want to find the shortest distance between the line and the dot.
I already found mathematical equations for this, but I am not a mathematician, and i failed to understand the different variables in the equation and apply them to Java/Android.
I have searched and viewed the similar questions here and almost everywhere, but there were no example in any programming language.
After spending the night learning some spacial math, I could finally convert the equations to Java code:
public static float betweenPointAndLine(float[] point, float[] lineStart, float[] lineEnd){
float[] PointThing = new float[3];
float[] TotalThing = new float[3];
PointThing[0] = lineStart[0] - point[0];
PointThing[1] = lineStart[1] - point[1];
PointThing[2] = lineStart[2] - point[2];
TotalThing[0] = (PointThing[1]*lineEnd[2] - PointThing[2]*lineEnd[1]);
TotalThing[1] = -(PointThing[0]*lineEnd[2] - PointThing[2]*lineEnd[0]);
TotalThing[2] = (PointThing[0]*lineEnd[1] - PointThing[1]*lineEnd[0]);
float distance = (float) (Math.sqrt(TotalThing[0]*TotalThing[0] + TotalThing[1]*TotalThing[1] + TotalThing[2]*TotalThing[2]) /
Math.sqrt(lineEnd[0] * lineEnd[0] + lineEnd[1] * lineEnd[1] + lineEnd[2] * lineEnd[2] ));
return distance;
}
public static double distance(double x1, double y1, double z1,
double x2, double y2, double z2,
double x3, double y3, double z3) {
double b = Math.sqrt(Math.pow((x2 - x3), 2)
+ Math.pow((y2 - y3), 2)
+ Math.pow((z2 - z3), 2));
double S = Math.sqrt(Math.pow((y2 - y1) * (z3 - z1) - (z2 - z1) * (y3 - y1), 2) +
Math.pow((z2 - z1) * (x3 - x1) - (x2 - x1) * (z3 - z1), 2) +
Math.pow((x2 - x1) * (y3 - y1) - (y2 - y1) * (x3 - x1), 2)) / 2;
return 2 * S / b;
}
I am writing a game. I need to know how to rotate point a around point b by a given number of degrees. I am writing this in java and it is going to be part of my class, Point.
double x1 = point.x - center.x;
double y1 = point.y - center.y;
double x2 = x1 * Math.cos(angle) - y1 * Math.sin(angle));
double y2 = x1 * Math.sin(angle) + y1 * Math.cos(angle));
point.x = x2 + center.x;
point.y = y2 + center.y;
This approach uses rotation matrices. "point" is your point a, "center" is your point b.
Here is the circle class:
public class Circle {
private double radius;
private double x;
private double y;
}
How can I tell if two objects from this class (circles) are colliding?
P.S. Can you use the method that avoids taking a square root?
double xDif = x1 - x2;
double yDif = y1 - y2;
double distanceSquared = xDif * xDif + yDif * yDif;
boolean collision = distanceSquared < (radius1 + radius2) * (radius1 + radius2);
dx = x2 - x1;
dy = y2 - y1;
radiusSum = radius1 + radius2;
return dx * dx + dy * dy <= radiusSum * radiusSum; // true if collision
The link from #instanceofTom in the comments is better... with pictures.
The circles will touch when the distance between their centres is equal to the sum of their radii, or collide when the distance is less.
Since we are using absolute distance, it is Ok to compare the square of the distance between centres with the square of the sum of the radii.
Here's the updated Java solution:
public boolean hasCollision(Circle circle){
double xDiff = x - circle.getX();
double yDiff = y - circle.getY;
double distance = Math.sqrt((Math.pow(xDiff, 2) + Math.pow(yDiff, 2)));
return distance < (radius + circle.getRadius());
}