Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>For each pair of adjacent vertices A,B:</p> <ol> <li><p>construct a vector from A to B, call it p</p></li> <li><p>now construct a vector from A to your test point X call it q</p></li> <li><p>the dot product formula for a pair of vectors is p.q = |p||q|cosC where C is the angle between the vectors.</p></li> <li><p>so if p.q/|p||q| == 1 then the points AX and AB are co-linear. Working on a computer, you will want 1 - p.q/|p||q| &lt; some_small_value depending on how accurate you want to be.</p></li> <li><p>also need to check that |q| &lt; |p| (ie X is closer to A than B)</p></li> </ol> <p>if 4&amp;5 are true your point is on the border.</p> <p>Edit</p> <p>The other way I think I've seen this done is to take your test point X, and construct a line through X perpendicular to the line between A and B. Find where this line and the line A->B cross. Work out the distance from X to this crossing point, if that is sufficiently small you consider the point as being on the line.</p> <p>Edit -- fun little exercise!</p> <p>Posted some code that was wrong earlier due to me misremembering some maths. Had a play in Pythonista on the train home and came up with this which seems to basically work. Have left the maths proof out as editing posts on iPad is painful!</p> <p>Not much testing done, no testing for division by zero etc, caveat user.</p> <pre><code> # we determine the point of intersection X between # the line between A and B and a line through T # that is perpendicular to the line AB (can't draw perpendicular # in ascii, you'll have to imagine that angle between AB and XT is 90 # degrees. # # B # / #. X # / \ # / T # A # once we know X we can work out the closest the line AB # comes to T, if that distance is 0 (or small enough) # we can consider T to be on the line import math # work out where the line through test point t # that is perpendicular to ab crosses ab # # inputs must be 2-tuples or 2-element lists of floats (x,y) # returns (x,y) of point of intersection def intersection_of_perpendicular(a,b,t): if a[0] == b[0]: return (a[0],t[1]) if a[1] == b[1]: return (t[0],a[1]) m = (a[1] - b[1])/(a[0] - b[0]) #slope of ab x_inter = (t[1] - a[1] + m*a[0] + (1/m)*t[0])*m/(m**2 + 1) y_inter = m*(x_inter - a[0]) + a[1] y_inter2 = -(1/m)*(x_inter - t[0]) + t[1] #print '...computed ',m,(x_inter, y_inter), y_inter2 return (x_inter, y_inter) # basic Pythagorean formula for distance between two points def distance(a,b): return math.sqrt( (a[0]-b[0])**2 + (a[1]-b[1])**2 ) # check if a point is within the box defined by a,b at # diagonally opposite corners def point_in_box(a,b,t): xmin = min(a[0],b[0]) xmax = max(a[0],b[0]) ymin = min(a[1],b[1]) ymax = max(a[1],b[1]) x_in_bounds = True if xmax != xmin: x_in_bounds = xmin &lt;= t[0] &lt;= xmax y_in_bounds = True if ymax != ymin: y_in_bounds = ymin &lt;= t[1] &lt;= ymax return x_in_bounds and y_in_bounds # determine if point t is within 'tolerance' distance # of the line between a and b # returns Boolean def is_on_line_between(a,b,t,tolerance=0.01): intersect = intersection_of_perpendicular(a,b,t) dist = distance(intersect, t) in_bounds = point_in_box(a,b,t) return in_bounds and (dist &lt; tolerance) a = (0,0) b = (2,2) t = (0,2) p = intersection_of_perpendicular(a,b,t) bounded = point_in_box(a,b,t) print 'd ',distance(p,t), ' p ',p, bounded a = (0,2) b = (2,2) t = (1,3) p = intersection_of_perpendicular(a,b,t) bounded = point_in_box(a,b,t) print 'd ',distance(p,t),' p ',p, bounded a = (0.0,2.0) b = (2.0,7.0) t = (1.7,6.5) p = intersection_of_perpendicular(a,b,t) bounded = point_in_box(a,b,t) on = is_on_line_between(a,b,t,0.2) print 'd ',distance(p,t),' p ',p, bounded,on </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload