Why won't shapely split my line with this point? - shapely

I have a long Linestring and I'm getting 2 points on the linestring with shapelies closest_points. That seems to work fine however calling .split() with the line and one of the closest points as args returns the original object, no split. Why is that?
shapely_track = wkt.loads(act.track.wkt)
shapely_seg = wkt.loads(seg.track.wkt)
startpoint, endpoint = shapely_seg.boundary
segment_start, point = nearest_points(shapely_track,startpoint)
segment_end, point = nearest_points(shapely_track,endpoint)
splitted = split(shapely_track,segment_start)
#splitted_again = split(splitted[1], segment_end)
print(len(splitted))
>>>1
Visually everything is allright, points are on the line since i got them with nearest_point, nu funky buisness going on.

It turned out to be a floating point imprecision issue, I added minimal .buffer() to the point before applying .split()

Related

Find intersection of given two lines each passing through more than two points

Challenge:
We have two lines.
Blue line passes through points : (20,100), (25,44.44), (30,30), (35,20), (40,0), (45,0), (50,0), (55,0), (60,0)
Pink line passes through points : (20,00), (25,0), (30,0), (35,0), (40,20), (45,33.33), (50,64.44), (55,100), (60,100)
Without any manual intervention, I want to know the point where they intersect. For example, the point of intersection as shown in figure is (37.5,10)
Remember: The only input of the program is set of points of two lines. Output needed is intersection point of both the line.
Things that did not work out:
I tried to find library of Python that can generate intersection point of two lines(both passing through more than two points). Couldn't find it.
I tried to find a mathematical equation generator for lines passing through more than two points. Then I thought I'll be able to find the intersection of those two equations. Got very complex with lots of polynomial equations!
Most of the places I searched in internet were able to give me intersection of two straight lines that passed through two points only. However as seen in the above image, the both the line passes through about 9 points.
Correct solution:
Well, call it a bummer or any but the solution wasn't as complex as I thought.
Now if you carefully look at the image, you can interpret it in this way:
Instead of calling it a line that passes from lots of points and not just two points, call it a line that is passing through two points. Then it is passing through another two points. Then another two points.. so on..
There are many solutions available online for finding intersection of lines that passes through 2 points. The problem here was only because of the interpretation that both the lines are passing through N number of points (N>2).
Hence, the answer is calculated this way
Step 1: Check for intersection of line1 with first two points [(20,100),(25,44.44)] and line2 with first two points[(20,0.0),(25,0.0)]
Step 2: Check for intersection of line1 with next two points [(25,44.44),(30,30)] and line2 with first two points[(25,0.0),(30,0)]
Step 3: Repeat this process for the whole loop of points till the last point is reached.
Output: The program was able to yield (37.5,10) correctly!
PS: I can share the code of this if need be.

Using the pip2d function in R, how do we know the correct 'order' of the vertices?

I am new to R and I am trying to determine if a point is contained inside a polygon. I am using the R function, pip2d, to do it. I understand the basic principles of the function, but I am having trouble figuring out the appropriate order in which to put the vertices in my polygon matrix. Since I am going to iterate the function over a lot of data, I need to really understand this part so I don't encounter future problems.
1st try
This is what I did for my first try:
poly1 <- rbind(c(14,36), c(14,63), c(25,63), c(25,36))
points <- rbind(c(20,45), c(20,70), c(35,45), c(35,70))
pip2d(poly1, points)
With these coordinates, I was expecting the function to return this output: 1, -1, -1, -1, meaning that the point (20,45) was inside the borders of the polygon.
Instead, I got this : -1, -1, 1, -1 which didn't make any sense to me.
2nd try
I played around a bit with it and changed the order of the vertices, but kept the same polygon:
poly1 <- rbind(c(14,36), c(25,36), c(25,63), c(14,63))
points <- rbind(c(20,45), c(20,70), c(35,45), c(35,70))
pip2d(poly1, points)
This change gave me the expected output: 1, -1, -1, -1.
What's the difference between the order of the first try and the one of the second try?
Thank you
This is due to the convention used to define polygon interior or polygon exterior.
Although it's not clearly specified in pip2d documentation, reading the referenced articles suggests that the convention used here is the 'right hand rule'.
Follow the vertices sequence with the fingers of your right hand :
if your thumb is pointing at you (you're turning Counter Clock Wise), what is in your hand is the interior of the polygon
if your thumb is pointing in the opposite direction, what is in your hand is an hole not belonging to the polygon

How to mirror a vector along a surface?

Hi everyone I couldn't find any solution about this so I wanted to ask this on the forum.
While referencing the image below, I have a curve AB and I want to mirror the direction vector dB along the curve's surface. I only want the mirrored direction. So I need to use that curve as an axis to mirror that direction.
See image
2D Curve
Assuming that you have the normalized tangent t = normalize(a-b), use the following formula, where · is the dot product:
dA = dB - 2*t*(dB·t)
A bit of explanation: t*(dB·t) is the tangential component. Remove it once will give the normal component, a removing it twice will reverse the tangantial component, thus resulting in the reflected vector.
3D Surface
Assuming that you have the normal n of the surface, use the following formula:
dA = -(dB - n*(dB·n)) + n*(dB·n)
which can be simplified to dA = -dB + 2*n*(dB·n).
A bit of explanation: n*(dB·n) is the normal component. We first remove it from dB since we want to preserve it. dB - n*(dB·n) is thus the tangential component. Then, we negate the tangential component, and we add the normal component back to obtain the reflected vector.

Using dot product of non-normalized vectors to project a point onto a line?

I'm trying to determine whether a line intersects a circle, and to do that I'm trying to first calculate whether a point (circle center) is within the bounds of the line, when projected onto the line.
I found an example of that being done here, but I'm having trouble understanding part of it. It creates two vectors, from the one end of the line to the point, and from one end of the line to the other. That's fine.
vec2 vecToPoint = point - lineA;
vec2 vecLine = lineB - lineA;
But then it takes the dot product of these two vectors and divides them, using the result as an offset along the line for the projected point.
float coef = dot(vecToPoint,vecLine) / dot(vecLine,vecLine);
return vec2( lineA.x + (coef * vecLine.x), lineA.y + (coef * vecLine.y) );
This is the part I don't understand. I've done dot products of normalized vectors to get the angle, but I've never seen non-normalized vectors in a dot product before, much less dividing the results.
Can someone explain to me how this is working? What is it doing here?
I finally found a video that explains the math behind this. Makes sense now!

Check which side of a plane points are on

I'm trying to take an array of 3D points and a plane and divide the points up into 2 arrays based on which side of the plane they are on. Before I get to heavily into debugging I wanted to post what I'm planning on doing to make sure my understanding of how to do this will work.
Basically I have the plane with 3 points and I use (pseudo code):
var v1 = new vector(plane.b.x-plane.a.x, plane.b.y-plane.a.y, plane.b.z-plane.a.z);
var v2 = new vector(plane.c.x-plane.a.x, plane.c.y-plane.a.y, plane.c.z-plane.a.z);
I take the cross product of these two vectors to get the normal vector.
Then I loop through my array of points and turn them into vectors and calculate the dot product against the normal.
Then i use the dot product to determine the side that the point is on.
Does this sound like it would work?
Let a*x+b*y+c*z+d=0 be the equation determining your plane.
Substitute the [x,y,z] coordinates of a point into the left hand side of the equation (I mean the a*x+b*y+c*z+d) and look at the sign of the result.
The points having the same sign are on the same side of the plane.
Honestly, I did not examine the details of what you wrote. I guess you agree that what I propose is simpler.
Following the 'put points into the plane's equation and check the sign' approach given previously. The equation can be easily obtained using SymPy. I used it to find location of points (saved as numpy arrays) in a list of points.
from sympy import Point3D, Plane
plane=Plane(Point3D(point1), Point3D(point2), Point3D(point3))
for point in pointList:
if plane.equation(x=point[0], y=point[1],z=point[2]) > 0:
print "point is on side A"
else:
print "point is on side B"
I haven't tested its speed compared to other methods mentioned above but is definitely the easiest method.
Your approach sounds good. However, when you say "and turn them into vectors", it might not be good (depending on the meaning of your sentence).
You should "turn your points into vector" by computing the difference in terms of coordinates between the current point and one of the points in the plane (for example, one of the 3 points defining the plane). As you wrote it, it sounds like you might have misunderstood that ; but apart from that, it's ok!
take into account the normal vector of the plane
example: for the point A=[-243.815437431962, -41.7407630281635, 10.0]
equation= -2663.1860000000006*Z +21305.488000000005=0
RESULt POSITIVE
but if equation= 2663.1860000000006*Z -21305.488000000005=0
RESULT NEGATIVE

Resources