Detect click on a line - java

I would like to find a way to know if I click on a line. I have a standard 2D plan with square for example and a line between both. I would like to detect when I click on the line.
The line can be horizontal, vertical or with an angle.
I have those information on the line :
-Starting coordinate (x,y)
-Ending coordinate (x,y)
-The mouse click position (x,y)
I might be able to get the angle with tan().
I found this solution but i can't add mouse event: How to select a line
Thanks you.

Let S and E be the segment endpoints and M the mouse.
The vector that joins M to a point along SE is given by MS+t.SE, where 0<t<1.
Square this vector to get its (squared) length: d²=SE²t²+2(SE.MS)t+MS²,
and find the position of the minimum, t=-(SE.MS)/SE².
If t<=0, the shortest distance is to S, hence d²=MS².
If t>=1, the shortest distance is to E, hence d²=ME².
Else, the shortest distance is to a point on the segment, and d²=MS²-(SE.MS)²/SE².
There is no need to take the square root, because d<Tolerance is equivalent to d²<Tolerance².

Have a look at this answer:
Shortest distance between a point and a line segment
They calculate the shortest distance from a point to a segment.
Having calculated this value, you can accept or reject the mouse click event:
if ( distanceToSegment(...) < threshold && mouseClicked()) {
// insert code here
}
The threshold will depend on how precise you want the user to be.

Related

Collision between a moving circle and a stationary circle

So what I'm trying to make is a function where I input the location of a moving circle and its target location, the location of a stationary circle and both of their radiuses, and I want to return the point at which they intersected if they did and the target location if they didn't.
The starting position of both circles, their radiuses and the end position of the moving circle are all known.
In this example I want to in a single frame move circle A from point Start to point End, if A collides with B I want to return the point where they touch closest to Start. In between Start and End there is a vector that can be calculated through End-Start which I'll call V and use in my attempt at solving this.
I will to refer the point Start as S and the position of B as P, the radius of A as Ra and the radius of B as Rb as seen in this image: variables.
So this is how far I've got:
When the two circles are just about touching the distance between them should be their radiuses combined like in this image: radiuses combined.
Therefore Ra+Rb = length of P-C which becomes (Ra+Rb)² = (P.x-C.x)² + (P.y-C.y)² according to Pythagoras (I squared both sides to remove the square root)
C can be described as the point S plus the vector V scaled by some constant t, C = S + tV so for example the point half way between Start and End could be described as S + 0.5V.
So the equation would then become (Ra+Rb)² = (P.x-(S.x+tV.x))² + (P.y-(S.y+tV.y))²
I have not gotten further than that since I cant isolate t which I need to find C
Any help is greatly appreciated! Sorry if I made any mistakes, its my first time posting.
(If anyone has code in Java for this that would be amazing)
You would probably have received a better answer for your question over at math.stackexchange.com, since this really seems to be a question about the maths related to your program.
But anyhow, this problem can be solved in a few steps:
1. Projection of a point onto a line:
Let Q be a projected point on V. Is the distance P-Q larger than the sum of Ra and Rb? If so, there is no collision, else proceed:
2. Pythagoras:
You now know the distance P-Q, and as you noted yourself, the circles will intersect at a distance Ra+Rb - if they collide. So, now if we find the distance Q-C, we can find where C is, since we already know where Q is from the projection onto V.
So, what is the distance Q-C: Sqrt((B-Q)^2 - (B-C)^2)
3. Find C by translating Q by distance Q-C
Now, you just need to make sure that you translate Q in the right direction: toward S.
As for the coding part of your problem, there was never a question asked, so there's nothing to respond to...
[Edit: fixed #3 Translate->Find]

Sphere-Sphere Intersection, choosing right theta

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.

Comparing a set of coordinates (strokes?) for a percentage difference

I have 2 paths A and B.
For example:
A = {(1,1), (2,2), (3,3)}
B = {(2,2), (3,3), (5,5), (6,7)}
Each pair of elements is a line, starting at the element before it.
The beginning element is the start of the stroke, and the ending element is the end of the stroke.
I want to compare A and B for similarity, and in the end get a percentage accuracy.
I have done some research already and found references to Hausdorff Distance and Frechet Distance but I cannot figure out how to get these to do what I want them to do.
Thank you!
(The language I am looking to code this in, is Java if any libraries exist for this problem, that would be greatly appreciated)

Join two lines in one line (in Java)

I have an array of Lines and I am using it to draw vectors in my map.
I want to replace two superposed Lines (or have short distance between them) with one Line. Can you give an algorithm to do that ?
Here is a picture that helps you to understand this problem:
The Input Lines :
After executing the algorithm, I would like to to get the output represented in the following picture:
PS: A Line is an ArrayList of points.
Merge any pair of vertices that are within some fixed distance of each other (set their position to be equal).
Find the nearest point on each line to each vertex. If it's close enough, then split the line on that point, and merge the points.
Remove duplicate lines that have the exact same start and end points.
For example, if you have a line defined by points A and B, and another line with point C (diagram on left above). The point D can be found using a shortest distance from point to line function. If D is too far away from C then ignore it, otherwise split the line AB into two lines AD and DB, and move all points in position C to position D, to get the diagram on the right.
This question is similar to the question "Do two ranges intersect, and if not then what is the distance between them?" The answer depends slightly on whether you already know which range is smallest already, and whether the points in the ranges are ordered correctly (that is, whether the lines have the same direction).
So a preliminary algo approach will be like this :
if (a.start < b.start) {
first = a;
second = b;
} else {
first = b;
second = a;
}
Let us find the distance now :
distance = max(0, second.start - first.end);
Now you have must have a range of values for shortest distance , depending on which you are going to super impose the lines into 1 . Lets say you have kept them in an array called :
arrayRange[];
Now if ,
for(int 1=0;i<arrayRange.length;i++)
{
if(distance is one of the elements of the arrayRange)
then,
callFunctionSuperImposeLines(distance,a,intersectionPoint,a.end,b,b.end);
}

2D waypoint pathfinding: combinations of WPs to go from curLocation to targetLocation

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.

Categories

Resources