I'm looking for the easiest/fastest (computationally) way to determine whether a shape, more specifically a GeneralPath object, contains any given line segment (of type Line2D.Double).
GeneralPath has methods to determine whether a point or a rectangle is contained, but not a line (that I can find). The line can be at a slant, so I can't just model a really thin rectangle. One point in the line will definitely be inside the shape, but I need to check the rest of the line segment. So potentially, I could also check to see if the line intersects any of the boundary edges, but I'm not sure how that would look just given the shape and the line.
Does your GeneralPath contain straight line segments or quadratic or bezier segments? This matters a lot. The algorithm for the straight line is the most straightforward:
Iterate over all points in the path. If two consecutive points are on opposite sides of the line, you have a potential crossing. Then you need to check if the line segment end point is inside or outside the shape relative to the potential crossing, which you get by solving for the intersection of two points (the line and the line formed by the two consecutive points) and seeing if the result is contained in your line segment.
Unfortunately, the curved paths can have two consecutive points with a parenthesis shape between them ")", which your line can pass through while still keeping the iterable points on the same side. If you can get the format with two end points and a single (double) control point(s) that form a bounding triangle (quadrilateral), you can get easy simple solutions (since the curve is guaranteed to fit inside the triangle/quad formed by the three/four points, as long as the line doesn't intersect the triangle/quad, you are good). Unfortunately, this has an ugly part as well--if the line does intersect the triangle/quad, you aren't guaranteed anything and have to check closer. As a double unfortunate, I don't know a technique other than normalizing the coordinate system and solving for the zeroes. And that's something I'd look up in a book that I can't seem to find (or wait until another nice SO poster comes along).
... actually, since the curvature properties of the shapes are invariant under rotation, for the closer inspection part you can just rotate the curve points (whether 3 or 4) to be axis aligned. Then do your skinny rectangle trick. That's probably not the cleanest, but it's the most obvious trick.
Come to think of it, why not do the rotation of all the points in the first place? The whole intersection problem is rotation invariant. That would save a lot of code. Just axis-align the line, apply the transformation to the shape, and do your cheeky rectangle trick.
Unless I am missing something, why can't you check if the the path contains x1,y1 and x2,y2 and AND the two as follows:
generalPath.contains(line.getX1(),line.getY1()) &&
generalPath.contains(line.getX2(),line.getY2())
Related
I am working on a C++ problem where I'm trying to make a utility function that takes as input two line segments starting points in 3d space [(x,y,z) and radius r]. If the segments can be oriented such that they end at the same point, the function should return true and print out that point. If there are multiple orientations that would produce a common endpoint, the function should choose the one that is furthest in the direction indicated by hint_direction.
The function receives these values:
bool func(
point3d position_0, // origin of first line segment.
float length_0, // length of first line segment.
point3d position_1, // origin of second line segment.
float length_1, // length of second line segment.
vector3d hint_direction, // in the event there are multiple solutions, return the one furthest in this direction.
point3d *out_common_end_position) // if result is true, point where both line segments can be oriented to end. otherwise uninitialized.
I have been following some guides online which lay out how to do this such as this: https://gamedev.stackexchange.com/questions/75756/sphere-sphere-intersection-and-circle-sphere-intersection.
I was able to successfully get all the intersecting points, but I cannot figure out how to get a point that is furthest in the hint direction.
I thought I might be able to use the intersection point between circle and hint_direction and get a angle of that point, but I cannot figure out how to do so.
As Spektre correctly pointed out I missed the 3D portion of your question, so the 4 options are the following:
no intersection (or one sphere completely lies within the other)
a single point (spheres touch from inside or outside)
a normal intersection forming a circle
both spheres overlap completely, i.e. they have the same origin and the same radius
Since the normal intersection would form a circle you'd want to project the direction hint onto that circle and calculate the intersection between the circle and the projected vector to get the farthest intersection point.
So I have a list of points here.
private List<Point> points;
and the points class just has x,y,z values but only x,y are used in this case. So I store all the polygon points in there
and then I have this method here.
public Point getIntersection(Crossable aLine) {
}
And aLine is just two points so it has 4 values total for x1,x2,y1,y2 etc.
I want to get the intersection of the Line and the polygon, I have no understanding of how to get the intersection since there are a lot of variables involved and special cases. Any ideas?
Consider every two adjacent points of the polygon as a line and check to see if it intersects with your line. You need a loop to go through them all.
In Java SE 7, I'm trying to solve a problem where I have a series of Rectangles. Through some user interaction, I get a Point. What I need to do is find the (first) Rectangle which contains the Point (if any).
Currently, I'm doing this via the very naieve solution of just storing the Rectangles in an ArrayList, and searching for the containing Rectangle by iterating over the list and using contains(). The problem is that, because this needs to be interactive for the user, this technique starts to be too slow for even a relatively small number of Rectangles (say, 200).
My current code looks something like this:
// Given rects is an ArrayList<Rectangle>, and p is a Point:
for(Rectangle r : rects)
{
if(r.contains(p))
{
return r;
}
}
return null;
Is there a more clever way to solve this problem (namely, in O(log n) instead of O(n), and/or with fewer calls to contains() by eliminating obviously bad candidates early)?
Yes, there is. Build 2 interval trees which will tell you if there is a rectangle between x1 to x2 and between y1 and y2. Then, when you have the co-ordinates of the point, perform O(log n) searches in both the trees.
That'll tell you if there are possibly rectangles around the point of interest. You still need to check if there is a common rectangle given by the two trees.
I have encountered a slight problem.
Is there a way to match routes in Google Maps so that as long as the 2 routes moves along the same path, they will be matched.
For example, Andrew is going from Point A to Point B, and James is going from Point A1 to Point B1.
Although their destinations are different, but because the route from Point A to Point B passes through Point A1 and B1, Google Maps matches these 2 routes together.
Can this be done? If so, how?
i am not 100 percent sure about but think about this,
Google keeps driving or walking directions(polylines) as encoded strings. there are some js codes to decode these and you will see this string has many lines start and end point according to a pattern to save string length.
like this
"}wjiGtdpcNrAlBJZ"
they will be an exact start coordinate and coordinate differences of other points of a direction.
like these coordinates;
-0.00001, 43.64175
-79.38652, 43.64133
-79.38707000000001, 43.641270000000006
-79.38721000000001, 43.641270000000006
so if you encode two different direction and turn these points to exact coordinates you can compare them by checking start and end coordinates are same. because "-0.00001, 43.64175" part or another ones will be in the other way's polyline too if they intersects.
i think you can know if a to b and c to d intersects on same street or particular distance.
Please take a moment to understand my situation. If it is not comprehendable, please tell me in a comment.
I have an ArrayList of Waypoints. These waypoints are not in any order. A waypoint has the following properties:
{int type, float z, float y, float x, float rotation}
This applies to a 3 dimensional world, but since my pathfinding should not care about height (and thus treat the world as a 2 dimensional one), the y value is ignored. Rotation is not of importance for this question.
In this 2 dimensional world, the x represents the x axis and the z represents the y axis.
If x increases, the object in the world moves east. If x decreases, the object in the world moves west.
If z increases, the object in the world moves north. If z decreases, the object in the world moves south.
Thus, these "new" waypoints can be simplified to: waypoint = {float x, float y}.
Now, these waypoints represent the X-axis (x) and Y-axis (z) locations of an object. Moreover, there is a current location: curLocation = {float x, float y} and a target location: tarLocation = {float x, float y}.
This is what I want to get:
All combinations of waypoints (aka: paths or routes) that will lead from curLocation to tarLocation under the following strict conditions:
The distance inbetween each waypoint may not be bigger than (float) maxInbetweenDistance. This includes the initial distance from curLocation to the first waypoint and the distance from the last waypoint to tarLocation. If no such combination of waypoints is possible, null should be returned.
When multiple waypoints are found within maxInbetweenDistance from a waypoint that lead towards the target waypoint, the closest waypoint should be chosen (even better would be if an alternative waypoint that is slightly further away would result in a new path with a longer distance that is also returned).
The order of returned waypoint combinations (paths) should be from shortest route (minimum distance) to longest route (maximum distance)
Finally, please consider these points:
This is the only thing I need to do AI/pathfinding wise, which is why I do not wish to use a full blown pathfinding or AI framework. I believe one function should be able to handle the above.
If returning all possible combinations of waypoints causes too much overhead, it'd also be fine if one can specify a maximum amount of combinations (but still ordered from closest to furthest). Eg. the 5 closest paths.
How would I achieve this? Any feedback is appreciated.
I think your solution is to start with Dijkstra's Algorithm to find the shortest path first. You can consider your waypoints to be a connected graph where nodes are connected if they are close enough in the xy plane then apply Dijkstra (there are many example code listings online).
Now you have the shortest path through your graph from start to finish, which will be composed of N edges of the graph.
You would next need to create N new graphs, each just like the first, but with one segment of your shortest route un-connected. Find the shortest routes from start to finish on these modified graphs. Now you have N+1 routes which you can sort by length.
Repeat this until you have found enough paths for your needs, or there are no unranked paths left.
I haven't found a name for this technique, but it is described as a modification to Dijkstra here.
If your waypoints possess connectivity, you should take a look at Dijkstra's shortest path algorithm. The first couple of google hits even lists an implementation in Java. (I can't tell if connectivity is known from the post, but it does contain the "graph-algorithm" tag, so I'll assume so). As the name suggests, this method give you a shortest path between the two nodes.
Your constraints are challenging, as is the need for all possible combinations of paths under those constraints. Again - assuming connectivity exists - your node adjacency matrix can enforce your maxInbetweenDistance rule. Likewise, you can use this matrix in obtaining the "next best" solutions. Once the optimal path is known, you can mark that path (or elements of it) as unavailable, then re-run Dijkstra's algorithm. By repeating this process, you can obtain a set of increasingly sub-optimal paths.
As a matter of convention: in most computational geometry problems, Z is the height, and the horizontal plane is formed by the XY axes.
Well the easiest to implement would probably be creating an ArrayList of paths, which would be in turn an ArrayList of waypoints, that contains ALL possible paths, then using a recursive function to return whether each path is Valid or not given the starting and finishing point values, and the max distance, and if a path is not valid remove it from the list. The next step would be going through each of the paths that is left and ordering them from shortest total distance to shortest. This would be the brute force method of getting what you want, so the least efficient one possible. When I get home tonight I will repost if some one already hasn't with a more efficient method for doing this in java.
Edit: if the brute force method is too much, the list of waypoints will have to be sorted some how, the best way is probably to sort them initially based on distance from the starting point.