get coordinates of points that form circumference - java

I have an ellipse:
Ellipse2D e2D = new Ellipse2D.Float(startPoint.x, startPoint.y, x - startPoint.x, y - startPoint.y);
And what I need is to get coordinates of all points that form circumference.
ArrayList<Point> oneDraw = new ArrayList<>();
for (int i = startX; i < borderX; i++)
for (int j = startY; j < borderY; j++)
if (e2D.contains(new Point(i, j)))
oneDraw.add(new Point(i, j));
By doing so, I put all coordinates that are inside my circle to the list, but I don't need this.
Thank you for the answer and spent time.

Create an ellipse that is a little larger than the target ellipse.
Create an ellipse that is a little smaller than the target ellipse.
Subtract the 2nd ellipse from the first. This will form an elliptical ring.
Do the current 'contains' code with the elliptical ring.

Your approach would add all pixels in the box which are inside the ellipse to the list, i.e. you'd get the area of the ellipse rather than its circumference. I'd say it would be better to look for the correct formula and solve it for discrete x/y pairs.
Or yet better apply one of the algorithms for drawing ellipses that can be found on the net, e.g. this one: http://www.mathopenref.com/coordcirclealgorithm.html
Then get the pixels that have been drawn (if still needed).
Edit: if you have a look at the source code of Ellipse2D you can either get an an idea of how to implement your own algorithm or you could just use getPathIterator() with a uniform transform and then "rasterize" the path elements into your list.

Related

How can I draw the points of a route equidistant of one another?

I am writing a program that outputs the shortest route between two points on a map. The problem is that if the route is too long and it has many points that define its path it slows the program a lot and I am looking for a way to draw just some points instead of all the points in the array.
My approach goes as follows: the map has a zoom, each time the zoom changes check which points overlaps with the others. All the points that doesn't overlap go into the routeToDraw list and then it is drawn.
To check if the points overlap or not I have the following function:
//route is a list of latitude and longitude points
LinkedList<Point.Double> route = MapPanel.this.getGlassPane().getRoute();
LinkedList<Point.Double> routeToDraw = new LinkedList<Point.Double>();
int ovalSize = 8;
boolean compareMorePoints;
for(int i = 0; i < route.size(); i++) {
Point p1 = getScreenCoordinates(route.get(i).x, route.get(i).y);
compareMorePoints = true;
int j = i + 1;
while (j < route.size() && compareMorePoints == true) {
Point p2 = getScreenCoordinates(route.get(j).x, route.get(j).y);
if (Math.sqrt(Math.pow(p1.x - p2.x, 2) + Math.pow(p1.y - p2.y, 2)) > ovalSize ) {
routeToDraw.add(route.get(i));
compareMorePoints = false;
}
j++;
}
}
MapPanel.this.getGlassPane().setRouteToDraw(routeToDraw);
The problem is that this function is quite expensive and although it does reduce the amount of points to draw and I seem to obtain some speed after calculating routeToDraw I don't think it is worth the wait each time I zoom in or out.
The ideal solution would be something like Google Maps' does when routing, drawing a series of equidistant points that modify each time you zoom in or out and look quite nice.
Two suggestions...
(old trick)... Don't do unnecessary math inside of a loop. You can and should eliminate the sqrt function, which is an "expensive" math operation when doing distances. Just compare to the square of ovalSize. It is mathematically equivalent.
Is your list sorted in any way? If there were a convenient point in your program to sort your list (or a copy of it) before displaying, then you could very quickly:
Lop off the first and last part that is outside your zoom window in one of the coordinates (say X, if you sorted by X) by doing a binary search for the window boundary
Tighten up your loop to only look at neighbors within a window of concern, and do a sliding window instead of all-compared-to-all.

How to get the up vector of my object in libgdx/box2d?

I'm rotating my object(ship) to face a target with the code below.
playerBody.setTransform(playerBody.getPosition(), MathUtils.lerpAngle(playerBody.getAngle(), getDesiredAngle(),lerpProgress));
I want to to move the ship in the direction the ship is looking. I thought that retrieving the Up vector of the ship would suffice. I tried the below code but that didn't work.
Vector2 direction = playerBody.getWorldPoint(new Vector2(0,1));
playerBody.setLinearVelocity(direction.nor());
I believe that getWorldPoint() does not give you what you are looking for. It returns the vector (direction + distance) of a local point, in regard to the box2D world's origin. In this picture, this would be the blue vector: getWorldPoint(). What you want is the red vector.
The most basic way of doing would be something like this :
float angle = playerBody.getAngle();
Vector2 direction = new Vector2(MathUtils.cos(angle),MathUtils.sin(angle))
I must add that in my case, I had to add 90°, since I needed an angle of 0° to correspond to a vertical body : angle = playerBody.getAngle() + MathUtils.PI/2f

Tetris: Turning the pieces?

So I am making a tetris game and one of the problems I am running into is piece rotation. I know I can just hard code it but thats not the right way to do it. The way the system works is I have a 2d array of an object 'Tile' the 'Tile' object has x, y coords, boolean isActive, and color. The boolean isActive basically tells the computer which tiles are actually being used (Since tetris shapes are not perfect quadrilaterals).
Here is how I would make a shape in my system:
public static Tile[][] shapeJ() {
Tile[][] tile = new Tile[3][2];
for (int x = 0; x < 3; x++) {
for (int y = 0; y < 2; y++) {
tile[x][y] = new Tile(false, Color.blue);
}
}
tile[0][0].setActive(true);
tile[0][0].setX(0);
tile[0][0].setY(0);
tile[1][0].setActive(true);
tile[1][0].setX(50);
tile[1][0].setY(0);
tile[2][0].setActive(true);
tile[2][0].setX(100);
tile[2][0].setY(0);
tile[2][1].setActive(true);
tile[2][1].setX(100);
tile[2][1].setY(50);
return tile;
}
Now I need to rotate this object, I do not know how to do that without hard coding the positions. There has to be an algorithm for it. Can anyone offer some help?
A good way that I used when writing a tetris clone is to use rotational matrices:
http://en.wikipedia.org/wiki/Rotation_matrix
So the coordinates (x',y') of the point (x,y) after rotation are:
x' = x*cos(theta) - y*sin(theta);
y' = x*sin(theta) + y*cos(theta);
Where theta is the angle of rotation(+-90 degrees or +-PI/2 radians for the java functions that I know)
In this case the blocks are rotated around the origin (0, 0) so you either have to have the coordinates of the block in special "block space" that then gets transposed onto "field space" or you take away the offset of the block so that it is centered at the origin every iteration.
I hope that helps, I am happy to answer specific questions in the comments.

Trying to rotate a polygon using math

I have a school assignment where I'm supposed to (among other things) rotate a polygon. I can not use any premade rotate functions, so I have an array of points. The array is set up like this:
intArray[2][amount_of_points] where intArray[0] equals the points x coordinate, and intArray[1] holds the y coordinates.
//x=pivot point x coordinate, y = pivot point y coordinate.
public int[][] rotate(int[][]matrix,int x, int y, double degrees){
double s=Math.sin(degrees);
double c=Math.cos(degrees);
for (int i=0;i<matrix.length;i++){
//translate to origin
int px=matrix[0][i]-x;
int py=matrix[1][i]-y;
//rotate
double xnew = (px*c)-(py*s);
double ynew = (px*s)+(py*c);
//translate back
px=(int)((xnew+x)+0.5);
py=(int)((ynew+y)+0.5);
matrix[0][i]=px;
matrix[1][i]=py;
}
This is my code so far, and it is definitely not working out for me. I tried to trim the code as much as I could. Any help would mean a lot!
edit: I'm not getting any errors when I run the code, no exceptions etc. The only problem is that the polygon isn't rotating the way I intend it to.
I've made a test polygon:
polyArray = new int [2][3];
polyArray[0][0]=400;
polyArray[1][0]=200;
polyArray[0][1]=300;
polyArray[1][1]=500;
polyArray[0][2]=500;
polyArray[1][2]=500;
Which I draw in a JPanel, then I run this array through the rotation method like this:
polyArray=mm.rotate(polyArray, polyArray[0][0], polyArray[1][0], Math.PI);
Using the top point as pivotpoint. The whole polygon is then deformed.
Although still not very clear on question, I feel your problem is with the loop.
matrix.length is 2. So, the code never uses these :
polyArray[0][2]=500;
polyArray[1][2]=500;
If you change the condition as below, it should work :
for (int i=0;i<matrix[0].length;i++)

How to get an object to follow a path

I'm having some trouble getting an object to follow a path that is drawn with a touch event.
The problem is more in the smoothness of which the object follows the path.
/* the ACTION_MOVE code */
Hashtable<String, Integer> ht = new Hashtable<String, Integer>();
for (int h = 0; h < historySize; h++) {
for (int p = 0; p < pointerCount; p++) {
int newX = (int) event.getHistoricalX(p, h);
int newY = (int) event.getHistoricalY(p, h);
ht.put("x", newX);
ht.put("y", newY);
droid.path.add(ht);
}
droid.p.lineTo(x, y);
}
/* There's a game loop that calls a move() method on this droid object. In move I read the path list
and see the next coordinate to move the object to. */
I grab the coordinates as the user drags their finger across the screen using the
historic methods so I don't miss any points.
The problem is the smoothness that the object moves along this path.
If you draw your path slow then the droid will move slowly across the screen
( because more x,y points are captured? )
But if you draw the line fast then the droid moves really fast.
I need the object to move at a consistent speed across the path.
I somehow need to regulate the spacing between the points added to the hashTable or the
sample rate at which points are read in so its consistent and the object looks smooth
following the path.
I've googled this one a good bit and i'm having some trouble finding anything.
Any shove in the right direction would be appreciated.
Thanks so much!
Here I showed how to move and rotate an image along any path. Build a smooth path from your points. Then you can specify any number of points to make nice animation.

Categories

Resources