Окружность, ровная, итераций хватает..
При анимации по кругу заметен общий люфт.
При анимации по кругу заметен общий люфт.
Попробуйте такой вариант, пока только для вершин Corner:
Создаем один сплайн Circle и конвертируем его в Editable Spline.
Cплайн должен быть замкнутым-Closed.
Допустим нам хватает 6 итераций для сплайна.
В свитке Interpolation в поле Steps устанавливаем 0 (ноль) итераций-разбиений для сплайна.
Выделяем все сегменты-segment сплайна.
В свитке Geometry в поле Divisions устанавливаем 6 итераций-разбиений для сплайна.
Нажимаем кнопку Divide.
Выделяем все вершины сплайна и устанавливаем тип вершин Corner.
Создаем один чайник Teapot. Выделяем сплайн и чайник.
Запускаем скрипт. В новом окне нажимаем кнопку Apply.
Анимируем % Along Path чайника, который находится в начале сплайна.
Скрипт проверяет только половину длины сплайна и ищет подходящее место.
Объект Dummy и Plane являются вспомогательными и не нужно их удалять.
Код:
try (destroydialog igorznag_spline_ik) catch()
rollout igorznag_spline_ik "SplineIK"
(
--gui
spinner sp_count "Count:" range:[2,1e9,10] fieldWidth:60 type:#integer pos:[32,5]
spinner sp_spacing "Spacing:" range:[0,1e9,10] fieldWidth:60 type:#worldunits pos:[21,22]
checkbox chb_taf "Flip. Object LookAt Axis = X" pos:[5,57]
radiobuttons rb_stoa "Object Upnode Axis" labels:#("Y", "Z") pos:[5,75]
checkbox chb_stoaf "Flip" pos:[80,92]
label lbl_info "Spline Upnode Axis = Z" pos:[5,110]
button btn_apply "Apply" pos:[130,75] width:50 height:50
--events
on btn_apply pressed do
(
if(selection.count==2)then
(
spline_path=undefined; obj=undefined;
spline_types=#(SplineShape,line);cl1=classof selection[1];cl2=classof selection[2]
if(finditem spline_types cl1!=0 and finditem spline_types cl2==0)then
(spline_path=selection[1];obj=selection[2])
if(finditem spline_types cl2!=0 and finditem spline_types cl1==0)then
(spline_path=selection[2];obj=selection[1])
if(spline_path!=undefined)then
(
if numSplines spline_path==1 then
(
if isClosed spline_path 1 then
(
undo on
(
with animate off
(
len=curveLength spline_path 1
if(sp_spacing.value<len)then
(
objs_temp_a=#(); objs_count=sp_count.value
for i=1 to objs_count do
(
maxOps.cloneNodes obj cloneType:#instance newNodes:&n
append objs_temp_a n[1];
)--for i=1 to objs_count do
--
d=plane();d.name=uniquename "igorznag_splineIK";
d.width=0;d.length=0;d.widthsegs=1;d.lengthsegs=1;
d.pos.controller=Position_Constraint()
c=d.pos.controller;c.constraints.appendTarget objs_temp_a[1] 100
d_end=dummy();d_end.pos.controller=position_xyz();
--
for i=1 to objs_temp_a.count do
(
if(i==1)then
(
objs_temp_a[i].pos.controller=Path_Constraint()
c=objs_temp_a[i].pos.controller;c.path=spline_path
c.percent.controller=linear_float();
setBeforeORT c.percent.controller #cycle
setAfterORT c.percent.controller #cycle
)
if(i>1)then objs_temp_a[i].pos.controller=position_xyz();
objs_temp_a[i].rotation.controller = LookAt_Constraint();
c=objs_temp_a[i].rotation.controller
c.target_axis=0;c.lookat_vector_length=0;c.target_axisFlip=chb_taf.checked
objs_temp_a[i].rotation.controller.upnode_world = off
objs_temp_a[i].rotation.controller.pickUpNode=spline_path
c.upnode_ctrl=1;c.StoUP_axis=rb_stoa.state;c.StoUP_axisFlip=chb_stoaf.checked;
c.upnode_axis=2
if(i<objs_temp_a.count)then c.appendTarget objs_temp_a[i+1] 100
if(i==objs_temp_a.count)then c.appendTarget d_end 100
)--for i=1 to objs_temp_a.count do
--script
d.rotation.controller=rotation_script()
c=d.rotation.controller
setBeforeORT c #cycle; setAfterORT c #cycle
c.AddObject "igorznag_spline_path" spline_path
c.AddObject "igorznag_dummy_end" d_end.pos.controller
for i=1 to objs_temp_a.count do
c.AddObject ("igorznag_obj"+(i as string)) objs_temp_a[i].pos.controller
--
str=""
str+="fn sphere_segment_intersect c r o t=";str+="\n"
str+="(";str+="\n"
str+="roots_a=#(); sp_dir=normalize(t-o)";str+="\n"
str+="det=(dot sp_dir (o-c))*(dot sp_dir (o-c))- dot (o-c) (o-c)+r*r";str+="\n"
str+="if(det>=0)then";str+="\n"
str+="(";str+="\n"
str+="d1=-(dot sp_dir (o-c))+pow det 0.5; d2=-(dot sp_dir (o-c))-pow det 0.5";str+="\n"
str+="p1=o+d1*sp_dir; p2=o+d2*sp_dir";str+="\n"
str+="if(dot sp_dir (p1-o)>0 and length (p1-o) < length (t-o))then append roots_a p1";str+="\n"
str+="if(dot sp_dir (p2-o)>0 and length (p2-o) < length (t-o))then append roots_a p2";str+="\n"
str+=")--if(det>=0)then";str+="\n"
str+="roots_a";str+="\n"
str+=")--fn sphere_segment_intersect c r o t=";str+="\n"
str+="";str+="\n"
str+="with animate off ( try (";str+="\n"
str+="spacing="+(sp_spacing.value as string);str+="\n"
str+="len=curveLength igorznag_spline_path 1";str+="\n"
str+="if(len>0)then";str+="\n"
str+="(";str+="\n"
str+="percent1=igorznag_obj1.percent";str+="\n"
str+="percent1=(mod (percent1/100.0) 1.0);if(percent1<0)then percent1+=1";str+="\n"
str+="seg_legths=getSegLengths igorznag_spline_path 1 cum:true numArcSteps:0";str+="\n"
str+="segs_count=int(seg_legths.count-1)/2.0";str+="\n"
str+="seg_by_percent1=0; for i=1 to segs_count where seg_legths[i]>=percent1 do (seg_by_percent1=i;exit)";str+="\n"
str+="seg_by_percent_offset=seg_by_percent1";str+="\n"
for j=2 to objs_temp_a.count do
(
str+="for i=0 to (int(segs_count/2.0)) do";str+="\n"
str+="(";str+="\n"
str+="c=igorznag_obj"+((j-1) as string)+".value";str+="\n"
str+="r=spacing; o=undefined;";str+="\n"
str+="seg_by_percent_o=seg_by_percent_offset+i";str+="\n"
str+="if(seg_by_percent_o>segs_count)then seg_by_percent_o-=segs_count";str+="\n"
str+="o=getKnotPoint igorznag_spline_path 1 seg_by_percent_o";str+="\n"
str+="seg_by_percent_t=seg_by_percent_offset+i+1";str+="\n"
str+="if(seg_by_percent_t>segs_count)then seg_by_percent_t-=segs_count";str+="\n"
str+="t=getKnotPoint igorznag_spline_path 1 seg_by_percent_t";str+="\n"
str+="roots=sphere_segment_intersect c r o t";str+="\n"
str+="if(roots.count>0)then";str+="\n"
str+="(";str+="\n"
str+="if roots.count==1 then";str+="\n"
str+="(";str+="\n"
str+="if (dot (roots[1]-o) (roots[1]-c) >0) then";str+="\n"
str+="(";str+="\n"
str+=" igorznag_obj"+(j as string)+".value=roots[1]";str+="\n"
str+="seg_by_percent_offset=seg_by_percent_o";str+="\n"
str+="exit;";str+="\n"
str+=")";str+="\n"
str+=")";str+="\n"
str+="if roots.count==2 then";str+="\n"
str+="(";str+="\n"
str+="temp_root=roots[2]";str+="\n"
str+="if (dot (roots[1]-o) (roots[1]-c)>0)then temp_root=roots[1]";str+="\n"
str+="if (dot (roots[2]-o) (roots[2]-c)>0)then temp_root=roots[2]";str+="\n"
str+="igorznag_obj"+(j as string)+".value=temp_root";str+="\n"
str+="seg_by_percent_offset=seg_by_percent_o";str+="\n"
str+="exit;";str+="\n"
str+=")--if roots.count==2 then";str+="\n"
str+=")--if(roots.count>0)then";str+="\n"
str+=")--for i=0 to int(segs_count/2.0) do";str+="\n"
)--for i=2 to 2 do--objs_temp_a.count do
--d_end
str+="for i=0 to (int(segs_count/2.0)) do";str+="\n"
str+="(";str+="\n"
str+="c=igorznag_obj"+(objs_temp_a.count as string)+".value";str+="\n"
str+="r=spacing; o=undefined;";str+="\n"
str+="seg_by_percent_o=seg_by_percent_offset+i";str+="\n"
str+="if(seg_by_percent_o>segs_count)then seg_by_percent_o-=segs_count";str+="\n"
str+="o=getKnotPoint igorznag_spline_path 1 seg_by_percent_o";str+="\n"
str+="seg_by_percent_t=seg_by_percent_offset+i+1";str+="\n"
str+="if(seg_by_percent_t>segs_count)then seg_by_percent_t-=segs_count";str+="\n"
str+="t=getKnotPoint igorznag_spline_path 1 seg_by_percent_t";str+="\n"
str+="roots=sphere_segment_intersect c r o t";str+="\n"
str+="if(roots.count>0)then";str+="\n"
str+="(";str+="\n"
str+="if roots.count==1 then";str+="\n"
str+="(";str+="\n"
str+="if (dot (roots[1]-o) (roots[1]-c) >0) then";str+="\n"
str+="(";str+="\n"
str+="igorznag_dummy_end.value=roots[1]";str+="\n"
str+="seg_by_percent_offset=seg_by_percent_o";str+="\n"
str+="exit;";str+="\n"
str+=")";str+="\n"
str+=")";str+="\n"
str+="if roots.count==2 then";str+="\n"
str+="(";str+="\n"
str+="temp_root=roots[2]";str+="\n"
str+="if (dot (roots[1]-o) (roots[1]-c)>0)then temp_root=roots[1]";str+="\n"
str+="if (dot (roots[2]-o) (roots[2]-c)>0)then temp_root=roots[2]";str+="\n"
str+="igorznag_dummy_end.value=temp_root";str+="\n"
str+="seg_by_percent_offset=seg_by_percent_o";str+="\n"
str+="exit;";str+="\n"
str+=")--if roots.count==2 then";str+="\n"
str+=")--if(roots.count>0)then";str+="\n"
str+=")--for i=0 to int(segs_count/2.0) do";str+="\n"
--d_end
str+=")--if(len>0)then";str+="\n"
str+=")catch (quat 0 0 0 1))--try with animate off";str+="\n"
str+="quat 0 0 0 1";
c.script=str
select objs_temp_a; selectmore d; selectmore d_end
redrawViews()
)--if(sp_precision.value<len and sp_spacing.value<len)then
)--with animate off
)--undo off
)--if isClosed spline_path 1 then
)--if numSplines spline_path==1then
)--if(spline_path!=undefined)then
)--if(selection.count==2)then
)--on btn_apply pressed do
--
); createdialog igorznag_spline_ik 190 135