[Closed] Clone nodes between two points relative to spline
How to copy objects ei. spheres in this case between A-B points but relative to spline position and direction. In this example I added 2 type of splines (straight line and curve lines).
This is the start scene generated with code below. I commented my failed attempt.
(
delete objects
local colors = #(red,green,gray,yellow,blue)
local sphA = #(), sphB = #()
local avgPosA = [0,0,0], avgPosB = [0,0,0]
for i = 1 to 10 do
(
if i < 6 then
(
x = if i == 1 or i == 5 then -20 else if i==2 or i == 4 then -25 else -30
append sphA (sphere radius:2 pos:[x,(-20+(i-1)*10),0] material:(standard diffuse:colors[i]) wirecolor:black segs:8)
)
else
(
xz = if mod i 2 == 0 then 30 else 20
append sphB (sphere radius:2 pos:[xz,(-40+(i-6)*20),xz] material:(standard diffuse:colors[i-5]) wirecolor:black segs:8)
)
)
for i = 1 to 5 do
(
sphA[i].name = "sphA"+i as string ; avgPosA += sphA[i].pos/5.
sphB[i].name = "sphB"+i as string ; avgPosB += sphB[i].pos/5.
)
splSTR8 = splineshape name:"Guide_STR8" pos:avgPosA wirecolor:green steps:20
addNewSpline splSTR8 ; for p in #(avgPosA, avgPosB) do addKnot splSTR8 1 #smooth #curve p
setKnotType splSTR8 1 1 #beziercorner ; setKnotType splSTR8 1 2 #beziercorner
updateshape splSTR8
splSC = copy splSTR8 name:"Guide_S_Curve" wirecolor:yellow
setOutVec splSC 1 1 [-10,-20,20] ; setInVec splSC 1 2 [0,20,30]
/*
fn dotQuat q q_prev = ( (q.w * q_prev.w + q.x * q_prev.x + q.y * q_prev.y + q.z * q_prev.z) < 0 )
fn blendMatrix m1: m2: weight:0.5 =
(
r1 = m1.rotationpart
r2 = m2.rotationpart
if (dotQuat r1 r2) do r1 *=-1
r = slerp (normalize r1) (normalize r2) weight
t = m1.translationpart + (m2.translationpart - m1.translationpart) * weight
s = m1.scalepart
tm = translate (rotate (scale (matrix3 1) s on) r) t
)
count = 9
tm = arbAxis (normalize (tangentCurve3D splSTR8 1 0.0))
tm.row4 = (interpCurve3D splSTR8 1 0.0)
for i = 1 to 5 do
(
tmA = copy tm ; tmA.row4 = in coordSys tmA sphA[i].pos
tmB = copy tm ; tmB.row4 = in coordSys tmB sphB[i].pos
for j = 1 to count do blendMatrix sphA[i] m1:tmA m2:tmB weight:((1./count)*i)
)*/
)
Actually both. One only for position and the other Pos-Rot-Scale.
I create some surface in Rhinoceros using two shape profiles and guide. Now I’m looking the way to place some cutting objects to make openings. That’s why I need this concept.
It’s easier to create these objs in max on right position and then export these to Rhino for cutting process.
here is position:
fn scatterWithSplinePattern startNode endNode spline steps:10 pathParam:off =
(
fn matrixFrom2Vectors v1 v2 pos:[0,0,0] =
(
front = normalize v1
side = normalize (cross (normalize v2) front)
up = normalize (cross front side)
matrix3 front side up pos
)
s = getknotpoint spline 1 1
e = getknotpoint spline 1 (numknots spline 1)
stm = spline.transform
tm0 = matrixFrom2Vectors (e - s) spline.dir pos:s
tm1 = matrixFrom2Vectors (endNode.pos - startNode.pos) z_axis pos:startNode.pos
d0 = distance s e
d1 = distance startNode endNode
dtm = stm * inverse tm0 * (prescale tm1 [d1/d0,1,1])
ps = copy spline name:"ps" transform:dtm wirecolor:(color 255 100 100)
interp = if pathParam then pathInterp else lengthInterp
for k=0.0 to 1.0 by (1.0/steps) do
(
pos = (interp spline k) * inverse spline.objecttransform * dtm
p = point name:(uniquename "pt") size:5 pos:pos cross:on box:off wirecolor:(red*0.7)
)
)
delete objects
(
--seed 0
sp = converttosplineshape (helix radius1:(random 5 20) radius2:(random 5 20) turns:(random 0.3 2.0) wirecolor:green)
pos0 = random -[40,40,40] [40,40,40]
pos1 = random -[40,40,40] [40,40,40]
p0 = point name:"p0" size:5 pos:pos0 axistripod:off cross:on box:on wirecolor:yellow
p1 = point name:"p1" size:5 pos:pos1 axistripod:off cross:on box:on wirecolor:orange
scatterWithSplinePattern p0 p1 sp
)
add scale is easy… rotation is more tricky and i will not show it. because i use this algorithm in my rigs.
well… let’s say we have only point A and a spline that moves us to the point B.
in this case everything is obvious. the point B is at the end of shifted spline with offset (from A to spline’s pivot)
right?
Yes. We need to consider point A for cloning. Point B is last clone of point A.
I do not know how to describe better but point A need to be blended in point B following the line. Distance of PointA and first knot is different then PointB and second(last knot) ei. distance is gradually increased
honestly i exactly know what you mean.
if the point B is not exact end of shifted spline we can easily make a correction. we have to scale the spline to make its end be in the point B position.
I not understand you. Spline here only repersent imaginary guide (direction) that connects average position (center) of points A and B which we need to follow. I have already shown in my attempt what method can be used but “combo” is not correct and I know that matrix formula is quite complex … for me of course.
edit: off topic\
I hate time difference.
You posted last comment at 5:36am in my(country) time. This “edit” is posted at 5:30am in NY time.
Hey fajar
I know about that concept but I need mxs solution. Also copy of object need to have relative offset but not to be aligned with spline
This is the test on my example. Strange offset problem?
fn scatterWithSplinePattern startNode endNode spline wc:red steps:10 pathParam:off =
(
fn matrixFrom2Vectors v1 v2 pos:[0,0,0] =
(
front = normalize v1
side = normalize (cross (normalize v2) front)
up = normalize (cross front side)
matrix3 front side up pos
)
s = getknotpoint spline 1 1
e = getknotpoint spline 1 (numknots spline 1)
stm = spline.transform
tm0 = matrixFrom2Vectors (e - s) spline.dir pos:s
tm1 = matrixFrom2Vectors (endNode.pos - startNode.pos) z_axis pos:startNode.pos
d0 = distance s e
d1 = distance startNode endNode
dtm = stm * inverse tm0 * (prescale tm1 [d1/d0,1,1])
ps = copy spline name:"ps" transform:dtm wirecolor:wc
interp = if pathParam then pathInterp else lengthInterp
for k=0.0 to 1.0 by (1.0/steps) do
(
pos = (interp spline k)*dtm
p = point name:(uniquename "pt") size:5 pos:pos cross:on box:off wirecolor:wc
)
)
/*
delete $pt*
colors = #(red,green,gray,yellow,blue)
arr_A = $sphA* as array
arr_B = $sphB* as array
-- straight line points scatter
for i = 1 to arr_A.count do scatterWithSplinePattern arr_A[i] arr_B[i] $Guide_STR8 wc:colors[i]
-- curve lines points scatter
for i = 1 to arr_A.count do scatterWithSplinePattern arr_A[i] arr_B[i] $Guide_S_Curve wc:colors[i]
straight line points scatter
curve lines points scatter
how can i figure out the problem if i don’t have your spline? post the spline
edited…
ok. i’ve got why… i’ve fixed it in the code. (see it in red)
I mean on my example code from first post (#1)
Can you see green (Guide_STR8) and yellow(Guide_S_Curve) spline?
Yup. It works fantastic.
Is second method much different from this one? I mean Pos-Rot-Scale.
BTW despite the strange results it looks very cool.
This way can be also created mesh surface. Right?
Thanks for this matrix lesson.
edit: I will try right now.
the problem is how to calculate normal for spline. you have only tangent for sure. the normal needs some algorithm. who knows it has flip-free path constraint for example… or stable spline IK
I not undertand matrix methods very well but can you use average normal of A and B point as Up vector. Or I made a dumb idea:hmm:
Do we have to create this splines (stretched guides) to calculate point positions or just we can use main guide and somehow offset positions?
I’m analyze your code. You added two choises : path and length Interpolation.
I will probably use only lengthInterp for this.
Also are you just copy and stretch Guide spline? I ask this because I not see that you setup In and Out knots vector.