Last active
May 3, 2025 13:30
-
-
Save portnov/298567f5cfae0fb678709d9bff75fabb 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
""" | |
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