Skip to content

Instantly share code, notes, and snippets.

@portnov
Last active May 3, 2025 13:30
Show Gist options
  • Save portnov/298567f5cfae0fb678709d9bff75fabb to your computer and use it in GitHub Desktop.
Save portnov/298567f5cfae0fb678709d9bff75fabb to your computer and use it in GitHub Desktop.
"""
in curve_in C
in radiuses_in s
in t0_in s
out ts_out s
out ctrs_out v
"""
import numpy as np
from sverchok.data_structure import zip_long_repeat, ensure_nesting_level
from sverchok.utils.curve import SvCurve
from sverchok.utils.curve.algorithms import SvOffsetCurve
from sverchok.utils.math import TRACK_NORMAL, FRENET
from sverchok.dependencies import scipy
if scipy is None:
raise Exception("This script requires scipy")
from scipy.optimize import root_scalar
def mk_offset(curve, value):
return SvOffsetCurve(
curve,
offset_vector = [1,0,0],
offset_amount = value,
algorithm = TRACK_NORMAL,
resolution = 200)
def goal(ctr, radius, tgt_distance, curve):
offset = mk_offset(curve, tgt_distance)
ctr = np.array(ctr)
def calc(t):
pt = offset.evaluate(t)
rho = np.linalg.norm(pt - ctr) - radius
#print(t, tgt_distance, pt, rho)
return rho
return calc
def solve_step(t1, ctr, radius, tgt_distance, curve):
u1,u2 = curve.get_u_bounds()
result = root_scalar(goal(ctr, radius, tgt_distance, curve),
method = 'brentq',
bracket = (t1, u2),
x0 = (t1 + u2)*0.5,
xtol = 1e-6)
#print(result.root)
return result.root
def calc_next_ctr(ctr, tgt_distance, curve, t):
offset = mk_offset(curve, tgt_distance)
return tuple(offset.evaluate(t))
def solve_curve(t, radiuses, curve):
normal = curve.main_normal(t)
normal /= np.linalg.norm(normal)
p1 = curve.evaluate(t)
prev_radius = radiuses[0]
ctr1 = p1 + normal*prev_radius
ts = [t0]
ctrs = [ctr1]
ctr = p1 + normal * prev_radius
for radius in radiuses[1:]:
t = solve_step(t, ctr, prev_radius + radius, radius, curve)
ctr = calc_next_ctr(ctr, radius, curve, t)
prev_radius = radius
ctrs.append(ctr)
ts.append(t)
return ts, ctrs
curve_in = ensure_nesting_level(curve_in, 2, data_types=(SvCurve,))
radiuses_in = ensure_nesting_level(radiuses_in, 3)
t0_in = ensure_nesting_level(t0_in, 2)
ts_out = []
ctrs_out = []
for params in zip_long_repeat(curve_in, radiuses_in, t0_in):
for curve, radiuses, t0 in zip_long_repeat(*params):
new_ts, new_ctrs = solve_curve(t0, radiuses, curve)
ts_out.append(new_ts)
ctrs_out.append(new_ctrs)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment