Python line-plane collision detection - python

I need to work out whether a line segment will intersect a face of a 3D polygon (so a section of a plane confined by 4 points). Are there any well known python libraries that I could use? If not, how should I go about this?
I've tried looking at line-plane intersection equations but they seem over complicated as I only need to know if it will intersect, not find the point of intersection.
Sorry if this question has been asked before! Thanks

There's no way to do this that's simpler than the obvious one:
find the infinite plan that contains your polygon
determine the point where the line intersects that plane
determine whether this point is within the polygon
All but the very rare line will intersect the infinite plan somewhere, so the question isn't "does it intersect the plane", but "where"?
Each step in the above will be about as simple as a 3D geometry question can get, but still involve many the 3D mathematical tools (vectors, matrices, etc). There are lots of descriptions about how to do them, and I recommend that you search around for one that's presented at a level and in a notation that you're comfortable with. For example, for the line (infinite) plane intersection you could look here.

Related

Finding the intersection(s) of two 3D Polylines

I currently have 2 paths generated by a motion planning algorithm in Python. I interpolated into two 3D Polylines with equidistant points. Next I need to find whether these two paths of different lengths intersect (OR even ideally the point(s) at which they get near a certain distance of each other, if any). This is to eventually simulate a collision avoidance algorithm.
After much searching I have found multiple libraries and algorithms that can return points/line intersections of two Polylines, however they are all in 2D. I tried using the Bentley-Ottmann algorithm/python library, the Shapely library, the Geometry3D library, and other 2D solutions found on SO, but none have worked in a 3D environment. Next I tried using a 2D geometry library to find the intersections in the x-y, x-z, and y-z planes individually as shown in the graphs below showing a simple case, but I'm not sure where to go from there or whether that's even the right approach. The Polylines would usually contain 300+ points.
Any help pointing me towards a 3D algorithm or simple adjustments to make to the 2D libraries work in 3D would be really appreciated!
3D graph view, x-y view, z-y view.

How to draw smooth contour/level curves of multivariable functions

G'day programmers and math enthusiasts.
Recently I have been exploring how CAS graphing calculators function; in particular, how they are able to draw level curves and hence contours for multivariable functions.
Just a couple of notes before I ask my question:
I am using Python's Pygame library purely for the window and graphics. Of course there are better options out there but I really wanted to keep my code as primitive as I am comfortable with, in an effort to learn the most.
Yes, yes. I know about matplotlib! God have I seen 100 different suggestions for using other supporting libraries. And while they are definitely stunning and robust tools, I am really trying to build up my knowledge from the foundations here so that one day I may even be able to grow and support libraries such as them.
My ultimate goal is to get plots looking as smooth as this:
Mathematica Contour Plot Circle E.g.
What I currently do is:
Evaluate the function over a grid of 500x500 points equal to 0, with some error tolerance (mine is 0.01). This gives me a rough approximation of the level curve at f(x,y)=0.
Then I use a dodgy distance function to find each point's closest neighbour, and draw an anti-aliased line between the two.
The results of both of these steps can be seen here:
First Evaluating Valid Grid Points
Then Drawing Lines to Closest Points
For obvious reasons I've got gaps in the graph where the next closest point is always keeping the graph discontinuous. Alas! I thought of another janky work around. How about on top of finding the closest point, it actually looks for the next closest point that hasn't already been visited? This idea came close, but still doesn't really seem to be even close to efficient. Here are my results after implementing that:
Slightly Smarter Point Connecting
My question is, how is this sort of thing typically implemented in graphing calculators? Have I been going about this all wrong? Any ideas or suggestions would be greatly appreciated :)
(I haven't included any code, mainly because it's not super clear, and also not particularly relevant to the problem).
Also if anyone has some hardcore math answers to suggest, don't be afraid to suggest them, I've got a healthy background in coding and mathematics (especially numerical and computational methods) so here's me hoping I should be able to cope with them.
so you are evaluating the equation for every x and y point on your plane. then you check if the result is < 0.01 and if so, you are drawing the point.
a better way to check if the point should be drawn is to check if one of the following is true:
(a) if the point is zero
(b) if the point is positive and has at least one negative neighbor
(c) if the point is negative and has at least one positive neighbor
there are 3 problems with this:
it doesn't support any kind of antialisasing so the result will not look as smooth as you would want
you can't make thicker lines (more then 1 pixel)
if the 0-point line is only touching (it's positive on both sides and not positive on one, negative on the other)
this second solution may fix those problems but it was made by me and not tested so it may or may not work:
you assign the value to a corner and then calculate the distance to the zero line for each point from it's corners. this is the algorithm for finding the distance:
def distance(tl, tr, bl, br): # the 4 corners
avg = abs((tl + tr + bl + br) / 4) # getting the absolute average
m = min(map(abs, (tl + tr + bl + br))) # absolute minimum of points
if min == 0: # special case
return float('inf')
return avg / m # distance to 0 point assuming the trend will continue
this returns the estimated distance to the 0 line you can now draw the pixel e.g. if you want a 5-pixel line, then if the result is <4 you draw the pixel full color, elif the pixel is <5 you draw the pixel with an opacity of distance - 4 (*255 if you are using pygames alpha option)
this solution assumes that the function is somewhat linear.
just try it, in the worst case it doesn't work...
http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.30.1319&rep=rep1&type=pdf
This 21 Page doc has everything I need to draw the implicit curves accurately and smoothly. It even covers optimisation methods and supports bifurcation points for implicit functions. Would highly recommend to anyone with questions similar to my own above.
Thanks to everyone who had recommendations and clarifying questions, they all helped lead me to this resource.

Constructing convex hull object with known triangular faces

TLDR: I need to construct a python object for fast interior point testing, similar to a SciPy ConvexHull or DelaunayTriangulation. The catch is that I know ahead of time the order in which the triangulation of the points must be constructed: (6 points, 8 triangular faces, with a specific ordering of each face). In effect, I already know what the convex hull should be, but I need it in a form that I can use with existing (and optimised!) libraries (eg Scipy spatial). How can I do this?
Context:
I need to construct a triangular prism (imagine a Toblerone bar - 2 end faces, 6 side faces, all triangular) in order to do some interior point testing. As I will have many such prisms lying adjacent to each other (adjacent on their side faces, imagine many Toblerone bars stood on their ends and next to each other), I need to be careful to ensure that no region in space is contained by two adjacent prisms. The cross section of the prism will not generally be uniform, hence the possibility of overlap between adjacent prisms, as illustrated by this diagram of the approximately planar face between two adjacent prisms:
____
|\ /|
| \/ |
| /\ |
|/__\|
Note the two different diagonals constructed along the face - this is the problem. One prism may split the face into two triangles using the \ diagonal, and the neighbouring prism may instead use the /. In order to ensure no overlap between adjacent prisms, I need to explicitly control the order in which the triangles are formed so that they always use the same diagonal. This I can do: for each prism that I need to construct, I know ahead of time in what order the triangular faces should be constructed. Here's an illustration of two adjacent prisms, with the correct shared diagonal between them: neighbouring prisms, shared diagonal
My issue is with performing fast interior point testing with these prisms. Previously, I was using the approach linked in this answer: Delaunay(prism_points).find_simplex(test_points) >= 0. It's quick because it is using highly optimised library code, but I have no control over the construction of the triangulation, so there could be overlap.
If I construct the hulls as explicit np.array objects (vertices, faces) then I can use my own code to do the tests (there are numerous possible approaches, I'm projecting rays and testing for intersection with each triangular face). The problem is that this is around ~100x slower than the find_simplex() approach mentioned earlier. Whilst I'm sure I could get the code a bit quicker, it is worth pointing out this code is already fairly optimised from another use case with Cython - I am not sure if I can find all the extra speed I need here. As for the inevitable "do you really need the speed question", please take my word for it. This is turning a 5 minute job into many hours.
What I need is to construct an object I can use with external optimised libraries, whilst retaining control of the triangular faces. Adding extra Cython to my code is of course an option, but which such highly optimised code already out there, using that would be vastly preferable.
Thanks to anyone that can help.
Half a solution... Not an exact solution to the original question, but a different way of achieving the same outcome. Any triangular prism can be split into exactly three tetrahedra (see http://www.alecjacobson.com/weblog/?p=1888). This is a specific case of the fact that any polyhedron may be split into tetrahedra by connecting all faces to one vertex, if the faces does not already include it.
Knowing exactly how I would like the face triangles of my prism to be arranged, I can work out what three tetrahedra would reproduce the same configuration of triangles (with extra faces of course being added inside the original prism itself). I then form Delaunay triangulations around each of these three tetrahedra (ie, collections of 4 points) in turn and perform the original interior point tests: if it matches on any then I have a positive result for the whole prism. The key point is that by only giving four points to the Delaunay constructor at a time, I know exactly what triangulation it will return as there is only one way of forming such a tetrahedra (assuming no geometric degeneracy).
It's a bit longwinded, and involves 3x as many tests as I would like, but it's a start. If anyone in the future does know how I could do this better please do let me know.

Find "anomalous" curves in a "generic-linear" shape

I am not a mathematician but I am pretty sure my problem could be solved with a bit (maybe a lot?) of good maths.
Let me explain the problem with a picture.
I have a network (GIS data) which is composed of many linear segments.
Rarely, a curve is present throughout these segments and I would need to find a reasonable method to detect them rather automatically.
Given that I have the coordinates of my segments and the curves (the green dots in the picture), would you reccomend a reasonable way to detect these curves?
I am not sure but it could be similar to the opposite of what is asked in this other SO question, but I don't actually have a function to calculate a second derivative, only line segments (and curves) made by vertices...
Assuming you can easily list out the points in a segment and iterate over them, and that a segment is "mostly" linear, you can take the end-points of a segment and interpolate a line between them.
Next, check if each point of the segment lies on the interpolated line and add a margin of error.
You can then assume that several adjacent points of the segment that do not lie on the interpolated line make up a curve.
You may need to implement other checks:
Are the end-points are part of a straight segment -- i.e. that the segment does not end in a curve
Does the segment bend and should the segment be treated as two segments?
Can two curves be adjacent to one another without a point between them that's on the line?
To get started with python, I'd write the function is_on_line and loop over all the points, calling it each time to see if the point is on the line.
Excuse the verbose pseudo code (makes lots of assumptions about data structures, can be done in one loop), but this should help you break the problem apart to get started:
points_on_line = []
for idx, point in enumerate(segment):
result = is_on_line(
endpoint_1_x=segment[0].x,
endpoint_1_y=segment[0].y,
endpoint_2_x=segment[-1].x,
endpoint_2_y=segment[-1].y,
coord_x=point.x,
coord_y=point.y,
error_margin=0.1,
)
points_on_line.append((point, result,))
for point, on_line in points_on_line:
# figure out where your curves are

Detecting the centre of a curved shape with opencv

I've been trying for a while to find the centre of a curved shape (for example a banana). I can do all the basics, such as creating a binary image, and locating the contour. However, the centroid function correctly finds a point outside of the contour. The point I require must be inside the contour. I've attached an image which should explain things better.
If anyone has any ideas, or has seen something similar I would really appreciate some help.
You could look at this answer, What is the fastest way to find the "visual" center of an irregularly shaped polygon?
Basically skeletonisation algorithms should help (in terms of efficiency and accuracy as compared to continuous erosion, which would fail in some cases), since they narrow down the set of possible valid points to a set of line segments, which you can then do some sort of conditional processing on.

Categories

Resources