require 'plot numeric gl2' coinsert 'jgl2' NB. ========================================================= NB. Bezier curves NB. written by SHIMURA Masato Oct/2012 NB. Email: jcd02773@nifty.ne.jp NB. --------------------------------------------------------- NB. Usage: NB. * calc_bezier4 L0 NB. * calculus_bezier4 L0,L1 NB. * 3 calculus_bezier L4 NB. * 4 plot_bezier L0 // L4 NB. * 4 3 5 calculus_bezier_mix L4 NB. * 4 3 5 plot_bezier_mix L4 NB. * 4 hokusai0_run RA NB. ---0.----BezierMatrixForm------------------------- mat_bezier4=: 1 0 0 0,_3 3 0 0,3 _6 3 0,:_1 3 _3 1 NB.Cubic BezierMatrixForm mat_bezier3=: 1 0 0 , _2 2 0,: 1 _2 1 mat_bezier2=: 1 0,: _1 1 NB. bezier2 is linear & divide[0 1] by steps NB. ------5/6 is Kato's triangle------------------------------- mat_bezier5=: 1 0 0 0 0 ,_4 4 0 0 0, 6 _12 6 0 0 ,_4 12 _12 4 0,:1 _4 6 _4 1 mat_bezier6=: 1 0 0 0 0 0,_5 5 0 0 0 0 , 10 _20 10 0 0 0 ,: _10 30 _30 10 0 0 mat_bezier6=: mat_bezier6, 5 _20 30 _20 5 0,: _1 5 _10 10 _5 1 NB. ----1 calc single 2/3/4/5/6 points bezier------------------------------------------------------------ NB. modify steps yourself e.g. stepd (0 1), 100 calc_bezier4=: 3 : '(|: mat_bezier4 +/ . * y)&p. " 0 steps 0 1 20' calc_bezier40=:3 : '(|: mat_bezier4 +/ . * y)&p. " 0 steps 0 1 10' NB. for test calc_bezier3=: 3 : '(|: mat_bezier3 +/ . * y)&p. " 0 steps 0 1 20' calc_bezier2=: 3 : '(|: mat_bezier2 +/ . * y)&p. " 0 steps 0 1 20' calc_bezier5=: 3 : '(|: mat_bezier5 +/ . * y)&p. " 0 steps 0 1 20' calc_bezier6=: 3 : '(|: mat_bezier6 +/ . * y)&p. " 0 steps 0 1 20' NB. original cubic_bezier script calc_bezier4p1=: 3 : 0 NB. cubic Bezier NB. Usage: (short) calc_bezier4 L0 tmp0=. |: mat_bezier4 +/ . * y fx=. ({. tmp0)&p. fy=. ({: tmp0)&p. fx0=. fx steps 0 1 20 NB. divede [0,1] for smooth Bezier curves fy0=. fy steps 0 1 20 fx0,.fy0 ) NB. --2---main calc Bezier long data------------------------------ calculus_bezier4=: 3 : ';("1) calc_bezier4 (L:0) 4 form_bezier y' calculus_bezier3=: 3 : ';("1) calc_bezier3 (L:0) 3 form_bezier y' calculus_bezier2=: 3 : ';("1) calc_bezier2 (L:0) 2 form_bezier y' calculus_bezier5=: 3 : ';("1) calc_bezier5 (L:0) 5 form_bezier y' calculus_bezier6=: 3 : ';("1) calc_bezier6 (L:0) 6 form_bezier y' calculus_bezier=: 4 : 0 NB. Long data NB. x is same plot_bezier0 select. x case. 4 do. tmp=. calculus_bezier4 y NB. cubic bezier case. 3 do. tmp=. calculus_bezier3 y case. 2 do. tmp=. calculus_bezier2 y NB. linear line case. 5 do. tmp=. calculus_bezier5 y case. 6 do. tmp=. calculus_bezier6 y end. ) NB. ---3.----form for long data----------------------- form_bezier =: 4 : '(}: tmp), L:0 }.{. L:0 tmp=.(- <: x)<\ y' NB. ---3-1--mixed form------------------------------------------ form_bezier_mix=: 4 : 0 NB. 2 3 4 form_bezier_mix L0,L1,L2 index=. ;* L:0({@> x),L:0 (<:@<:L:0 {@>x ) #(L:0) 0 NB. set 3/4 of 1 0 0 (0) index=. index , 1 NB. add 1 to tail tmp=. (>: +/ <: x ){. y NB. set same length tmp2=. index <;.1 tmp NB. cut by index (}: tmp2), L:0 (}. {. L:0 tmp2) NB. overlaped one ) NB. --4 calc mixed form-------------------------------------------------- calc_bezier_mix=: 4 : 0 NB. 4 3 5 6 calc_bezier_mix L0,L1,L2,L3,L0 mixform=. x form_bezier_mix y num=. x NB. ; # L:0 mixform ANS=. <'' for_ctr. i. # num do. ind=. ctr { num select. ind case. 4 do. tmp=. calc_bezier4 L:0 ctr { mixform case. 3 do. tmp=. calc_bezier3 L:0 ctr { mixform case. 2 do. tmp=. calc_bezier2 L:0 ctr { mixform case. 5 do. tmp=. calc_bezier5 L:0 ctr { mixform case. 6 do. tmp=. calc_bezier6 L:0 ctr { mixform end. ANS=. ANS,tmp end. ;("2) ,. }. ANS NB. formed for graphics ) calculus_bezier_mix=: 4 : 0 NB. Usage(normal use):4 5 3 calculus_bezier_mix L0,L1,L2 ;"2 ,.({@> x) calc_bezier_mix (L:0) x form_bezier_mix y ) NB. ---4 plot------------------------------ plot_bezier=: 4 : 0 NB. Usage: 4 plot_bezier L0,L2 NB. could use for singleton L0 tmp1=. x calculus_bezier y tmp0=. ((<:x)*i. >.( # y)%3){ y pd 'reset' pd 'type line' pd {@|: y pd 'color 128 128 128' pd 'type marker' pd {@|: tmp0 pd 'type line' pd 'color red' pd {@|: tmp1 pd 'show' ) plot_bezier_mix=: 4 : 0 NB. calc_bezier4 plot_line_once OOI0;OOI1 NB. 64 is */ 2 2 4 4 // find singleton 3/4 raw NB. if.36 64 e. */2# $ y do. y =. < y end. NB. single--> box tmp0=. x calculus_bezier_mix y pd 'reset' pd 'type line;color blue' pd {@|: y pd 'type line;color red' pd {@|: tmp0 pd 'color blue;type marker' pd {@|: (+/\ 0,<:x){y pd 'show' ) NB.******************************* NB. ===5============================================== NB. another Bezier style NB. program Bernstein form directly NB. 3 order <---> 4 Points b4_0=: (^&3@-.);(3&* * ^&2@-.);(*&3@^&2 * -.);^&3 b4=: 3 : 0 NB. +/(b3 steps 0 1 10)* "0 1 EXG NB. b4 EXG t0=. ;"1 ,. b4_0 steps 0 1 10 +/ t0 * "0 1 y ) NB. Usage: (b4_long L0,3+L1),. calculus_bezier4 L0,3+L1 b4_long=: 3 : ';"2,. b4 (L:0) 4 form_bezier y' NB. ---5-1------------------------------------ NB. another quadratic b5_0=: (^&4@-.);(4&* * ^&3@-.);(*&6@^&2 * ^&2@-.);(*&4@^&3 * -. );^&4 b5=: 3 : 0 NB. +/(b3 steps 0 1 10)* "0 1 EXG NB. b4 EXG t0=. ;"1 ,. b5_0 steps 0 1 20 +/ t0 * "0 1 y ) b5_long=: 3 : ';"2,. b5 (L:0) 5 form_bezier y' NB. --6.-example data------------------- L0=: 0 1,1 2,2 2,:3 1 L1=: 0 1,1 3,2 4,:4 2 L2=: 0 1,3 1,2 4,:4 2 L3=: 0 1,4 2,2 4,:1 0 L4=: L0,4 2,5 3,4 6, 5 7,6 4,:7 6 NB. Hokusai No29 らの字 RANOJI0=: (1.5 9),3 8.8 , 1.8 8 ,(1.8 7),2.2 5.5,3 5 ,:(3.5 6.8) NB. 0/1/2 RANOJI0=: RANOJI0, 6 11,8 5.5 ,(4.2 4),1.5 3 ,4.5 7.5 ,:(4 2.8) NB. (2)/3/4/5 RANOJI0=: RANOJI0, 3.8 2.4 ,2.9 1.8 ,(3 1.5), 3.1 1.1 , 3.5 0.8,: (4 0.5) NB. 6/7 NB. ---7. isigraph------------------------------------- NB. usage: 4 hokusai0_run RA HOKUSAI0=: 0 : 0 pc hokusai0; xywh 0 0 200 200;cc hokusai0 isigraph; pas 6 6;pcenter; rem form end; ) hokusai0_run=: 4 : 0 wd HOKUSAI0 NB. initialize form here x draw_hokusai y wd 'pshow;' ) hokusai0_close=: 3 : 0 wd'pclose' ) draw_hokusai=: 4 : 0 'tmp0 tmp1'=. x fit_bezier_screen y NB. ---------------------------- glrgb 0 0 255 glpen 2,PS_SOLID gllines , tmp0 glrgb 255 0 0 glpen 2,PS_SOLID gllines , tmp1 glpaint '' ) NB. rotm=: (cos, sin,0:),(-@sin,cos,0:),: 0: ,0:,1: rotx0=: (1:,0:,0:), (0:,cos, sin),:(0:,-@sin,cos) rotx=: 3 : ' }:"1 (y,.1) +/ . * rotx0 1p1' compose_rotx0=: 3 : 0 tmp=. rotx y NB. RANOJI0 u 1p1 sign=. * min=. <./ tmp if. _1 = {: sign do. tmp=. ( 0, - {: min) +"1 tmp end. tmp ) compose_bezier_rotx=: 4 : 0 NB. compare bezier origin tmp0=. rotx y tmp1=. rotx x calculus_bezier y sign=. * +/ min=. ({:<./ tmp1 ) ,{:<./ tmp0 if. _1 = sign do. min=. <./ min tmp0=. (0,- min) +"1 tmp0 tmp1=. (0,- min)+"1 tmp1 end. tmp0;tmp1 ) minmax=: <./ ; >./ fit_bezier_screen=: 4 : 0 'tmp0 tmp1'=: x compose_bezier_rotx y NB. SCREEN=: 200 200 tmp2=. minmax tmp1 SIZE=.>./ (>{: tmp1) - >{. tmp1 TIMES=: +: >. 100 % SIZE ROCATION=:2# 100- TIMES (ROCATION +"1 TIMES * tmp0); ROCATION +"1 TIMES * tmp1 ) NB. -------------------------- NB. 菱割り(らの字)N0. 59 NB. diamond divide RA=: (1.5 9),3 8.8 , 1.8 8 ,(1.8 7),2.2 5.5,3 5 ,:(3.5 6.8) NB. 0/1/2 RA=: RA, 6 11,8 5.5 ,(4.2 4),1.5 3 ,4.5 7.5 ,:(4 2.8) NB. (2)/3/4/5 RA=: RA, 3.8 2.4 ,2.9 1.8 ,(3 1.5), 3.1 1.1 , 3.5 0.8,: (4 0.5) NB. 6/7 NB. EOF.