Determine if a 2D point is within a quadrilateral - javascript

I'm working on a JS program which I need to have determine if points are within four corners in a coordinate system.
Could somebody point me in the direction of an answer?
I'm looking at what I think is called a convex quadrilateral. That is, four pretty randomly chosen corner positions with all angles smaller than 180°.
Thanks.

There are two relatively simple approaches. The first approach is to draw a ray from the point to "infinity" (actually, to any point outside the polygon) and count how many sides of the polygon the ray intersects. The point is inside the polygon if and only if the count is odd.
The second approach is to go around the polygon in order and for every pair of vertices vi and vi+1 (wrapping around to the first vertex if necessary), compute the quantity (x - xi) * (yi+1 - yi) - (xi+1 - xi) * (y - yi). If these quantities all have the same sign, the point is inside the polygon. (These quantities are the Z component of the cross product of the vectors (vi+1 - vi) and (p - vi). The condition that they all have the same sign is the same as the condition that p is on the same side (left or right) of every edge.)
Both approaches need to deal with the case that the point is exactly on an edge or on a vertex. You first need to decide whether you want to count such points as being inside the polygon or not. Then you need to adjust the tests accordingly. Be aware that slight numerical rounding errors can give a false answer either way. It's just something you'll have to live with.
Since you have a convex quadrilateral, there's another approach. Pick any three vertices and compute the barycentric coordinates of the point and of the fourth vertex with respect to the triangle formed by the three chosen vertices. If the barycentric coordinates of the point are all positive and all less than the barycentric coordinates of the fourth vertex, then the point is inside the quadrilateral.
P.S. Just found a nice page here that lists quite a number of strategies. Some of them are very interesting.

You need to use winding, or the ray trace method.
With winding, you can determine whether any point is inside any shape built with line segments.
Basically, you take the cross product of each line segment with the point, then add up all the results. That's the way I did it to decide if a star was in a constellation, given a set of constellation lines. I can see that there are other ways..
http://en.wikipedia.org/wiki/Point_in_polygon
There must be some code for this in a few places.

It is MUCH easier to see if a point lies within a triangle.
Any quadrilateral can be divided into two triangles.
If the point is in any of the two triangles that comprise the quadrilateral, then the point is inside the quadrilateral.

Related

Check if a line drawn intersects or inside the existing polygon on html canvas

Check if a line drawn intersects or inside the existing polygon on html canvas.
I have a html canvas and there is polygon (mainly quadrilateral) which is already drawn. Now if a straight line is drawn on the canvas I have to check if it intersects the polygon's any side or it is inside the polygon. If any of these is true (intersects or inside) I have to return true.
I am writing code on Angular.
I assume that you mean line segment rather than infinite line.
You can check whether segment intersects any polygon edge (check them all) with intersection detection algorithm (arbitrary found example)
In case of false result also check one segment end with point in polygon test
If you expect that "inside" case is more frequent - do "point in polygon" first.
Perhaps similar functions already exist in your framework.
Also note that there are simpler methods for axis-aligned rectangle (box)
Obtain the implicit equation of the line of support of your segment (as you say that "inside" is possible, your "line" must be a segment). It has the form
s(x, y) = a x + b y + c = 0
and S is positive on one side of the line and negative on the other side.
Now take every polygon side in turn and plug the coordinates of the two vertices. If the S changes sign between the vertices, the side intersects the line.
Now the trick is to use the parametric equation of the line from one endpoint to the other and find the intersection with the line in terms of the parameter t along the line. Note that the segment will correspond to the t interval [0, 1].
After scanning the whole polygon, you will have a list of t values. If the list is empty, no intersection. If all values in the list are <0 or >1, no intersection. Otherwise, there is an intersection (one subsegment or more).

THREE .JS raycasting performance

I am trying to find the closest distance from a point to large, complex Mesh along a plane in a direction range:
for (var zDown in verticalDistances) {
var myIntersect = {};
for (var theta = Math.PI / 2 - 0.5; theta < Math.PI / 2 + 0.5; theta += 0.3) {
var rayDirection = new THREE.Vector3(
Math.cos(theta),
Math.sin(theta),
0
).transformDirection(object.matrixWorld);
// console.log(rayDirection);
_raycaster.set(verticalDistances[zDown].minFacePoint, rayDirection, 0, 50);
// console.time('raycast: ');
var intersect = _raycaster.intersectObject(planeBufferMesh);
// console.timeEnd('raycast: '); // this is huge!!! ~ 2,300 ms
// console.log(_raycaster);
// console.log(intersect);
if (intersect.length == 0) continue;
if ((!('distance' in myIntersect)) || myIntersect.distance > intersect[0].distance) {
myIntersect.distance = intersect[0].distance;
myIntersect.point = intersect[0].point.clone();
}
}
// do stuff
}
I get great results with mouse hover on the same surface but when performing this loop the raycasting is taking over 2 seconds per cast. The only thing i can think of is that the BackSide of the DoubleSide Material is a ton slower?
Also i notice as I space out my verticalDistances[zDown].minFacePoint to be farther apart raycast starts to speed up up (500ms /cast). So as the distance between verticalDistances[i].minFacePoint and verticalDistances[i+1].minFacePoint increases, the raycaster performs faster.
I would go the route of using octree but the mouse hover event works extremely well on the exact same planeBuffer. Is this a side of Material issue,. that could be solved by loading 2 FrontSide meshes pointing in opposite directions?
Thank You!!!!
EDIT: it is not a front back issue. I ran my raycast down the front and back side of the plane buffer geometry with the same spot result. Live example coming.
EDIT 2: working example here. Performance is little better than Original case but still too slow. I need to move the cylinder in real time. I can optimize a bit by finding certain things, but mouse hover is instant. When you look at the console time the first two(500ms) are the results i am getting for all results.
EDIT 3: added a mouse hover event, that performs the same as the other raycasters. I am not getting results in my working code that i get in this sample though. The results I get for all raycast are the same as i get for the first 1 or 2 in the sample around 500ms. If i could get it down to 200ms i can target the items i am looking for and do way less raycasting. I am completely open to suggestions on better methods. Is octree the way to go?
raycast: : 467.27001953125ms
raycast: : 443.830810546875ms
EDIT 4: #pailhead Here is my plan.
1. find closest grid vertex to point on the plane. I can do a scan of vertex in x/y direction then calculate the min distance.
2. once i have that closest vertex i know that my closest point has to be on a face containing that vertex. So i will find all faces with that vertex using the object.mesh.index.array and calculate the plane to point of each face. Seems like a ray cast should be a little bit smarter than a full scan when intersecting a mesh and at least cull points based on max distance? #WestLangley any suggestions?
EDIT 5:
#pailhead thank you for the help. Its appreciated. I have really simplified my example(<200 lines with tons more comments); Is raycaster checking every face? Much quicker to pick out the faces within the set raycasting range specified in the constructor and do a face to point calc. There is no way this should be looping over every face to raycast. I'm going to write my own PlaneBufferGeometry raycast function tonight, after taking a peak at the source code and checking octree. I would think if we have a range in the raycaster constructor, pull out plane buffer vertices within that range ignoring z. Then just raycast those or do a point to plane calculation. I guess i could just create a "mini" surface from that bounding circle and then raycast against it. But the fact that the max distance(manual uses "far") doesn't effect the speed of the raycaster makes me wonder how much it is optimized for planeBuffer geometries. FYI your 300k loop is ~3ms on jsfiddle.
EDIT 6: Looks like all meshes are treated the same in the raycast function. That means it wont smart hunt out the area for a plane Buffer Geometry. Looking at mesh.js lines 266 we loop over the entire index array. I guess for a regular mesh you dont know what faces are where because its a TIN, but a planeBuffer could really use a bounding box/sphere rule, because your x/y are known order positions and only the Z are unknown. Last edit, Answer will be next
FYI: for max speed, you could use math. There is no need to use ray casting. https://brilliant.org/wiki/3d-coordinate-geometry-equation-of-a-plane/
The biggest issue resolved is filtering out faces of planeBufferGeometry based on vertex index. With a planeBufferGeometry you can find a bounding sphere or rectangle that will give you the faces you need to check. they are ordered in x/y in the index array so that filters out many of the faces. I did an indexOf the bottom left position and lastIndexOf the top right corner position in the index array. RAYCASTING CHECKS EVERY FACE
I also gave up on finding the distance from each face of the object and instead used vertical path down the center of the object. This decreased the ray castings needed.
Lastly I did my own face walk through and used the traingle.closestPointToPoint() function on each face.
Ended up getting around 10ms per point to surface calculation(single raycast) and around 100 ms per object (10 vertical slices) to surface. I was seeing 2.5 seconds per raycast and 25+ seconds per object prior to optimization.

Calculate Angle between two 3D Vectors

Note: I have absolutely no clue about Vector math, especially not in 3D.
I am currently working on some Javascript code that determines if a Finger that got captured by a Leap Motion Controller is extended (i.e. completely straight) or not.
Leap Motion provides us with an API that gives us Object for Hands, Fingers and Bones. Bones in particular have several properties, such as position Vectors, direction Vectors and so on, see here for the Documentation.
My idea was to take the Distal Phalang (tip of your finger) and Proximal Phalang (first bone of your finger), calculate the angle between them by getting the dot product of the two direction Vectors of the bones and then decide if it is straight or not. Like this, essentially:
var a = hand.indexFinger.distal.direction();
var b = hand.indexFinger.proximal.direction();
var dot = Leap.vec3.dot(a,b);
var degree = Math.acos(dot)*180/Math.PI;
The issue here is that these values are not reliable, especially if other fingers move about. It seems like the direction Vectors of the bones change when other fingers change direction (???).
For example, when all my Fingers are extended, the value of degree is roughly 0 and fluctuates between -5 and 5. When I make a fist, the value shoots up to 10, 15, 20. Logging the values of the direction Vectors reveals that they indeed do get changed, but how does this make sense? The Finger doesn't move, so its direction should stay the same.
Even worse for the thumb, the values don't add up there at all. An extended thumb can get values similar to the IndexFinger, but rotation the thumb upwards or downwards has changes in the range of 60 degrees!
I've tried using positional values instead, which gives me NaN results because the values seem to be to big.
So, my question is: how could I reliably calculate the angle between two Vectors? What am I missing here?
The correct formula is
cos(angle) = dot(a,b)/(norm(a)*norm(b))
where norm is the euclidean norm or length.
You should have gotten a wrong result, but the lengths of a and b should be constant, so the result should have been consistently wrong…
dot product is the cosine of the angle between vectors if those vectors are normalized. So be sure that a and b are normalized prior to calculate the dot product

In a spherical condition, given 3 points and their respective distances to a 4th point, how do a find its geolocation? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Trilateration using 3 latitude and longitude points, and 3 distances
This is more of a math question than programming question. Basically, I have P1:(lat1, lon1), P2:(lat2, lon2), P3:(lat3, lon3) and D1, D2, D3, and a 4th unknown point Px:(latx, lonx); also P1, P2, P3 do not lie in the same path of Great Circle, and D1 is the distance between P1 and Px, and D2 is the distance betwwen P2 and Px, etc.
How do I figure out the coordinates of Px?
=edited based on reply=
Thanks a lot!
PS. If you are going to point to any API, I would like it to be in JavaScript.
You have to understand that there will be multiple points that satisfy the mathematical constraint here. Think clearly, if you have two points on a sphere (ignore the geodesic form for now), P1 and P2, and you have another point T1, at distance x from P1 and distance y from P2, then you will have another symmetric (mirrored) point T1' which will satisfy the same distance conditions, on the other side, so to speak.
Even worse: Consider the case of a sphere with a diameter D. Your P1 is at the North Pole, and your P2 is at the South pole. Do you see that the all points on the equator will satisfy your condition?
Apply this to your example: Consider P1 at the North Pole. Consider P2 at the South Pole. Consider distance to Px, i.e. D1 = D2 = (2.pie.r)/4. See the problem? All points on the equator satisfy this, not a single unique point. In fact, for this case, even if D1 != D2, then you have smaller concentric lines (concentric to the equator) whose points satisfy these constraints.
Too many Px's in your case, not one. To come to a singularity point on a spherical surface, the description constraints would be more specific.
Lastly, establishing correctness of the context is important. Should your algorithm support all points that meet the criteria? Or should your criteria be altered such that the algorithm evaluates to a singular point, always. Be careful.
Some links to help you:
Wikipedia: http://en.wikipedia.org/wiki/Spherical_coordinates
SO: Plotting a point on the edge of a sphere
Updates, based on your three point example:
Again, there can be multiple points satisfying your criteria. What if P1, P2, P3 lie on the same arc? See the diagram below. Even with three points, there is no guarantee that there will be a single fourth point satisfying the distance criteria. Even with n points, there is no such guarantee.
In mathematical language, for a set of n random points, and a set of distances from these individual points, the set of resulting points that satisfy the distance criteria MAY have more than one elements.
You may be fooled into thinking: Oh, this guy is always assuming points lying on the same arc. Well, you are not making a special algorithm, are you? Your algo will be a generalized solution, won't it?
You need to guarantee that the points are not on the same arc (in a set of n points, I think at least 1 point cannot be on the same arc).
For keeping source points to a bare minimum : You need to establish traingular relations between points, because then, using ONLY two points, the triangle relation will yield exactly one point.
What triangle? Visualize this: You have two points, and a third unknown point. All distance you mention are SPHERICAL, i.e. curved surface distances. Do you see that there are also flat distances between these points? Can you visualize, that there will be a plane passing through these points, slicing the sphere, right? I say this to emphasize that you do not need to worry about surface curvature (hence 3d steradian angles). You can see the underlying 2d triangle, whose unknown vertex will also be the third point on the sphere surface.
I know this maybe very hard for you to visualize, I'll try making a diagram for this. (Can't find any good online tools!).
Lastly, this will be of significant help: Please read carefully.
Taken from Wikipedia: http://en.wikipedia.org/wiki/Great-circle_distance
The great-circle or orthodromic distance is the shortest distance between any two points on the surface of a sphere measured along a path on the surface of the sphere (as opposed to going through the sphere's interior). Because spherical geometry is different from ordinary Euclidean geometry, the equations for distance take on a different form. The distance between two points in Euclidean space is the length of a straight line from one point to the other. On the sphere, however, there are no straight lines. In non-Euclidean geometry, straight lines are replaced with geodesics. Geodesics on the sphere are the great circles (circles on the sphere whose centers are coincident with the center of the sphere).
Some more updates:
Conversion between long, lats to Cartesian coordinates can be done by the Haversine formula. Google it. See here: Converting from longitude\latitude to Cartesian coordinates
and here: http://en.wikipedia.org/wiki/World_Geodetic_System

What is the math behind this ray-like animation?

I have unobfuscated and simplified this animation into a jsfiddle available here. Nevertheless, I still don't quite understand the math behind it.
Does someone have any insight explaining the animation?
Your fiddle link wasn't working for me due to a missing interval speed, should be using getElementById too (just because it works in Internet Explorer doesn't make it cross-browser).
Here, I forked it, use this one instead:
http://jsfiddle.net/spechackers/hJhCz/
I have also cleaned up the code in your first link:
<pre id="p">
<script type="text/javascript">
var charMap=['p','.'];
var n=0;
function myInterval()
{
n+=7;//this is the amount of screen to "scroll" per interval
var outString="";
//this loop will execute exactly 4096 times. Once for each character we will be working with.
//Our display screen will consist of 32 lines or rows and 128 characters on each line
for(var i=64; i>0; i-=1/64)
{
//Note mod operations can result in numbers like 1.984375 if working with non-integer numbers like we currently are
var mod2=i%2;
if(mod2==0)
{
outString+="\n";
}else{
var tmp=(mod2*(64/i))-(64/i);//a number between 0.9846153846153847 and -4032
tmp=tmp+(n/64);//still working with floating points.
tmp=tmp^(64/i);//this is a bitwise XOR operation. The result will always be an integer
tmp=tmp&1;//this is a bitwise AND operation. Basically we just want to know if the first bit is a 1 or 0.
outString+=charMap[tmp];
}
}//for
document.getElementById("p").innerHTML=outString;
}
myInterval();
setInterval(myInterval,64);
</script>
</pre>
The result of the code in the two links you provided are very different from one another.
However the logic in the code is quite similar. Both use a for-loop to loop through all the characters, a mod operation on a non-integer number, and a bitwise xor operation.
How does it all work, well basically all I can tell you is to pay attention to the variables changing as the input and output change.
All the logic appears to be some sort of bitwise cryptic way to decide which of 2 characters or a line break to add to the page.
I don't quite follow it myself from a calculus or trigonometry sort of perspective.
Consider that each line, as it sweeps across the rectangular area, is actually a rotation of (4?) lines about a fixed origin.
The background appears to "move" according to optical illusion. What actually happens is that the area in between the sweep lines is toggling between two char's as the lines rotate through them.
Here is the rotation eq in 2 dimensions:
first, visualize an (x,y) coordinate pair in one of the lines, before and after rotation (motion):
So, you could make a collection of points for each line and rotate them through arbitrarily sized angles, depending upon how "smooth" you want the animation.
The answer above me looks at the whole plane being transformed with the given formulae.
I tried to simplify it here -
The formula above is a trigonometric equation for rotation it is more simply solved
with a matrix.
x1 is the x coordinate before the the rotation transformation (or operator) acts.
same for y1. say the x1 = 0 and y1 = 1. these are the x,y coordinates of of the end of the
vector in the xy plane - currently your screen. if you plug any angle you will get new
coordinates with the 'tail' of the vector fixes in the same position.
If you do it many times (number of times depends on the angle you choose) you will come back to 0 x = 0 and y =1.
as for the bitwise operation - I don't have any insight as for why exactly this was used.
each iteration there the bitwise operation acts to decide if the point the plane will be drawn or not. note k how the power of k changes the result.
Further reading -
http://en.wikipedia.org/wiki/Linear_algebra#Linear_transformations
http://www.youtube.com/user/khanacademy/videos?query=linear+algebra

Categories

Resources