Skip to content

Instantly share code, notes, and snippets.

@fisherdog1
Created January 10, 2024 04:24
Show Gist options
  • Save fisherdog1/8a441f6f6f035866f0501a8698bba422 to your computer and use it in GitHub Desktop.
Save fisherdog1/8a441f6f6f035866f0501a8698bba422 to your computer and use it in GitHub Desktop.
# Lineweld.py
from matplotlib import pyplot
from random import random
import math
# Stuff
def Dot(x1, y1, x2, y2):
return x1 * x2 + y1 * y2
def Mag(x1, y1):
return math.sqrt(x1 ** 2.0 + y1 ** 2.0)
def GregsResaw(listoftuple):
return [p[0] for p in listoftuple], [p[1] for p in listoftuple]
# Example points
density = 20
ex = [i / density for i in range(density * 200)]
ey = [i * math.sin(i / 10) for i in ex]
# Squiggle example
points = list(zip(ex, ey))
# Jeff's Crazy Testpoints (Square spiral with acceleration)
polypoints = []
vertex = (0, 0)
for i in range(20):
x = vertex[0]
y = vertex[1]
r = 100.0 * i / 4
if i % 4 == 0:
x += r
if i % 4 == 1:
y += r
if i % 4 == 2:
x -= r
if i % 4 == 3:
y -= r
dist = round(Mag(vertex[0] - x, vertex[1] - y) / 10.0)
lastvertex = vertex
vertex = (x, y)
for j in range(dist):
a = j / dist
a = 3 * a ** 2 - 2 * a ** 3
px = lastvertex[0] * (1.0 - a) + vertex[0] * a
py = lastvertex[1] * (1.0 - a) + vertex[1] * a
for k in range(9):
polypoints.append((px, py))
# Completely random points
awfulpoints = [(random() * 400 - 200, random() * 400 - 200) for i in range(100)]
fig = pyplot.figure()
ax = fig.add_subplot(111)
ax.scatter(ex, ey, s = 0.1)
ax.set_aspect("equal")
# Angle based line-welding algorithm
ax.scatter(*GregsResaw(polypoints), color = "purple", s = 0.2)
ax.scatter(*GregsResaw(awfulpoints), color = "green", s = 0.2)
# Point angles are measured around, reset for each new segment
pivot = (ex[1], ey[1])
# Previous point on last segment
last = (ex[0], ey[0])
lastsample = last
# Min Distance for filtering out dwell
mindist = 0.05
# Line ending angle change threshold degrees
anglethresh = 5
# Force line segment to end after this length
distthresh = 50
# Result
linepoints = []
linepoints.append(last)
for (x, y) in polypoints[2:]:
lastdir = (pivot[0] - last[0], pivot[1] - last[1])
mag = Mag(*lastdir)
if mag < mindist:
# Unreliable direction, take next point instead
last = pivot
pivot = (x, y)
lastsample = (x, y)
continue
# Normalize direction
lastdir = (lastdir[0] / mag, lastdir[1] / mag)
nextdir = (x - pivot[0], y - pivot[1])
mag = Mag(*nextdir)
if mag < mindist:
# Unreliable direction, take next point instead
lastsample = (x, y)
continue
# Normalize direction
nextdir = (nextdir[0] / mag, nextdir[1] / mag)
# Dot
dot = Dot(*nextdir, *lastdir)
# Angle
anglechange = math.acos(dot) * 180.0 / math.pi
print(anglechange)
if anglechange > anglethresh or mag > distthresh:
# Update pivot to last point before this one
last = lastsample
pivot = (x, y)
linepoints.append(lastsample)
print("New segment")
# Last sample
lastsample = (x, y)
# Finish final segment?
linepoints.append((x, y))
# How good is this?
print(f"Number of segments: {len(linepoints) - 1}, Number of original points: {len(polypoints)}")
pyplot.plot(*GregsResaw(linepoints), color = "red", linewidth = 0.2)
pyplot.scatter(*GregsResaw(linepoints), color = "red", s = 0.5)
pyplot.show()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment