Created
January 10, 2024 04:24
-
-
Save fisherdog1/8a441f6f6f035866f0501a8698bba422 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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