How do I find all the Points in a Path in Android? - java

Awhile back I asked a question to see if I was able to find a pair of specific points in a path; however, this time I want to know if there is a way to know all points in a path? (I couldn't find a method that did so, which is unfortunate because Java provides a way to do this, just not Android?)
The reason I ask this is because I have multiple geometric graphs and I want to compare the points to see where they intersect.
I appreciate any helpful responses

You can use PathMeasure to get coordinates of arbitrary point on the path.For example this simple snippet(that I saw here) returns coordinates of the point at the half of the path:
PathMeasure pm = new PathMeasure(myPath, false);
//coordinates will be here
float aCoordinates[] = {0f, 0f};
//get point from the middle
pm.getPosTan(pm.getLength() * 0.5f, aCoordinates, null);
Or this snippet returns an array of FloaPoints.That array involves coordinates of 20 points on the path:
private FloatPoint[] getPoints() {
FloatPoint[] pointArray = new FloatPoint[20];
PathMeasure pm = new PathMeasure(path0, false);
float length = pm.getLength();
float distance = 0f;
float speed = length / 20;
int counter = 0;
float[] aCoordinates = new float[2];
while ((distance < length) && (counter < 20)) {
// get point from the path
pm.getPosTan(distance, aCoordinates, null);
pointArray[counter] = new FloatPoint(aCoordinates[0],
aCoordinates[1]);
counter++;
distance = distance + speed;
}
return pointArray;
}
In above snippet,FloatPoint is a class that encapsulate coordinates of a point:
class FloatPoint {
float x, y;
public FloatPoint(float x, float y) {
this.x = x;
this.y = y;
}
public float getX() {
return x;
}
public float getY() {
return y;
}
}
References:
stackoverflow
Animating an image using Path and PathMeasure – Android

If you have created a Path that means that in some point of your code, you know the exact (Geo)point. Why don't you put this point(s) on a ArrayList or something similar?
So for example before doing:
path.lineTo(point.x, point.y);
you can do:
yourList.add(point);
path.lineTo(point.x, point.y);
And later you can get all your points from the ArrayList.
Note you that you can take advantage of the Enhanced For Loop Syntax of ArrayList that execute up to three times faster.

Related

Iterate through 3 dimensional radius in world from center position

I am trying to get all positions in a radius from a 3 dimensional world(In this case the game Minecraft) this is the current code I use.
public static List<BlockPos> getBlocksInRadius(double radius) {
List<BlockPos> circleblocks = new ArrayList<>();
int centralx = mc.player.posX;
int centraly = mc.player.posY;
int centralz = mc.player.posZ;
for (int x = centralx - radius; x <= centralx + radius; x++) {
for (int z = centralz - radius; z <= centralz + radius; z++) {
for (int y = centraly - radius; y < centraly + radius; y++) {
double dist = mc.player.getDistance(x, y, z);
if (dist < radius) {
BlockPos l = new BlockPos(x, y, z);
circleblocks.add(l);
}
}
}
}
return circleblocks;
}
This method goes from the x coord farthest away and keeps coming closer to the player. I want it to iterate it by starting at central x,y,z and then increase distance from the player. This is to make it easier to find block x closest to player. Any help would be apreciated!
Depending on how large of a radius you have, you might try the static method BlockPos::getAllInBox. There doesn't seem to be any official documentation on it, but it looks like it takes two BlockPos parameters and returns an Iterable<BlockPos>. It finds all the blocks in a cube in between the two parameters, so you probably want to center it on the player.
Here's what I would do. This code hasn't been tested, and you might need to adapt it for all of the 1.14 and 1.13 changes, but the theory should be the same, with just name changes.
BlockPos playerPos = player.getPosition(); // Or some other method of getting a BlockPos of the player
positiveRadiusPosition = playerPos.add(radius, radius, radius); // Gets one corner of the cube in the positive X, Y, and Z direction
negativeRadiusPosition = playerPos.add(-1 * radius, -1 * radius, -1 * radius); // Gets the opposite corner
Iterable<BlockPos> cubeResult = BlockPos.getAllInBox(positiveRadiusPosition, negativeRadiusPosition);
for (BlockPos pos: cubeResult) {
// cubeResult will contain blocks that are outside of the sphere with the
// radius you want. If that's okay, cool! If that's not okay, you should
// check each pos' distance from the player. If it's outside of the radius,
// remove it from the list.
}
Now you need to figure out which block is closest. The method I would use would be to use a Comparator to sort the Iterable, which is copied into a List. For reference:
public static Iterator sortedIterator(Iterator it, Comparator comparator) {
List list = new ArrayList();
while (it.hasNext()) {
list.add(it.next());
}
Collections.sort(list, comparator);
return list.iterator();
}
In the Comparator, you should check the distance from the player to each block.
public static double getDistanceToEntity(Entity entity, BlockPos pos) {
double deltaX = entity.posX - pos.getX();
double deltaY = entity.posY - pos.getY();
double deltaZ = entity.posZ - pos.getZ();
return Math.sqrt((deltaX * deltaX) + (deltaY * deltaY) + (deltaZ * deltaZ));
}
Of course, this method doesn't actually start at the player and work outwards. It's just a cleaner and expanded version of your original method that should do what you want. If you are working with a very large radius, it's probably not a good idea to use this, as you'll have to work with the entire cube.

Java - How to check if a lat/lng coords are inside a polygon

I want to check if a given point on a map (with its latitude and longitude) is inside a certain polygon. I have the vertex coords (in lat/long) of the polygon.
I thought of creating a Polygon and check if point is inside, but it gives me that the point is always outside... Maybe the polygon does not work with georeferential coords?
Double[] xCoords = {40.842226, 40.829498, 40.833394, 40.84768, 40.858716}
Double[] yCoords = {14.211753, 14.229262, 14.26617, 14.278701, 14.27715}
Double[] myPoint = {40.86141, 14.279932};
Path2D myPolygon = new Path2D.Double();
myPolygon.moveTo(xCoords[0], yCoords[0]); //first point
for(int i = 1; i < xCoords.length; i ++) {
myPolygon.lineTo(xCoords[i], yCoords[i]); //draw lines
}
myPolygon.closePath(); //draw last line
if(myPolygon.contains(myPoint{0}, myPoint{1})) {
//it's inside;
}
This is how it looks like in google maps
It always return false... but the point it's inside the polygon...
That point can't possibly be contained in that polygon, no matter what shape the polygon has.
Your right-most coordinate is at 40.858716 while the point has an x value of 40.86141, this means that the point lies on the right of your polygon. Same for y, max y coordinate in the polygon is 14.278701 while the point is at 14.279932. This means that the point is outside.
Also, you're inverting the coordinates, the coordinates of our beloved city are 40.8518° N, 14.2681° E, this means that 40 is the y and 14 the x.
Path2D will do just fine. My observation just tells you that the point is not in the polygon but checking the extremes is not a general solution for verifying that a point is inside a polygon.
public class CoordinatesDTO {
private Long id;
private double latitude;
private double longnitude;
}
public static boolean isLocationInsideTheFencing(CoordinatesDTO location, List<CoordinatesDTO> fencingCoordinates) { //this is important method for Checking the point exist inside the fence or not.
boolean blnIsinside = false;
List<CoordinatesDTO> lstCoordinatesDTO = fencingCoordinates;
Path2D myPolygon = new Path2D.Double();
myPolygon.moveTo(lstCoordinatesDTO.get(0).getLatitude(), lstCoordinatesDTO.get(0).getLongnitude()); // first
// point
for (int i = 1; i < lstCoordinatesDTO.size(); i++) {
myPolygon.lineTo(lstCoordinatesDTO.get(i).getLatitude(), lstCoordinatesDTO.get(i).getLongnitude()); // draw
// lines
}
myPolygon.closePath(); // draw last line
// myPolygon.contains(p);
Point2D P2D2 = new Point2D.Double();
P2D2.setLocation(location.getLatitude(), location.getLongnitude());
if (myPolygon.contains(P2D2)) {
blnIsinside = true;
} else {
blnIsinside = false;
}
return blnIsinside;
}

How to get the nearest Vector to a given target from a list

So imagine I've created a Vector class with two variables x and y in Java:
public class Vector {
private int x;
private int y;
public Vector(int x, int y) {
this.x = x;
this.y = y;
}
public int getX() {
return this.x;
}
public int getY(){
return this.y;
}
}
Then I've craeted an ArrayList of vectors:
private List<Vector> vecs = new ArrayList<Vector>();
I've created in that list:
8,9
10,5
83473834,938849584985
etc ...
Now I want to get the closest vector to another vector.
Example:
private List<Vector> vecs = new ArrayList<Vector>();
private Vector vec = new Vector(1,1);
for(Vector vector:vecs) {
//What do i put here??
}
So what do i put in the for loop to make it select the nearest vector from the vector list?
I would start by adding a method to the Vector class, distanceTo, that calculates the distance from this vector to another one:
public double distanceTo(Vector vec) {
double dx = x - vec.x; //calculate the diffrence in x-coordinate
double dy = y - vec.y; //calculate the diffrence in y-coordinate
return Math.sqrt(dx*dx + dy*dy); //use the distance formula to find the difference
}
And then you can write the following method that returns the closest vector in a list to a given vector:
public static Vector closest(Vector target, List<Vector> list) {
Vector closest = list.get(0); //this variable will kep track of the closest vector we have found yet. We simply start with the first one
for(int i = 1; i < list.size(); i++) { //loop over the list, skipping the first entry
Vector curr = list.get(i); //get the current vector from the list
if (target.distanceTo(curr) < target.distanceTo(closest)) //if the current vector is closer to target than the closest one yet
closest = curr; //keep the current vector as the new closest one
}
return closest; //return the resulting vector
}
This method can then be used like this:
Vector target = new Vector(1, 2);
List<Vector> vecs = new ArrayList<Vector>();
vecs.add(new Vector(-2, 6));
vecs.add(new Vector(1, 3));
vecs.add(new Vector(4, 0));
vecs.add(new Vector(8, -1));
Vector closest = findClosest(target, vecs);
As you can see I tried to explain the code as best as I could, but feel free to ask any further questions!
EDIT another method is:
public double distanceTo(Vector vec1,Vector vec2) {
double dx = vec2.x - vec1.x; //calculate the diffrence in x-coordinate
double dy = vec.y - vec1.y; //calculate the diffrence in y-coordinate
return Math.sqrt(dx*dx + dy*dy); //use the distance formula to find the difference
}
This is if you can't put it into the vector class
This is a basic programming question. It is not related to OpenGL. A simple linear search could look as follows:
private List<Vector> vecs = new ArrayList<Vector>();
private Vector vec = new Vector(1,1);
Vector minDistanceVector = null;
int minDistanceSquared = Integer.MAX_VALUE;
for(Vector vector : vecs) {
//Calculate the distance
//This could be a member function of Vector
int dx = vector.getX() - vec.getX();
int dy = vector.getY() - vec.getY();
int squaredDistance = dx * dx + dy * dy;
if(squaredDistance < minDistanceSquared) {
minDistanceSquared = squaredDistance;
minDistanceVector = vector;
}
}
After that, you will have the closest vector in minDistanceVector. I chose Euclidean distance because this is probably what you want. But you could use any other distance, of course.
If you want something more efficient, you may want to build some acceleration data structure over the points and query that one (e.g. grid, kd-tree, quadtree...).

Rotating Polygon Objects

Rotating Asteroids ( Polygons )
I am trying to rotate asteroids(polygons) so that they look nice. I am doing this through multiple mathematical equations. To start I give the individual asteroid a rotation velocity:
rotVel = ((Math.random()-0.5)*Math.PI/16);
Then I create the polygon shape,
this.shape = new Polygon();
Followed by generating the points,
for (j = 0; j < s; j++) {
theta = 2 * Math.PI / s * j;
r = MIN_ROCK_SIZE + (int) (Math.random() * (MAX_ROCK_SIZE - MIN_ROCK_SIZE));
x = (int) -Math.round(r * Math.sin(theta)) + asteroidData[0];
y = (int) Math.round(r * Math.cos(theta)) + asteroidData[1];
shape.addPoint(x, y);
}
Finally, in a loop a method is being called in which it attempts to move the polygon and its points down as well as rotating them. (I'm just pasting the rotating part as the other one is working)
for (int i = 0; i < shape.npoints; i++) {
// Subtract asteroid's x and y position
double x = shape.xpoints[i] - asteroidData[0];
double y = shape.ypoints[i] - asteroidData[1];
double temp_x = ((x * Math.cos(rotVel)) - (y * Math.sin(rotVel)));
double temp_y = ((x * Math.sin(rotVel)) + (y * Math.cos(rotVel)));
shape.xpoints[i] = (int) Math.round(temp_x + asteroidData[0]);
shape.ypoints[i] = (int) Math.round(temp_y + asteroidData[1]);
}
now, the problem is that when it prints to the screen the asteroids appear to 'warp' or rather the x and y positions on some of the polygon points 'float' off course.
I've noticed that when I make 'rotVel' be a whole number the problem is solved however the asteroid will rotate at mach speeds. So I've concluded that the problem has to be in the rounding but no matter what I do I can't seem to find a way to get it to work as the Polygon object requires an array of ints.
Does anyone know how to fix this?
Currently your asteroids rotate around (0 , 0) as far as i can see. Correct would be to rotate them around the center of the shape, which would be (n , m), where n is the average of all x-coordinates of the shape, and m is the average of all y-coordinates of the shape.
Your problem is definitely caused by rounding to int! The first improvement is to make all shape coordinates to be of type double. This will solve most of your unwanted 'effects'.
But even with double you might experience nasty rounding errors in case you do a lot of very small updates of the coordinates. The solution is simple: Just avoid iterative updates of the asteroid points. Every time, you update the coordinates based on the previous coordinates, the rounding error will get worse.
Instead, add a field for the rotation angle to the shape and increment it instead of the points themselves. Not until drawing the shape, you compute the final positions by applying the rotation to the points. Note that this will never change the points themselves.
You can extend this concept to other transformations (e.g. translation) too. What you get is some kind of local coordinate system for every shape/object. The points of the shape are defined in the local coordinate system. By moving and rotating this system, you can reposition the entire object anywhere in space.
public class Shape {
// rotation and position of the local coordinate system
private double rot, x, y;
// points of the shape in local coordinate system
private double[] xp, yp;
private int npoints;
// points of the shape in world coordinates
private int[][] wxp, wyp;
private boolean valid;
public void setRotation(double r) { this.rot = r; valid = false; }
public void setPosition(double x, double y) { this.x = x; this.y = y; valid = false; }
public void addPoint(double x, double y) {
// TODO: add point to xp, yp
valid = false;
}
public void draw(...) {
if (!valid) {
computeWorldCoordinates(wxp, wyp);
valid = true;
}
// TODO: draw shape at world coordaintes wxp and wyp
}
protected void computeWorldCoordinates(int[] xcoord, int[] ycoord) {
for (int i = 0; i < npoints; i++) {
double temp_x = xp[i] * Math.cos(rot) - yp[i] * Math.sin(rot);
double temp_y = xp[i] * Math.sin(rot) + yp[i] * Math.cos(rot);
xcoord[i] = (int) Math.round(x + temp_x);
ycoord[i] = (int) Math.round(y + temp_y);
}
}
}

Java - how to get maximum result of a calculation

We are working on creating object and driver classes. I have an object class that does various things to a moving exploratory robot.
What I need to do now is create a method that returns the largest distance that the robot moved in one single move command. I also need to return the time that it took to move that distance.
Here's the relevant code for that so far:
{
private int xcoord, ycoord; //Cartesian coordinates of the robot
private int identification; //Identification number of the robot
private double rate; //Rate at which the robot explores
private double traveled; //Distance the robot has travelled
private double timeSpent; //Time spent travelling
private double longestLeg; //Longest leg of the journey
private double longestLegTime; //Time on the longest leg
//Sets up a robot with the given ID number and beginning x and y coordinates
public Robot (int id, int x, int y)
{
identification = id;
xcoord = x;
ycoord = y;
traveled = 0;
rate = 5.0;
}
//Has the robot travel to the set coordinates
public double setDestination (int x, int y)
{
double distance = Math.pow(x - xcoord, 2) + Math.pow(y - ycoord, 2);
traveled += Math.sqrt(distance);
xcoord = x;
ycoord = y;
timeSpent += Math.sqrt(distance)/rate;
return traveled;
}
//Gets the time spent travelling
public double getTimeSpent()
{
return timeSpent;
}
//Sets the rate at which the robot travels
public void setRate(double setrate)
{
rate = setrate;
}
//Returns longest leg of the robot's travels
public int getLongestLeg()
{
return longestLeg;
}
//Returns time of longest leg
public double getLongestLegTime()
{
return longestLegTime;
}
I'm not allowed to use if statements or loops yet, so it will have to be using Math.max I'm guessing. I tried using it, but it gave me an error saying that it required an int but I supplied a double.
Any suggestions would be awesome. Thanks!
If you are able, I have one final problem with the code as well. I need to create a method that would get the distance between two Robot objects. I'm not even sure how to start this one since we haven't really worked with it yet. A suggestion on how to even start this would be great. Thanks again.
To avoid casting, this should work:
longestLeg = Math.max(distance, longestLeg);
If you are getting an error about requiring an int, it probably means one of your parameters was an int when it shouldn't be. Can't be sure without seeing exactly how you were calling it, but I suspect it may have been to do with the fact getLongestLeg() is returning longestLeg as an int when it's actually a double. I would suggest changing that method to:
//Returns longest leg of the robot's travels
public double getLongestLeg()
{
return longestLeg;
}
In terms of your second question, to calculate the distance between another robot, the calcDist() method should probably look something like this:
public double calcDist(Robot other)
{
return Math.sqrt(Math.pow(this.getX() - other.getX(), 2) + Math.pow(this.getY() - other.getY(), 2));
}
If i got your question right you just wanted to use the Math.max() with Integers.
Try
(int) Math.max()

Categories