Skip to content

Instantly share code, notes, and snippets.

@zeffii
Forked from anonymous/point_on_lne.py
Last active August 29, 2015 13:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zeffii/9857952 to your computer and use it in GitHub Desktop.
Save zeffii/9857952 to your computer and use it in GitHub Desktop.
# This example assumes we have a mesh object in edit-mode
import bpy
import bmesh
from mathutils import Vector
from mathutils.geometry import intersect_point_line as pt_on_line
# or
# from mathutils.geometry import intersect_point_line as PtLineIntersect
''' step 1 '''
# invent an edge.
a = Vector((1.0, 0.0, 0.0))
b = Vector((2.0, 0.0, 0.0))
''' step 2 '''
# pick a point we know is definitely between those two points
intx = Vector((1.5, 0.0, 0.0))
# use intersect_point_line to see how it responds.
k = pt_on_line(intx, a, b)
print(k)
# >>> (Vector((1.5, 0.0, 0.0)), 0.5)
# >>> cool, the difference between intx and k[0] will be very very small.
# >>> k[1] tells us the ratio between point a and b that this intersection
# lies on.
''' step 3 '''
# pick a different point not on the edge, but still on the infinitely
# long line described by the two points. The vector will be the same as the
# input vector.
intx = Vector((0.5, 0.0, 0.0))
k = pt_on_line(intx, a, b)
print(k)
# >>> (Vector((0.5, 0.0, 0.0)), -0.5)
# the negative 0.5 means it's beyond the limits of the edge.
''' step 4 '''
# ok, that's great let's try the other extreme, let's place the intersection
# vector on the other side, but still on the mathematical line.
intx = Vector((2.5, 0.0, 0.0))
k = pt_on_line(intx, a, b)
print(k)
# >>> (Vector((2.5, 0.0, 0.0)), 1.5)
# as expected, maybe, the ratio is now 1.5 because it's relative to the
# distance between point a and b, starting from point a.
''' step 5 '''
# time to try a vector which we know is not axactly on the edge or line..
# we could do several variations on this
intx = Vector((1.5, 1.0, 0.0))
k = pt_on_line(intx, a, b)
print(k)
# >>> (Vector((1.5, 0.0, 0.0)), 0.5)
# it returns the point between a, b which is closest to input vector
# but the most important information is (intx-k[0]) , if that isn't a very
# small value then we know it's not on the line / or edge described by (a,b).
# I've settled on a PRECISION = 1.0e-5 to determine this.
# - if (intx-k[0]).length is not less than PRECISION, it's not good enough.
# - if it is, then k[1] must be between 0.0 and 1.0 to be acceptable
# - you can avoid redundant checks by testing of intx is equal to a or b.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment