I have a work order management system that has Python 2.7.
The system has lines and points:
Line Vertex 1: 676561.00, 4860927.00
Line Vertex 2: 676557.00, 4860939.00
Point 100: 676551.00, 4860935.00
Point 200: 676558.00, 4860922.00
I want to snap the points to the nearest part of the line.
Snapping can be defined as:
Moving a point so that it coincides exactly with the closest part of a line.
There appear to be two different mathematical scenarios at play:
A. The closest part of a line is the position along the line where the point is perpendicular to the line.
B. Or, the closest part of the line is simply the closest vertex.
Is it possible to snap a point to the closest part of a line using Python 2.7 (and the standard 2.7 library)?
This is an extremely helpful resource.
import collections
import math
Line = collections.namedtuple('Line', 'x1 y1 x2 y2')
Point = collections.namedtuple('Point', 'x y')
def lineLength(line):
dist = math.sqrt((line.x2 - line.x1)**2 + (line.y2 - line.y1)**2)
return dist
## See http://paulbourke.net/geometry/pointlineplane/
## for helpful formulas
## Inputs
line = Line(0.0, 0.0, 100.0, 0.0)
point = Point(50.0, 1500)
## Calculations
print('Inputs:')
print('Line defined by: ({}, {}) and ({}, {})'.format(line.x1, line.y1, line.x2, line.y2))
print('Point "P": ({}, {})'.format(point.x, point.y))
len = lineLength(line)
if (len == 0):
raise Exception('The points on input line must not be identical')
print('\nResults:')
print('Length of line (calculated): {}'.format(len))
u = ((point.x - line.x1) * (line.x2 - line.x1) + (point.y - line.y1) * (line.y2 - line.y1)) / (
len**2)
# restrict to line boundary
if u > 1:
u = 1
elif u < 0:
u = 0
nearestPointOnLine = Point(line.x1 + u * (line.x2 - line.x1), line.y1 + u * (line.y2 - line.y1))
shortestLine = Line(nearestPointOnLine.x, nearestPointOnLine.y, point.x, point.y)
print('Nearest point "N" on line: ({}, {})'.format(nearestPointOnLine.x, nearestPointOnLine.y))
print('Length from "P" to "N": {}'.format(lineLength(shortestLine)))