Ýòîò óðîê ñîçäàâàëñÿ äëÿ Render.ru
Ðåçóëüòàò âûïîëíåíèÿ óðîêà (ñ 2:33)

Ìàêðîñêðèïò ArchedSpline: ïàðàìåòðè÷åñêèé àðî÷íûé ñïëàéí

Ìîé ïñåâäîíèì 1acc, ÿ ïèøó ñêðèïòû â 3dsmax è â äàííîì óðîêå õî÷ó ïðîäåìîíñòðèðîâàòü, êàê ýòî äåëàòü áûñòðî, ïðîñòî è ýôôåêòèâíî. Íà ïðèìåðå ArchedSpline ïîñòàðàþñü îõâàòèòü âñå ñòàäèè ñêðèïòîïðîèçâîäñòâà, îò èäåè äî ðåàëèçàöèè. Ñêðèïòîâûé ýëåìåíò óðîêà ñîñòîèò èç 3-õ ÷àñòåé - íåçàâèñèìûõ ôðàãìåíòîâ îáùåãî êîäà, êîòîðûå ìîæíî êîïèðîâàòü, çàïóñêàòü è ñìîòðåòü, ÷òî ïîëó÷èëîñü. Ôèíàëüíûé ñêðèïò íóæíî óñòàíàâëèâàòü, ïîýòîìó åãî êîäà â óðîêå íåò - æåëàþùèå ìîãóò åãî ïîñìîòðåòü óæå â 3dsmax.  êîíöå óðîêà ïðèâåäåí ñêðèïòîâûé ôðàãìåíò ñ êîììåíòàðèÿìè, êîòîðûé îáúÿñíÿåò, ÷òî íóæíî äîáàâèòü äî ôèíàëà.

Èäåÿ: îïòèìèçèðîâàòü ñîçäàíèå è ðåäàêòèðîâàíèå ñïëàéíà - îñíîâû äëÿ àðî÷íîãî ïðîåìà. Ñïëàéí òàêîãî âèäà ñîçäàâàòü ñòàíäàðòíûìè ñðåäñòâàìè ñëèøêîì äîëãî è î÷åíü íåóäîáíî, îñîáåííî, åñëè íóæíà òî÷íîñòü, õî÷åòñÿ ìàêñèìàëüíî îïòèìèçèðîâàòü ïðîöåññ, ÷åì ÿ ñåé÷àñ è çàéìóñü.

Ñòðóêòóðà êîäà è èíòåðôåéñ: ôèíàëüíûé ñêðèïò áóäåò ìàêðîñêðèïòîì, òî åñòü êíîïêà íà ïàíåëè, ïðè íàæàòèè íà êîòîðóþ îí çàïóñêàåòñÿ. Ïðè çàïóñêå îòêðûâàåòñÿ îêíî ñ ÷åòûðüìÿ ñïèííåðàìè, îòâå÷àþùèìè çà ïàðàìåòðû ñïëàéíà è êíîïêîé Create, ñîçäàþùåé ñïëàéí. Ïàðàìåòðû: îáùàÿ äëèíà, îáùàÿ âûñîòà, âûñîòà àðêè, ðàäèóñ àðêè - ñ÷èòàþ èõ íåîáõîäèìûìè è äîñòàòî÷íûìè. Ïî-àíãëèéñêè â èíòåðôåéñå îíè áóäóò â òîì æå ïîðÿäêå íàçûâàòüñÿ ñîîòâåòñòâåííî: Full Length, Full Height, Arc Height, Arc Radius.


Âõîäíûå äàííûå: ïðåæäå ÷åì ñîçäàâàòü ñêðèïòîì ëþáîé îáúåêò, íåîáõîäèìî îïðåäåëèòüñÿ, â êàêîé ñèñòåìå êîîðäèíàò (ÑÊ) îí áóäåò íàõîäèòüñÿ: â ëþáîé èëè çàðàíåå ïðåäîïðåäåëåííîé.  ìîåì ñëó÷àå ÑÊ íåîïðåäåëåíà, òàê êàê ïîëîæåíèå ïëîñêîñòè ñòåíû íåèçâåñòíî è îíà ìîæåò ðàñïîëàãàòüñÿ êàê óãîäíî â ïðîñòðàíñòâå. Çíà÷èò, ïðè ñîçäàíèè ñïëàéíà íåîáõîäèìî çàäàòü ÑÊ è åãî ïàðàìåòðû. ÑÊ çàäàåòñÿ òðåìÿ òî÷êàìè A B C, îïðåäåëÿþùèìè ïëîñêîñòü XY, íàïðàâëåíèå îñè Z äëÿ ìåíÿ â äàííîì ñëó÷àå íåâàæíî. Ñýêîíîìëþ âðåìÿ è ââåäó íà÷àëüíûå ãàáàðèòû ñïëàéíà îäíîâðåìåííî ñ óêàçàíèåì òî÷åê, ó÷èòûâàÿ òî, ÷òî èñõîäíàÿ äóãà ñîñòàâëÿåò ïîëîâèíó îêðóæíîñòè (180 ãðàäóñîâ) ñ äèàìåòðîì, ðàâíûì äëèíå âåêòîðà AB. Òî÷êè A è B - êðàéíèå òî÷êè îñíîâàíèÿ ñïëàéíà. Òî÷êà C ìîæåò íàõîäèòüñÿ â ëþáîì ìåñòå íà ïðÿìîé n è îïðåäåëÿåò âûñîòó ïðîåìà, òî åñòü äëèíà ïåðïåíäèêóëÿðà CN, îïóùåííîãî èç íåå íà ïðÿìóþ AB ðàâíà ëèáî ïîëíîé âûñîòå ñïëàéíà (âàðèàíò 1), ëèáî âûñîòå ñåãìåíòà äî äóãè (âàðèàíò 2 - â ñëó÷àå, êîãäà íåâîçìîæíî íà÷åðòèòü 180-ãðàäóñíóþ äóãó ñ ìàêñèìóìîì â òî÷êå C). Ïîñëå ñîçäàíèÿ ñïëàéíà, ñîîòâåòñòâóþùåãî ãàáàðèòàì, åãî ìîæíî îòðåäàêòèðîâàòü ïî 4-ì ïàðàìåòðàì: èçìåíèòü äëèíó, îáùóþ âûñîòó, âûñîòó àðêè è ðàäèóñ àðêè. Ïîñëåäíèå äâà ïàðàìåòðà âçàèìîçàâèñèìûå, ò.å. ïðè èçìåíåíèè îäíîãî ìåíÿåòñÿ è äðóãîé. Âîçìîæíîñòü ðåäàêòèðîâàòü ïàðàìåòðû äîëæíà áûòü äîñòóïíà âñåãäà, ïîýòîìó èõ äëÿ êàæäîãî ñïëàéíà íóæíî ãäå-òî õðàíèòü, íî îá ýòîì ïîñëå.
Èòàê, îïðåäåëèëñÿ ñ ãåîìåòðèåé, âõîäíûìè äàííûìè, ïàðàìåòðàìè, òåïåðü íåìíîãî ìàòåìàòèêè. ß íå áóäó îïèñûâàòü ðåøåíèå, êòî çàõî÷åò - ìîæåò ñàì ïîñ÷èòàòü, ýòî çàäà÷à äëÿ ñòàðøåãî êëàññà ñðåäíåé øêîëû. Îäèí î÷åíü âàæíûé ìîìåíò - çàäà÷à ðåøàåòñÿ â ñèñòåìå êîîðäèíàò ñïëàéíà ñ öåíòðîì â òî÷êå O [0,0,0], âåêòîð AB (èëè BA, ìíå íåâàæíî, ò.ê. ñïëàéí ñèììåòðè÷íûé) - íàïðàâëåíèå îñè x, âåêòîð NC - íàïðàâëåíèå îñè y. Êàê ýòîò ñïëàéí ïîñòàâèòü â ìèðîâóþ ÑÊ, ò.å. â ñîîòâåòñòâèè ñ ðåàëüíûìè êîîðäèíàòàìè òî÷åê ABC - óæå çàäà÷à óíèâåðñèòåòà :-) è åå ðåøåíèå âû óçíàåòå äàëüøå, êîãäà ÿ áóäó îïèñûâàòü êîä. Ñåé÷àñ ïðèâîæó òîëüêî êîíå÷íûå ôîðìóëû â ÑÊ ñïëàéíà (ñðàçó â ñèíòàêñèñå MAXScript):

R=(l^2+h^2)/(2*h)
h=R-sqrt(R^2-l^2)
a=asin(l/R)
c=[0, H, 0]-[0, R, 0]

Çäåñü: R - ðàäèóñ àðêè, h - âûñîòà àðêè, H - îáùàÿ âûñîòà, l - ïîëîâèíà îáùåé äëèíû, a - ïîëîâèíà óãëà äóãè (íåîáõîäèìî çíàòü äëÿ ïîñòðîåíèÿ äóãè), c - êîîðäèíàòà öåíòðà äóãè, sqrt - êâàäðàòíûé êîðåíü, asin - àðêñèíóñ, ^2 - âîçâåäåíèå â êâàäðàò.

Íó âñå, òåïåðü íàêîíåö ìîæíî ïðèñòóïàòü íåïîñðåäñòâåííî ê ïðîãðàììèðîâàíèþ.
ß îñòàâëÿþ "íà ïîòîì" âñå äåòàëè, ñâÿçàííûå ñ îïèñàíèåì èíòåðôåéñà è ñîçäàþ äâå îñíîâíûõ ôóíêöèè.

Ïåðâàÿ: getcoordmatrix - ïîëó÷àåò ÑÊ ïî òðåì òî÷êàì. Òî÷êè äëÿ ôóíêöèè ëèáî çàäàþòñÿ ïîëüçîâàòåëåì ïðè ñîçäàíèè ñïëàéíà, ëèáî áåðóòñÿ èç âåðøèí ñïëàéíà, â ñëó÷àå, êîãäà ñïëàéí óæå ñîçäàí è íàäî ïîëó÷èòü åãî ÑÊ äëÿ ðåäàêòèðîâàíèÿ ñïëàéíà.
Âòîðàÿ: editarchedspline - ñîçäàåò àðî÷íûé ñïëàéí ïî ïàðàìåòðàì.

--ÑÊÐÈÏÒÎÂÀß ×ÀÑÒÜ 1
fn getcoordmatrix pp = ( --ÍÀ ÂÕÎÄ ÔÓÍÊÖÈÈ ÏÎÑÒÓÏÀÅÒ ÌÀÑÑÈ ÈÇ ÒÐÅÕ ÒÎ×ÅÊ (ÊÎÎÐÄÈÍÀÒÛ ABC), ÅÑËÈ ÑÏËÀÉÍÀ ÅÙÅ ÍÅÒ ÈËÈ 0, ÅÑËÈ ÑÏËÀÉÍ ÓÆÅ ÅÑÒÜ
    if pp==0 then ( --ÅÑËÈ ÏÎÑÒÓÏÀÅÒ 0, ÒÎ ÇÍÀ×ÈÒ ÑÏËÀÉÍ ÓÆÅ ÑÎÇÄÀÍ È ÌÀÑÑÈ ÍÀÄÎ ÇÀÏÎËÍÈÒÜ ÎÏÐÅÄÅËÅÍÍÛÌÈ ÊÎÎÐÄÈÍÀÒÀÌÈ ÂÅÐØÈÍ ÑÏËÀÉÍÀ
    pp=#(0,0,0) --ÑÏËÀÉÍ ÑÎÇÄÀÅÒÑß ÒÀÊÈÌ ÎÁÐÀÇÎÌ, ×ÒÎ ÍÎÌÅÐÀ ÂÅÐØÈÍ ÈÄÓÒ ÑÒÐÎÃÎ ÏÎ ÏÎÐßÄÊÓ È ÑÎÎÒÂÅÒÑÒÂÓÞÒ ÈÌÅÍÍÎ ÍÓÆÍÛÌ ÌÍÅ ÒÎ×ÊÀÌ
    pp[1]=getKnotPoint currentarchedspline 1 2 --ÒÎ×ÊÀ A
    pp[2]=getKnotPoint currentarchedspline 1 3 --ÒÎ×ÊÀ B
    pp[3]=getKnotPoint currentarchedspline 1 1 --ÒÎ×ÊÀ C
    )
    in coordsys world ( --ÐÀÑ×ÅÒ Â ÌÈÐÎÂÎÉ ÑÈÑÒÅÌÅ ÊÎÎÐÄÈÍÀÒ È ÍÅÂÀÆÅÍ ÏÎÐßÄÎÊ ÒÎ×ÅÊ ÎÑÍÎÂÀÍÈß, Ò.Å. ÌÎÆÍÎ È ABC È BAC
    ppc=(pp[1]+(pp[2]-pp[1])/2) --ÊÎÎÐÄÈÍÀÒÀ ÒÎ×ÊÈ O
    win_length=(distance pp[2] pp[1])/2 --ÏÎËÎÂÈÍÀ ÄËÈÍÛ AB
    v1=(pp[3]-ppc) --ÂÅÊÒÎÐ OC
    vx=normalize (pp[1]-ppc) --ÍÎÐÌÈÐÎÂÀÍÍÛÉ (ÄËÈÍÀ ÐÀÂÍÀ 1) ÂÅÊÒÎÐ OA, ÝÒÎ ÅÄÈÍÈ×ÍÛÉ ÂÅÊÒÎÐ ÎÑÈ x ÑÊ ÑÏËÀÉÍÀ
    vdot=dot v1 vx --ÄËÈÍÀ ÏÐÎÅÊÖÈÈ ÂÅÊÒÎÐÀ OC ÍÀ ÎÑÜ x
    pp4=ppc+vx*vdot --ÊÎÎÐÄÈÍÀÒÀ ÒÎ×ÊÈ N
    win_height=distance pp[3] pp4 --ÎÁÙÀß ÂÛÑÎÒÀ (ÐÀÑÑÒÎßÍÈÅ ÌÅÆÄÓ ÒÎ×ÊÀÌÈ C È N)
    vy=normalize (pp[3]-pp4) --ÍÎÐÌÈÐÎÂÀÍÍÛÉ ÂÅÊÒÎÐ NC, ÝÒÎ ÅÄÈÍÈ×ÍÛÉ ÂÅÊÒÎÐ ÎÑÈ y ÑÊ ÑÏËÀÉÍÀ
    vz=normalize (cross vx vy) --ÍÎÐÌÈÐÎÂÀÍÍÛÉ ÂÅÊÒÎÐ, ÏÅÐÏÅÍÄÈÊÓËßÐÍÛÉ ÎÑßÌ x È y, ÝÒÎ ÅÄÈÍÈ×ÍÛÉ ÂÅÊÒÎÐ ÎÑÈ z ÑÊ ÑÏËÀÉÍÀ
    m=matrix3 vx vy vz ppc --ÑÎÇÄÀÞ ÌÀÒÐÈÖÓ 4x3 ÈÇ ÏÎËÓ×ÅÍÍÛÕ ÅÄÈÍÈ×ÍÛÕ ÂÅÊÒÎÐÎÂ È ÊÎÎÐÄÈÍÀÒÛ ÖÅÍÒÐÀ
    )
    m --ÂÎÇÂÐÀÙÀÞ ÌÀÒÐÈÖÓ
)   
   
fn editarchedspline wLen wHei wARad wAHei = ( --ÍÀ ÂÕÎÄ ÔÓÍÊÖÈÈ ÏÎÑÒÓÏÀÞÒ 4 ÏÀÐÀÌÅÒÐÀ ÑÏËÀÉÍÀ
    l=wLen/2.0 --ÏÎËÎÂÈÍÀ ÎÑÍÎÂÀÍÈß
    anglealpha=asin(l/wARad) --ÏÎËÎÂÈÍÀ ÓÃËÀ ÄÓÃÈ
    arc_center=[0, wHei, 0]-[0, wARad, 0] --ÖÅÍÒÐ ÄÓÃÈ
       
    ca=arc pos: [0,0,0] radius: wARad from: (90-anglealpha) to: (90+anglealpha) --ÑÎÇÄÀÞ ÄÓÃÓ Ñ ÖÅÍÒÐÎÌ Â ÍÀ×ÀËÅ ÊÎÎÐÄÈÍÀÒ
    aw=SplineShape() --ÑÎÇÄÀÞ ÎÑÒÀÂØÓÞÑß ×ÀÑÒÜ ÑÏËÀÉÍÀ (ÏÅÐÅÂÅÐÍÓÒÀß ÁÓÊÂÀ Ï)
    addnewspline aw --ÄÎÁÀÂËßÞ ÍÎÂÛÉ ÑÏËÀÉÍ
    addKnot aw 1 #corner #line [-l, wHei-wAHei,0] --ÄÎÁÀÂËßÞ 1 ÂÅÐØÈÍÓ
    addKnot aw 1 #corner #line [-l,0,0] --ÄÎÁÀÂËßÞ 2 ÂÅÐØÈÍÓ
    addKnot aw 1 #corner #line [l,0,0] --ÄÎÁÀÂËßÞ 3 ÂÅÐØÈÍÓ
    addKnot aw 1 #corner #line [l, wHei-wAHei,0] --ÄÎÁÀÂËßÞ 4 ÂÅÐØÈÍÓ
    updateShape aw --ÎÁÍÎÂËßÞ ÑÏËÀÉÍ

    ca.pos=arc_center --ÏÅÐÅÌÅÙÀÞ ÄÓÃÓ Â ÖÅÍÒÐ
    convertToSplineShape ca --ÊÎÍÂÅÐÒÈÐÓÞ ÄÓÃÓ Â EDITABLE SPLINE
    addAndWeld aw ca 0.001 --ÏÐÈÑÎÅÄÈÍßÞ ÄÓÃÓ Ê ÑÏËÀÉÍÓ
    updateShape aw --ÎÁÍÎÂËßÞ ÑÏËÀÉÍ
    aw.wireColor=color 255 0 0 --ÇÀÄÀÞ ÊÐÀÑÍÛÉ ÖÂÅÒ ÄËß ÑÏËÀÉÍÀ (×ÒÎÁÛ ÍÅ ÌÎÐÃÀËÎ ÏÐÈ ÐÅÄÀÊÒÈÐÎÂÀÍÈÈ)
    setUserProp aw "Length" wLen --ÑÎÕÐÀÍßÞ ÏÀÐÀÌÅÒÐÛ Â ÑÂÎÉÑÒÂÀÕ ÎÁÚÅÊÒÀ
    setUserProp aw "Height" wHei --ÑÎÕÐÀÍßÞ ÏÀÐÀÌÅÒÐÛ Â ÑÂÎÉÑÒÂÀÕ ÎÁÚÅÊÒÀ
    setUserProp aw "ARadius" wARad --ÑÎÕÐÀÍßÞ ÏÀÐÀÌÅÒÐÛ Â ÑÂÎÉÑÒÂÀÕ ÎÁÚÅÊÒÀ
    setUserProp aw "AHeight" wAHei --ÑÎÕÐÀÍßÞ ÏÀÐÀÌÅÒÐÛ Â ÑÂÎÉÑÒÂÀÕ ÎÁÚÅÊÒÀ
   
    aw --ÂÎÇÂÐÀÙÀÞ ÑÏËÀÉÍ ÊÀÊ ÐÅÇÓËÜÒÀÒ ÔÓÍÊÖÈÈ
    )

--ÏÐÎÂÅÐÎ×ÍÛÉ ÊÎÄ
m=getcoordmatrix #([0,0,0], [100,100,0], [0 ,100,200])
currentarchedspline=editarchedspline 100 200 50 50
currentarchedspline.transform=m
--ÊÎÍÅÖ ÑÊÐÈÏÒÎÂÎÉ ×ÀÑÒÈ 1

Ñêîïèðóéòå â MAXScript/MAXScript Editor è âûïîëíèòå âûøåïðèâåäåííûé êîä - ñîçäàñòñÿ àðî÷íûé ñïëàéí ïî ïàðàìåòðàì â çàäàííîé ÑÊ.


Òåïåðü ñàìîå âðåìÿ çàíÿòüñÿ èíòåðôåéñîì ñêðèïòà.

Èíòåðôåéñ óäîáíåå âñåãî ñîçäàâàòü è ðåäàêòèðîâàòü ïðè ïîìîùè Visual MAXScript Editor (VME), íî ñîõðàíÿòü â îòäåëüíîì ôàéëå è ðåäàêòèðîâàòü îòäåëüíî (Tools/Edit Rollout), à ïîòîì êîïèðîâàòü â îáùèé ôàéë. Åñëè ðåäàêòèðîâàòü â îáùåì ôàéëå - ñóùåñòâóåò îïàñíîñòü óäàëåíèÿ èëè ìíîãîêðàòíîãî äóáëèðîâàíèÿ êîäà ñîáûòèé äëÿ ýëåìåíòîâ èíòåðôåéñà - ïîòîì çàìó÷àåòåñü ïðàâèòü. Èç-çà ýòîãî ãëþêà äàæå ñóùåñòâóåò ìíåíèå, ÷òî ëó÷øå íå èñïîëüçîâàòü VME è äåëàòü âñå ðó÷êàìè áåç GUI - ðàçìåùàòü ýëåìåíòû, äâèãàòü êíîïêè è ò.ä. ß ñîõðàíÿþ â îòäåëüíîì ôàéëå è íå èìåþ ïðîáëåì ñ èíòåðôåéñàìè è VME.
Çàïóñòèòå íèæåïðèâåäåííûé êîä - ýòî "÷èñòûé" èíòåðôåéñ, âîò òàêîé ìîæíî è íóæíî ñîõðàíÿòü îòäåëüíî, áåçáîëåçíåííî ðåäàêòèðîâàòü ïîñðåäñòâîì VME, à ïîòîì êîïèðîâàòü â êîä ñâèòêà, â êîòîðîì îïèñûâàþòñÿ ïåðåìåííûå, ôóíêöèè è ñîáûòèÿ ýëåìåíòîâ èíòåðôåéñà.



Èíòåðôåéñ
--ÑÊÐÈÏÒÎÂÀß ×ÀÑÒÜ 2
rollout floaterarchedspline "ArchedSpline 1.0" width:138 height:118
(
label lbl_fulllength "Full Length:" pos:[9,8] width:58 height:13
label lblfullheight "Full Height:" pos:[11,28] width:54 height:13
label lbl_archeight "Arc Height:" pos:[11,52] width:54 height:13
label lbl_arcradius "Arc Radius:" pos:[9,72] width:56 height:13

spinner spn_fulllength "" pos:[70,5] width:56 height:16 range:[0.001, 100000.0, 100.0] type:#float enabled: false
spinner spn_fullheight "" pos:[70,25] width:56 height:16 range:[0.001, 100000.0, 100.0] type:#float enabled: false
spinner spn_archeight "" pos:[70,49] width:56 height:16 range:[0.001, 100000.0, 100.0] type:#float enabled: false
spinner spn_arcradius "" pos:[70,69] width:56 height:16 range:[0.001, 100000.0, 100.0] type:#float enabled: false
checkbutton btn_create "Create" pos:[8,91] width:118 height:19 enabled: false checked: true
)
CreateDialog floaterarchedspline
--ÊÎÍÅÖ ÑÊÐÈÏÒÎÂÎÉ ×ÀÑÒÈ 2

Äîáàâëÿþ â èíòåðôåéñ äâå ôóíêöèè, ñ êîòîðûõ íà÷àë, ïèøó ñîáûòèÿ äëÿ ýëåìåíòîâ è ò.ä.
Êîä ñâèòêà:
--ÑÊÐÈÏÒÎÂÀß ×ÀÑÒÜ 3
rollout floaterarchedspline "ArchedSpline 1.0" width:138 height:118 --ÎÏÐÅÄÅËßÞ ÑÂÈÒÎÊ
(
--ÌÅÒÊÈ
label lbl_fulllength "Full Length:" pos:[9,8] width:58 height:13
label lblfullheight "Full Height:" pos:[11,28] width:54 height:13
label lbl_archeight "Arc Height:" pos:[11,52] width:54 height:13
label lbl_arcradius "Arc Radius:" pos:[9,72] width:56 height:13

--ÑÏÈÍÍÅÐÛ.  ÍÀ×ÀËÜÍÎÌ ÑÎÑÒÎßÍÈÈ ÈÕ ÈÇÌÅÍßÒÜ ÍÅËÜÇß (enabled: false), Ò.Ê. ÑÏËÀÉÍ ÑÎÇÄÀÅÒÑß ÏÎ ÒÐÅÌ ÒÎ×ÊÀÌ, À ÍÅ ÏÎ ÇÍÀ×ÅÍÈßÌ ÑÏÈÍÍÅÐÎÂ
spinner spn_fulllength "" pos:[70,5] width:56 height:16 range:[0.001, 100000.0, 100.0] type:#float enabled: false
spinner spn_fullheight "" pos:[70,25] width:56 height:16 range:[0.001, 100000.0, 100.0] type:#float enabled: false
spinner spn_archeight "" pos:[70,49] width:56 height:16 range:[0.001, 100000.0, 100.0] type:#float enabled: false
spinner spn_arcradius "" pos:[70,69] width:56 height:16 range:[0.001, 100000.0, 100.0] type:#float enabled: false
checkbutton btn_create "Create" pos:[8,91] width:118 height:19 enabled: false checked: true --ÊÍÎÏÊÀ-ÔËÀÆÎÊ, ÏÎ ÐÓÑÑÊÈ ÍÀÇÎÂÓ "ÂÊËÞ×ÀÒÅËÜ"

--ËÎÊÀËÜÍÛÅ ÏÅÐÅÌÅÍÍÛÅ
local isOpen=off --ÎÒÂÅ×ÀÅÒ ÇÀ ÑÎÑÒÎßÍÈÅ ÎÊÍÀ ÈÍÒÅÐÔÅÉÑÀ (ÎÒÊÐÛÒÎ/ÇÀÊÐÛÒÎ)
local currentarchedspline=0 --ÕÐÀÍÈÒ ÒÅÊÓÙÈÉ ÀÐÎ×ÍÛÉ ÑÏËÀÉÍ
local win_length, win_height --ÕÐÀÍßÒ ÄËÈÍÓ È ØÈÐÈÍÓ ÒÅÊÓÙÅÃÎ ÑÏËÀÉÍÀ

--ÔÓÍÊÖÈÈ, Ê ÊÎÒÎÐÛÌ ÁÓÄÓÒ ÎÁÐÀÙÀÒÜÑß ÝËÅÌÅÍÒÛ ÈÍÒÅÐÔÅÉÑÀ
fn onoffspinners arg = (--ÂÊËÞ×ÀÅÒ/ÂÛÊËÞ×ÀÅÒ ÂÎÇÌÎÆÍÎÑÒÜ ÐÅÄÀÊÒÈÐÎÂÀÍÈß ÑÏÈÍÍÅÐΠ ÇÀÂÈÑÈÌÎÑÒÈ ÎÒ ÀÐÃÓÌÅÍÒÀ
    floaterarchedspline.spn_fulllength.enabled=arg
    floaterarchedspline.spn_fullheight.enabled=arg
    floaterarchedspline.spn_arcradius.enabled=arg
    floaterarchedspline.spn_archeight.enabled=arg
    )
   
fn setcorrectvalues = (--ÎÁÍÎÂËßÅÒ ÇÍÀ×ÅÍÈß ÑÏÈÍÍÅÐΠ ÇÀÂÈÑÈÌÎÑÒÈ ÎÒ ÒÅÊÓÙÅÃÎ ÑÏËÀÉÍÀ
    if isValidNode currentarchedspline then (--ÅÑËÈ ÑÏËÀÉÍ ÅÑÒÜ
    floaterarchedspline.spn_fulllength.value=getUserProp currentarchedspline "Length"
    floaterarchedspline.spn_fullheight.value=getUserProp currentarchedspline "Height"
    floaterarchedspline.spn_arcradius.value=getUserProp currentarchedspline "ARadius"
    floaterarchedspline.spn_archeight.value=getUserProp currentarchedspline "AHeight"
    )
    )
   
fn editarchedspline wLen wHei wARad wAHei = ( --ÍÀ ÂÕÎÄ ÔÓÍÊÖÈÈ ÏÎÑÒÓÏÀÞÒ 4 ÏÀÐÀÌÅÒÐÀ ÑÏËÀÉÍÀ   
    l=wLen/2.0 --ÏÎËÎÂÈÍÀ ÎÑÍÎÂÀÍÈß
    anglealpha=asin(l/wARad) --ÏÎËÎÂÈÍÀ ÓÃËÀ ÄÓÃÈ
    arc_center=[0, wHei, 0]-[0, wARad, 0] --ÖÅÍÒÐ ÄÓÃÈ

    ca=arc pos: [0,0,0] radius: wARad from: (90-anglealpha) to: (90+anglealpha) --ÑÎÇÄÀÞ ÄÓÃÓ Ñ ÖÅÍÒÐÎÌ Â ÍÀ×ÀËÅ ÊÎÎÐÄÈÍÀÒ
    aw=SplineShape() --ÑÎÇÄÀÞ ÎÑÒÀÂØÓÞÑß ×ÀÑÒÜ ÑÏËÀÉÍÀ (ÏÅÐÅÂÅÐÍÓÒÀß ÁÓÊÂÀ Ï)
    addnewspline aw --ÄÎÁÀÂËßÞ ÍÎÂÛÉ ÑÏËÀÉÍ
    addKnot aw 1 #corner #line [-l, wHei-wAHei,0] --ÄÎÁÀÂËßÞ 1 ÂÅÐØÈÍÓ
    addKnot aw 1 #corner #line [-l,0,0] --ÄÎÁÀÂËßÞ 2 ÂÅÐØÈÍÓ
    addKnot aw 1 #corner #line [l,0,0] --ÄÎÁÀÂËßÞ 3 ÂÅÐØÈÍÓ
    addKnot aw 1 #corner #line [l, wHei-wAHei,0] --ÄÎÁÀÂËßÞ 4 ÂÅÐØÈÍÓ
    updateShape aw --ÎÁÍÎÂËßÞ ÑÏËÀÉÍ

    ca.pos=arc_center --ÏÅÐÅÌÅÙÀÞ ÄÓÃÓ Â ÖÅÍÒÐ
    convertToSplineShape ca --ÊÎÍÂÅÐÒÈÐÓÞ ÄÓÃÓ Â EDITABLE SPLINE
    addAndWeld aw ca 0.001 --ÏÐÈÑÎÅÄÈÍßÞ ÄÓÃÓ Ê ÑÏËÀÉÍÓ
    updateShape aw --ÎÁÍÎÂËßÞ ÑÏËÀÉÍ
    aw.wireColor=color 255 0 0 --ÇÀÄÀÞ ÊÐÀÑÍÛÉ ÖÂÅÒ ÄËß ÑÏËÀÉÍÀ (×ÒÎÁÛ ÍÅ ÌÎÐÃÀËÎ ÏÐÈ ÐÅÄÀÊÒÈÐÎÂÀÍÈÈ)
    setUserProp aw "Length" wLen --ÑÎÕÐÀÍßÞ ÏÀÐÀÌÅÒÐÛ Â ÑÂÎÉÑÒÂÀÕ ÎÁÚÅÊÒÀ
    setUserProp aw "Height" wHei --ÑÎÕÐÀÍßÞ ÏÀÐÀÌÅÒÐÛ Â ÑÂÎÉÑÒÂÀÕ ÎÁÚÅÊÒÀ
    setUserProp aw "ARadius" wARad --ÑÎÕÐÀÍßÞ ÏÀÐÀÌÅÒÐÛ Â ÑÂÎÉÑÒÂÀÕ ÎÁÚÅÊÒÀ
    setUserProp aw "AHeight" wAHei --ÑÎÕÐÀÍßÞ ÏÀÐÀÌÅÒÐÛ Â ÑÂÎÉÑÒÂÀÕ ÎÁÚÅÊÒÀ
    aw --ÂÎÇÂÐÀÙÀÞ ÑÏËÀÉÍ ÊÀÊ ÐÅÇÓËÜÒÀÒ ÔÓÍÊÖÈÈ
    )

fn getcoordmatrix pp = ( --ÍÀ ÂÕÎÄ ÔÓÍÊÖÈÈ ÏÎÑÒÓÏÀÅÒ ÌÀÑÑÈ ÈÇ ÒÐÅÕ ÒÎ×ÅÊ (ÊÎÎÐÄÈÍÀÒÛ ABC), ÅÑËÈ ÑÏËÀÉÍÀ ÅÙÅ ÍÅÒ ÈËÈ 0, ÅÑËÈ ÑÏËÀÉÍ ÓÆÅ ÅÑÒÜ
    if pp==0 then ( --ÅÑËÈ ÏÎÑÒÓÏÀÅÒ 0, ÒÎ ÇÍÀ×ÈÒ ÑÏËÀÉÍ ÓÆÅ ÑÎÇÄÀÍ È ÌÀÑÑÈ ÍÀÄÎ ÇÀÏÎËÍÈÒÜ ÎÏÐÅÄÅËÅÍÍÛÌÈ ÊÎÎÐÄÈÍÀÒÀÌÈ ÂÅÐØÈÍ ÑÏËÀÉÍÀ
    pp=#(0,0,0) --ÑÏËÀÉÍ ÑÎÇÄÀÅÒÑß ÒÀÊÈÌ ÎÁÐÀÇÎÌ, ×ÒÎ ÍÎÌÅÐÀ ÂÅÐØÈÍ ÈÄÓÒ ÑÒÐÎÃÎ ÏÎ ÏÎÐßÄÊÓ È ÑÎÎÒÂÅÒÑÒÂÓÞÒ ÈÌÅÍÍÎ ÍÓÆÍÛÌ ÌÍÅ ÒÎ×ÊÀÌ
    pp[1]=getKnotPoint currentarchedspline 1 2 --ÒÎ×ÊÀ A
    pp[2]=getKnotPoint currentarchedspline 1 3 --ÒÎ×ÊÀ B
    pp[3]=getKnotPoint currentarchedspline 1 1 --ÒÎ×ÊÀ C
    )
    in coordsys world ( --ÐÀÑ×ÅÒ Â ÌÈÐÎÂÎÉ ÑÈÑÒÅÌÅ ÊÎÎÐÄÈÍÀÒ È ÍÅÂÀÆÅÍ ÏÎÐßÄÎÊ ÒÎ×ÅÊ ÎÑÍÎÂÀÍÈß, Ò.Å. ÌÎÆÍÎ È ABC È BAC
    ppc=(pp[1]+(pp[2]-pp[1])/2) --ÊÎÎÐÄÈÍÀÒÀ ÒÎ×ÊÈ O
    win_length=(distance pp[2] pp[1])/2 --ÏÎËÎÂÈÍÀ ÄËÈÍÛ AB
    v1=(pp[3]-ppc) --ÂÅÊÒÎÐ OC
    vx=normalize (pp[1]-ppc) --ÍÎÐÌÈÐÎÂÀÍÍÛÉ (ÄËÈÍÀ ÐÀÂÍÀ 1) ÂÅÊÒÎÐ OA, ÝÒÎ ÅÄÈÍÈ×ÍÛÉ ÂÅÊÒÎÐ ÎÑÈ x ÑÊ ÑÏËÀÉÍÀ
    vdot=dot v1 vx --ÄËÈÍÀ ÏÐÎÅÊÖÈÈ ÂÅÊÒÎÐÀ OC ÍÀ ÎÑÜ x
    pp4=ppc+vx*vdot --ÊÎÎÐÄÈÍÀÒÀ ÒÎ×ÊÈ N
    win_height=distance pp[3] pp4 --ÎÁÙÀß ÂÛÑÎÒÀ (ÐÀÑÑÒÎßÍÈÅ ÌÅÆÄÓ ÒÎ×ÊÀÌÈ C È N)
    vy=normalize (pp[3]-pp4) --ÍÎÐÌÈÐÎÂÀÍÍÛÉ ÂÅÊÒÎÐ NC, ÝÒÎ ÅÄÈÍÈ×ÍÛÉ ÂÅÊÒÎÐ ÎÑÈ y ÑÊ ÑÏËÀÉÍÀ
    vz=normalize (cross vx vy) --ÍÎÐÌÈÐÎÂÀÍÍÛÉ ÂÅÊÒÎÐ, ÏÅÐÏÅÍÄÈÊÓËßÐÍÛÉ ÎÑßÌ x È y, ÝÒÎ ÅÄÈÍÈ×ÍÛÉ ÂÅÊÒÎÐ ÎÑÈ z ÑÊ ÑÏËÀÉÍÀ
    m=matrix3 vx vy vz ppc --ÑÎÇÄÀÞ ÌÀÒÐÈÖÓ 4x3 ÈÇ ÏÎËÓ×ÅÍÍÛÕ ÅÄÈÍÈ×ÍÛÕ ÂÅÊÒÎÐÎÂ È ÊÎÎÐÄÈÍÀÒÛ ÖÅÍÒÐÀ
    )
    m --ÂÎÇÂÐÀÙÀÞ ÌÀÒÐÈÖÓ
    )   
   
fn createarchedspline = ( --ÑÎÇÄÀÞ ÑÏËÀÉÍ   
    pp=#(0,0,0); checkpoints=0 --ÌÀÑÑÈ ÒÎ×ÅÊ È ÏÐÎÂÅÐÎ×ÍÀß ÏÅÐÅÌÅÍÍÀß
    for i=1 to 3 do ( --ÖÈÊË ÎÒ ÏÅÐÂÎÉ ÄÎ ÒÐÅÒÜÅÉ ÒÎ×ÊÈ
    t=case i of (
        1: " First "
        2: " Second "
        3: " Third "
        )
    txt="Pick"+ t+ "Point" --ËÞÁËÞ ÀÍÃËÈÉÑÊÈÉ :)
    floaterarchedspline.title=txt --ÌÅÍßÞ ÇÀÃÎËÎÂÎÊ ÎÊÍÀ ÄËß ÊÐÀÑÎÒÛ È ÏÎÍßÒÍÎÑÒÈ
    txt="\n"+txt --ÏÅ×ÀÒÀÞ Â ËÈÑÒÅÍÅÐ
   
    --ÓÊÀÇÛÂÀÞ ÏÅÐÂÓÞ ÒÎ×ÊÓ (ÌÎÆÍÎ ÙÅËÊÀÒÜ ÌÛØÊÎÉ Â ÎÊÍÀÕ ÏÐÎÅÊÖÈÈ, ÈËÈ ÇÀÄÀÂÀÒÜ ÊÎÎÐÄÈÍÀÒÛ Â ËÈÑÒÅÍÅÐÅ)
    if i==1 then point_pos = pickPoint prompt: txt snap: #3D
   
    --ÅÑËÈ 1 ÒÎ×ÊÀ ÎÏÐÅÄÅËÅÍÀ, ÒÎ ÁÅÐÓ ÂÒÎÐÓÞ ÒÎ×ÊÓ È ÂÅÄÓ ÏÓÍÊÒÈÐÍÓÞ ËÈÍÈÞ ÎÒ ÏÅÐÂÎÉ ÄÎ ÂÒÎÐÎÉ
    if i==2 and pp[1]!=0 then point_pos = pickPoint prompt: txt snap: #3D rubberBand: pp[1]
   
    --ÅÑËÈ 1 È 2 ÒÎ×ÊÈ ÎÏÐÅÄÅËÀÍÛ, ÒÎ ÁÅÐÓ ÒÐÅÒÜÞ ÒÎ×ÊÓ È ÂÅÄÓ ÏÓÍÊÒÈÐÍÓÞ ËÈÍÈÞ ÎÒ ÑÅÐÅÄÈÍÛ ÎÒÐÅÇÊÀ À ÄÎ ÒÐÅÒÜÅÉ
    if i==3 and pp[2]!=0 and pp[1]!=0 then point_pos = pickPoint prompt: txt snap: #3D rubberBand: (pp[1]+(pp[2]-pp[1])/2)
   
    --ÏÐÎÂÅÐÊÀ ÍÀ ÏÐÀÂÈËÜÍÎÑÒÜ ÒÎ×ÅÊ (ÍÅ ÎÒÌÅÍÈËÈ, ÍÅ ÙÅËÊÍÓËÈ ÏÐÀÂÎÉ ÊÍÎÏÊÎÉ - ÇÀÙÈÒÀ "ÎÒ ÄÓÐÀÊÀ")
    if (classOf point_pos)==Point3 then pp[i]=point_pos else checkpoints=1
    ) --ÊÎÍÅÖ ÖÈÊËÀ
   
    if checkpoints==0 then (--ÅÑËÈ ÂÑÅ ÒÐÈ ÒÎ×ÊÈ ÎÏÐÅÄÅËÅÍÛ, ÒÎ ÑÊÐÈÏÒ ÐÀÁÎÒÀÅÒ ÄÀËÜØÅ
    m=getcoordmatrix pp--ÏÎËÓ×ÀÞ ÌÀÒÐÈÖÓ, ÂÛÇÛÂÀß ÇÀÐÀÍÅÅ ÎÏÐÅÄÅËÅÍÍÓÞ ÔÓÍÊÖÈÞ (ÎÄÍÀ ÔÓÍÊÖÈß ÇÀÏÓÑÊÀÅÒÑß ÈÇ ÄÐÓÃÎÉ)
    l=win_length --ÏÎËÎÂÈÍÀ ÄËÈÍÛ ÀÂ
    h=win_length --ÂÛÑÎÒÀ ÀÐÊÈ ÏÎ ÓÌÎË×ÀÍÈÞ
    if win_height<win_length then win_height+=h --ÌÅÍßÞ ÂÛÑÎÒÓ ÄËß ÂÒÎÐÎÃÎ ÂÀÐÈÀÍÒÀ (ÑÌ. ÐÈÑ)
    win_radius=(l^2+h^2)/(2*h) --ÐÀÄÈÓÑ ÀÐÊÈ
    currentarchedspline=editarchedspline (distance pp[2] pp[1]) win_height win_radius h--ÑÎÇÄÀÞ ÑÏËÀÉÍ (ÎÄÍÀ ÔÓÍÊÖÈß ÇÀÏÓÑÊÀÅÒÑß ÈÇ ÄÐÓÃÎÉ)
    onoffspinners true--ÇÀÏÓÑÊÀÞ ÔÓÍÊÖÈÞ È ÒÅÏÅÐÜ ÌÎÆÍÎ ÌÅÍßÒÜ ÇÍÀ×ÅÍÈß ÑÏÈÍÍÅÐÎÂ
    currentarchedspline.transform=m --ÑÒÀÂËÞ ÑÏËÀÉÍ Â ÏÐÀÂÈËÜÍÎÅ ÌÅÑÒÎ
    )
    floaterarchedspline.btn_create.checked=false --ÎÒÆÈÌÀÞ ÊÍÎÏÊÓ È ÒÅÏÅÐÜ ÍÀ ÍÅÅ ÌÎÆÍÎ ÆÀÒÜ È ÑÎÇÄÀÂÀÒÜ ÍÎÂÛÉ ÑÏËÀÉÍ
    floaterarchedspline.title="ArchedSpline 1.0" --ÌÅÍßÞ ÇÀÃÎËÎÂÎÊ ÎÊÍÀ
)
--ÔÓÍÊÖÈÈ ÇÀÊÎÍ×ÈËÈÑÜ

--ÑÎÁÛÒÈß, ÊÎÒÎÐÛÅ ÂÛÏÎËÍßÞÒÑß Â ÈÍÒÅÐÔÅÉÑÅ
on floaterarchedspline open do ( --ÏÐÈ ÎÒÊÐÛÒÈÈ ÎÊÍÀ
    createarchedspline() --ÑÐÀÇÓ ÇÀÏÓÑÊÀÞ ÔÓÍÊÖÈÞ ÑÎÇÄÀÍÈß ÑÏËÀÉÍÀ
    setcorrectvalues() --ÎÁÍÎÂËßÞ ÑÏÈÍÍÅÐÛ
    btn_create.enabled=true --ÂÊËÞ×ÀÞ ÂÊËÞ×ÀÒÅËÜ
)
   
on btn_create changed arg do ( --ÅÑËÈ ÂÊËÞ×ÀÒÅËÜ ÍÀÆÈÌÀÅÒÑß
    onoffspinners false --ÍÅËÜÇß ÇÀÄÀÂÀÒÜ ÇÍÀ×ÅÍÈß ÑÏÈÍÍÅÐÎÂ
    createarchedspline() --ÑÎÇÄÀÞ ÑÏËÀÉÍ
    setcorrectvalues() --ÎÁÍÎÂËßÞ ÑÏÈÍÍÅÐÛ
    onoffspinners true --ÒÅÏÅÐÜ ÌÎÆÍÎ ÌÅÍßÒÜ ÇÍÀ×ÅÍÈß ÑÏÈÍÍÅÐÎÂ
    )
   
on spn_fulllength changed arg do if isValidNode currentarchedspline then (--ÏÐÈ ÈÇÌÅÍÅÍÈÈ ÄËÈÍÛ ÒÅÊÓÙÅÃÎ ÑÏËÀÉÍÀ
    if spn_archeight.value<=spn_arcradius.value then (--ÅÑËÈ ÍÅ ÂÛÕÎÄÈÒ ÇÀ ÏÐÅÄÅËÛ
    m=getcoordmatrix 0 --ÏÎËÓ×ÀÞ ÌÀÒÐÈÖÓ ÈÇ ÑÏËÀÉÍÀ
    win_height=getUserProp currentarchedspline "Height" --ÂÛÑÎÒÀ
    h=getUserProp currentarchedspline "AHeight" --ÂÛÑÎÒÀ ÀÐÊÈ
    l=arg/2 --ÏÎËÎÂÈÍÀ ÄËÈÍÛ
    win_radius=(l^2+h^2)/(2*h) --ÐÀÄÈÓÑ
    delete currentarchedspline --ÓÄÀËßÞ ÑÏËÀÉÍ
    currentarchedspline=editarchedspline arg win_height win_radius h --ÑÎÇÄÀÞ ÒÓÒ ÆÅ ÍÎÂÛÉ
    currentarchedspline.transform=m --ÑÒÀÂËÞ ÑÏËÀÉÍ ÍÀ ÌÅÑÒÎ
    )
    setcorrectvalues() --ÎÁÍÎÂËßÞ ÇÍÀ×ÅÍÈß ÑÏÈÍÍÅÐÎÂ
)
   
on spn_fullheight changed arg do if isValidNode currentarchedspline then (--ÏÐÈ ÈÇÌÅÍÅÍÈÈ ÂÛÑÎÒÛ ÒÅÊÓÙÅÃÎ ÑÏËÀÉÍÀ
    if arg>=spn_archeight.value then (--ÅÑËÈ ÍÅ ÂÛÕÎÄÈÒ ÇÀ ÏÐÅÄÅËÛ
    m=getcoordmatrix 0 --ÏÎËÓ×ÀÞ ÌÀÒÐÈÖÓ ÈÇ ÑÏËÀÉÍÀ
    win_length=getUserProp currentarchedspline "Length" --ÄËÈÍÀ
    win_radius=getUserProp currentarchedspline "ARadius" --ÐÀÄÈÓÑ ÀÐÊÈ
    h=getUserProp currentarchedspline "AHeight" --ÂÛÑÎÒÀ ÀÐÊÈ
    l=win_length/2 --ÏÎËÎÂÈÍÀ ÄËÈÍÛ
    delete currentarchedspline --ÓÄÀËßÞ ÑÏËÀÉÍ
    currentarchedspline=editarchedspline win_length arg win_radius h --ÑÎÇÄÀÞ ÍÎÂÛÉ
    currentarchedspline.transform=m --ÑÒÀÂËÞ ÑÏËÀÉÍ ÍÀ ÌÅÑÒÎ
    )
    setcorrectvalues() --ÎÁÍÎÂËßÞ ÑÏÈÍÍÅÐÛ
)

on spn_archeight changed arg do if isValidNode currentarchedspline then (--ÏÐÈ ÈÇÌÅÍÅÍÈÈ ÂÛÑÎÒÛ ÀÐÊÈ ÒÅÊÓÙÅÃÎ ÑÏËÀÉÍÀ
    if arg<=spn_arcradius.value then (--ÅÑËÈ ÍÅ ÂÛÕÎÄÈÒ ÇÀ ÏÐÅÄÅËÛ
    m=getcoordmatrix 0 --ÏÎËÓ×ÀÞ ÌÀÒÐÈÖÓ ÈÇ ÑÏËÀÉÍÀ
    win_length=getUserProp currentarchedspline "Length" --ÄËÈÍÀ
    win_height=getUserProp currentarchedspline "Height" --ÂÛÑÎÒÀ
    h=arg --ÂÛÑÎÒÀ ÀÐÊÈ
    l=win_length/2 --ÏÎËÎÂÈÍÀ ÄËÈÍÛ
    win_radius=(l^2+h^2)/(2*h) --ÐÀÄÈÓÑ ÀÐÊÈ
    delete currentarchedspline --ÓÄÀËßÞ ÑÏËÀÉÍ
    currentarchedspline=editarchedspline win_length win_height win_radius arg --ÑÎÇÄÀÞ ÍÎÂÛÉ
    currentarchedspline.transform=m --ÑÒÀÂËÞ ÍÀ ÌÅÑÒÎ
    )
    setcorrectvalues() --ÎÁÍÎÂËßÞ ÑÏÈÍÍÅÐÛ
)
   
on spn_arcradius changed arg do if isValidNode currentarchedspline then (--ÏÐÈ ÈÇÌÅÍÅÍÈÈ ÐÀÄÈÓÑÀ ÀÐÊÈ ÒÅÊÓÙÅÃÎ ÑÏËÀÉÍÀ
    if arg>=(spn_fulllength.value/2) then (--ÅÑËÈ ÍÅ ÂÛÕÎÄÈÒ ÇÀ ÏÐÅÄÅËÛ
    m=getcoordmatrix 0 --ÄÎÑÒÀÞ ÌÀÒÐÈÖÓ
    len=getUserProp currentarchedspline "Length" --ÄËÈÍÀ
    win_height=getUserProp currentarchedspline "Height" --ÂÛÑÎÒÀ
    l=len/2 --ÏÎËÎÂÈÍÀ ÄËÈÍÛ
    h=arg-sqrt(arg^2-l^2) --ÂÛÑÎÒÀ ÀÐÊÈ
    delete currentarchedspline --ÓÄÀËßÞ ÑÏËÀÉÍ
    currentarchedspline=editarchedspline len win_height arg h --ÑÎÇÄÀÞ ÍÎÂÛÉ
    currentarchedspline.transform=m --ÑÒÀÂËÞ ÍÀ ÌÅÑÒÎ
    )
    setcorrectvalues() --ÎÁÍÎÂËßÞ ÑÏÈÍÍÅÐÛ
)

)--ÑÂÈÒÎÊ ÃÎÒÎÂ
CreateDialog floaterarchedspline --ÑÎÇÄÀÞ ÑÂÈÒÎÊ
--ÊÎÍÅÖ ÑÊÐÈÏÒÎÂÎÉ ×ÀÑÒÈ 3

Îáðàòèòå âíèìàíèå, òî÷êè A B è C ìîæíî çàäàâàòü íå òîëüêî ùåëêàÿ ìûøêîé â îêíàõ ïðîåêöèé, íî è ââîäÿ àáñîëþòíûå èëè îòíîñèòåëüíûå êîîðäèíàòû â MAXScript Listener. Ôóíêöèÿ pickPoint ïîääåðæèâàåò äëÿ ýòîãî ñèíòàêñèñ êîìàíäíîé ñòðîêè AutoCAD.

Äî ôèíàëà îñòàëîñü ðåàëèçîâàòü ñëåäóþùåå:
I. Âîçìîæíîñòü ðåäàêòèðîâàíèÿ ëþáîãî àðî÷íîãî ñïëàéíà, â òîì ÷èñëå ïðè åãî âûáîðå êàæäûé ðàç îáíîâëÿòü ñïèííåðû èç ñâîéñòâ îáúåêòà (çäåñü íóæåí êîëëáýê).
II. Ñäåëàòü èç ñêðèïòà ìàêðîñêðèïò, ñ çàïîìèíàíèåì ïîëîæåíèÿ îêíà èíòåðôåéñà è êíîïêîé âêëþ÷åíèÿ/âûêëþ÷åíèÿ.
III. Íàðèñîâàòü êàðòèíêè íà êíîïêó ìàêðîñêðèïòà è íàïèñàòü readme ïî óñòàíîâêå (îò ýòîãî ÿ âàñ èçáàâëþ, ñäåëàþ ñàì :-D).

I. Ìåíÿþ ñêðèïòîâóþ ÷àñòü 3 ñëåäóþùèì îáðàçîì.

I.1. Äîáàâëÿþ íîâóþ ôóíêöèþ whenchangeselection

fn whenchangeselection = (--ÔÓÍÊÖÈß ÇÀÏÓÑÊÀÅÒÑß ÊÎËËÁÝÊÎÌ, ÊÎÃÄÀ ÌÅÍßÅÒÑß ÂÛÄÅËÅÍÈÅ
    --ÅÑËÈ ÂÛÄÅËÅÍ ÎÄÈÍ ÎÁÚÅÊÒ È Ó ÍÅÃÎ ÅÑÒÜ ÑÂÎÉÑÒÂÎ AHeight, ÒÎ ÒÅÊÓÙÈÉ ÀÐÎ×ÍÛÉ ÑÏËÀÉÍ ÈÌÅÅÒ ÌÅÑÒÎ ÁÛÒÜ È ß ÇÀÏÈÑÛÂÀÞ ÅÃÎ Â ÏÅÐÅÌÅÍÍÓÞ
    if selection.count==1 and (getUserProp selection[1] "AHeight")!=undefined then floaterarchedspline.currentarchedspline=selection[1]
    --ÅÑÒÜ ÑÏËÀÉÍ ÈËÈ ÍÅÒ, ÂÛÄÅËÅÍÎ ÁÎËÅÅ ÎÄÍÎÃÎ ÎÁÚÅÊÒÀ - ÂÑÅ ÐÀÂÍÎ ÇÀÏÈÑÛÂÀÞ ÇÍÀ×ÅÍÈÅ ÏÅÐÅÌÅÍÍÎÉ Â a
    a=floaterarchedspline.currentarchedspline
    if isValidNode a then (floaterarchedspline.setcorrectvalues() --ÅÑËÈ ÎÁÚÅÊÒ ÑÏËÀÉÍÀ ÅÑÒÜ, ÎÁÍÎÂËßÞ È ÂÊËÞ×ÀÞ ÑÏÈÍÍÅÐÛ
        floaterarchedspline.onoffspinners true
        )
    else (floaterarchedspline.currentarchedspline=0; floaterarchedspline.onoffspinners false) --ÅÑËÈ ÎÁÚÅÊÒÀ ÍÅÒ - ÎÒÊËÞ×ÀÞ ÑÏÈÍÍÅÐÛ È ÎÁÍÓËßÞ ÏÅÐÅÌÅÍÍÓÞ ÑÏËÀÉÍÀ
)


I.2. Èçìåíÿþ ñîáûòèå îòêðûòèÿ îêíà è äîáàâëÿþ íîâîå ñîáûòèå çàêðûòèÿ îêíà

on floaterarchedspline open do ( --ÏÐÈ ÎÒÊÐÛÒÈÈ ÎÊÍÀ
    isOpen=on --ÇÀÏÎÌÈÍÀÞ, ×ÒÎ ÎÊÍÎ ÎÒÊÐÛÂÀÅÒÑß
    if selection.count==1 and (getUserProp selection[1] "AHeight")!=undefined then ( --ÅÑËÈ ÊÀÊÎÉ-ÒÎ ÎÄÈÍ ÀÐÎ×ÍÛÉ ÑÏËÀÉÍ ÂÛÄÅËÅÍ
        currentarchedspline=selection[1] --ÑÎÕÐÀÍßÞ Â ÏÅÐÅÌÅÍÍÓÞ
        onoffspinners true --ÂÊËÞ×ÀÞ ÑÏÈÍÍÅÐÛ
        btn_create.checked=false --ÎÒÆÈÌÀÞ ÂÊËÞ×ÀÒÅËÜ, ×ÒÎÁÛ ÏÎÒÎÌ ÍÀ ÍÅÃÎ ÌÎÆÍÎ ÁÛËÎ ÍÀÆÀÒÜ È ÑÎÇÄÀÒÜ ÍÎÂÛÉ ÑÏËÀÉÍ
        )
        else createarchedspline() --ÈÍÀ×Å ÑÐÀÇÓ ÇÀÏÓÑÊÀÞ ÔÓÍÊÖÈÞ ÑÎÇÄÀÍÈß ÑÏËÀÉÍÀ
        setcorrectvalues() --ÎÁÍÎÂËßÞ ÑÏÈÍÍÅÐÛ
    btn_create.enabled=true --ÂÊËÞ×ÀÞ ÂÊËÞ×ÀÒÅËÜ
    callbacks.removeScripts #selectionSetChanged id: #AWINDOW --ÓÄÀËßÞ ÑÒÀÐÛÉ ÊÎËËÁÝÊ
   
    --ÄÎÁÀÂËßÞ ÊÎËËÁÝÊ, ÇÀÏÓÑÊÀÞÙÈÉ ÔÓÍÊÖÈÞ ÏÐÈ ÈÇÌÅÍÅÍÈÈ ÒÅÊÓÙÅÃÎ ÂÛÄÅËÅÍÈß
    callbacks.addscript #selectionSetChanged "floaterarchedspline.whenchangeselection()" id: #AWINDOW
)

on floaterarchedspline close do ( --ÏÐÈ ÇÀÊÐÛÒÈÈ ÎÊÍÀ
    isOpen=off --ÇÀÏÎÌÈÍÀÞ, ×ÒÎ ÎÊÍÎ ÇÀÊÐÛÂÀÅÒÑß
    archedsplinepos=GetDialogPos floaterarchedspline --ÇÀÏÎÌÈÍÀÞ ÏÎËÎÆÅÍÈÅ ÎÊÍÀ
    callbacks.removeScripts #selectionSetChanged id: #AWINDOW --ÓÄÀËßÞ ÊÎËËÁÝÊ
    updateToolbarButtons() --ÎÁÍÎÂËßÞ ÊÍÎÏÊÓ ÌÀÊÐÎÑÊÐÈÏÒÀ
)

I.3. Óäàëÿþ êîìàíäó "CreateDialog floaterarchedspline", íàõîäÿùóþñÿ íà ñëåäóþùåé ñòðîêå ïîñëå ñêîáêè è êîììåíòàðèÿ "--ÑÂÈÒÎÊ ÃÎÒÎÂ"

II. Ñîçäàþ íîâûé ôàéë ArchedSpline.mcr ñî ñëåäóþùèì ñîäåðæàíèåì:

--ÎÏÐÅÄÅËßÞ ÌÀÊÐÎÑÊÐÈÏÒ
macroScript ArchedSpline category:"ScriptAttack" tooltip:"ArchedSpline v1.0" Icon: #("ArchedSpline",1) --silentErrors: true
(
global floaterarchedspline --ÕÐÀÍÈÒ ÎÊÍÎ ÈÍÒÅÐÔÅÉÑÀ
global archedsplinepos=[100,100] --ÇÀÏÎÌÈÍÀÅÒ ÏÎËÎÆÅÍÈÅ ÎÊÍÀ
   
on ischecked return try(execute "floaterarchedspline.isOpen")catch(off) --ÂÛÊËÞ×ÀÞ, ÅÑËÈ ÂÊËÞ×ÅÍÎ È ÍÀÎÁÎÐÎÒ.
on execute do (--ÇÀÏÓÑÊ ÑÊÐÈÏÒÀ
if (floaterarchedspline == undefined) then (--ÅÑËÈ ÎÊÍÀ ÑÊÐÈÏÒÀ ÍÅÒ ÍÀ ÝÊÐÀÍÅ, ÒÎ ÑÎÇÄÀÞ ÅÃÎ ÑÎ ÂÑÅÌÈ ÂÛÒÅÊÀÞÙÈÌÈ

--ÑÞÄÀ ÂÑÒÀÂËßÞ ÈÑÏÐÀÂËÅÍÍÓÞ ÑÊÐÈÏÒÎÂÓÞ ×ÀÑÒÜ 3

updateToolbarButtons() --ÎÁÍÎÂËßÞ ÊÍÎÏÊÓ ÌÀÊÐÎÑÊÐÈÏÒÀ
)
--ÅÑËÈ ÎÊÍÎ ÎÒÊÐÛÒÎ È ÍÀÆÀËÈ ÊÍÎÏÊÓ ÌÀÊÐÎÑÊÐÈÏÒÀ, ÒÎ ÇÀÏÎÌÈÍÀÞ ÏÎËÎÆÅÍÈÅ ÎÊÍÀ, ÓÄÀËßÞ ÅÃÎ È ÂÛÊËÞ×ÀÞ ÊÍÎÏÊÓ.
if floaterarchedspline.isOpen then (archedsplinepos=GetDialogPos floaterarchedspline; destroyDialog floaterarchedspline; updateToolbarButtons())
else CreateDialog floaterarchedspline pos: archedsplinepos --ÅÑËÈ ÎÊÍÎ ÇÀÊÐÛÒÎ - ÑÎÇÄÀÞ ÅÃÎ È ÑÊÐÈÏÒ ÇÀÏÓÑÊÀÅÒÑß
) --ÊÎÍÅÖ ÇÀÏÓÑÊÀ ÑÊÐÈÏÒÀ (execute)
) --ÊÎÍÅÖ ÌÀÊÐÎÑÊÐÈÏÒÀ

III. Ñêà÷àòü ãîòîâûé ñêðèïò


Íó âîò è âñå óðîê îêîí÷åí, íà ñëàäêîå îïèøó áàãè è íåäîñòàòêè ArchedSpline:

1. Íåò ïðîâåðêè òî÷åê A B C íà ïðèíàäëåæíîñòü îäíîé êîíêðåòíîé ïëîñêîñòè, ò.å. åñëè òî÷êè áóäóò ëåæàòü íà îäíîé ëèíèè - ñêðèïò âûäàñò èëè îøèáêó èëè ñïëàéí â íåïîéìè êàêîé ñèñòåìå êîîðäèíàò. Êòî çàõî÷åò - ìîæåò âíåäðèòü ïðîâåðêó ñàìîñòîÿòåëüíî (äîëæíà áûòü íåíóëåâàÿ äëèíà âåêòîðà AB è íåíóëåâîé ñèíóñ óãëà ìåæäó âåêòîðàìè AB è AC).

2. Èíîãäà ïðè èçìåíåíèè îáùåé âûñîòû äóãà ïðîïàäàåò (ïî÷åìó - íå ÿñíî, ì.á ãëþê ìàêñà) - â ýòîì ñëó÷àå íóæíî ïðîñòî "ïîäåðãàòü" çà êàêîé-òî äðóãîé ïàðàìåòð.

3. Ïðè óìåíüøåíèè âûñîòû äóãè äî íóëÿ - äóãà âûðîæäàåòñÿ â ïðÿìóþ ëèíèþ, â ýòîì ñëó÷àå íóæíî óâåëè÷èòü âûñîòó äóãè èëè óìåíüøèòü ðàäèóñ.

4. Íåëüçÿ ñðàçó ñîçäàòü ëþáîé ñïëàéí ïî íóæíûì ïàðàìåòðàì, íî ñêðèïòå èçíà÷àëüíî òàê è íå ïëàíèðîâàëîñü, çàòî ìîæíî ìîìåíòàëüíî ñòàâèòü â ïðàâèëüíóþ ñèñòåìó êîîðäèíàò, à ïîòîì ðåäàêòèðîâàòü è êîïèðîâàòü, åñëè ýòî íåîáõîäèìî.

5. Íåëüçÿ èçìåíÿòü ðàçîì ïàðàìåòðû íåñêîëüêèõ ñïëàéíîâ (òîæå èçíà÷àëüíî íå ïëàíèðîâàëîñü è âîîáùå ãîâîðÿ äëÿ ýòîãî ó ìåíÿ åñòü äðóãîé ñêðèïò).