GLE Example: curvedarrow.gle
[PDF file]
size 15 7.5 include "shape.gle" ! extra space between rows in LaTeX table (on the right) begin texpreamble \usepackage{tabls} \setlength{\tablinesep}{0.3cm} end texpreamble ! draw tiny dotted lines between point and corresponding label sub hair_line dx dy gsave set lwidth 0.0125 lstyle 2 rline dx dy grestore rmove dx dy end sub ! draw a small circle filled yellow sub yellow_circle x y amove x y circle 0.075 fill yellow end sub ! set the opening angle and size of the arrow sub set_arr_angle_size ang siz tan_alpha = tan(torad(ang)) arr_angle = ang arr_size = siz end sub ! get the value of "t1" given the arrow length sub get_delta_theta arrlen side = arrlen * cos(torad(arr_angle)) return todeg(side/r) end sub ! evaluate a degree 5 polynomial sub ev5 a5 a4 a3 a2 a1 a0 x return a5*x^5 + a4*x^4 + a3*x^3 + a2*x^2 + a1*x + a0 end sub ! evaluate the first derivative of a degree 5 polynomial sub ev5p a5 a4 a3 a2 a1 a0 x return 5*a5*x^4 + 4*a4*x^3 + 3*a3*x^2 + 2*a2*x + a1 end sub ! compute the norm of a given vector sub norm x1 y1 return sqrt(x1^2+y1^2) end sub ! compute the x-coordinate of a point on the arrow side sub ax t0 t pm return (1+pm*(t-t0)*tan_alpha)*r*cos(t) end sub ! compute the y-coordinate of a point on the arrow side sub ay t0 t pm return (1+pm*(t-t0)*tan_alpha)*r*sin(t) end sub ! compute the first derivative of the x-coordinate of the arrow side sub apx t0 t pm return r*(-sin(t)+pm*tan_alpha*(cos(t)-t*sin(t)+t0*sin(t))) end sub ! compute the first derivative of the y-coordinate of the arrow side sub apy t0 t pm return r*(cos(t)+pm*tan_alpha*(sin(t)+t*cos(t)-t0*cos(t))) end sub ! normalized first derivative of the x-coord of the arrow side sub apx_norm t0 t pm pm2 local tx = apx(t0,t,pm2) local ty = apy(t0,t,pm2) local d = norm(tx,ty) return pm*tx/d end sub ! normalized first derivative of the y-coord of the arrow side sub apy_norm t0 t pm pm2 local tx = apx(t0,t,pm2) local ty = apy(t0,t,pm2) local d = norm(tx,ty) return pm*ty/d end sub ! compute a bezier curve through a given point ! assume two control points at same distance from the end points sub bezier_slope_pt x0 y0 dx1 dy1 dx2 dy2 x3 y3 xp yp local a = xp - x0 local b = 3*(x0-x3) local c = 2*(x3-x0) local d = dx1 local e = dx2 - 2*dx1 local f = dx1 - dx2 local g = yp - y0 local h = 3*(y0-y3) local i = 2*(y3-y0) local j = dy1 local k = dy2 - 2*dy1 local l = dy1 - dy2 local a5 = c*l - i*f local a4 = c*k + b*l - i*e - h*f local a3 = c*j + b*k - i*d - h*e local a2 = b*j + a*l - h*d - g*f local a1 = a*k - g*e local a0 = a*j - g*d local t = 0.5 local tp = 0 while abs(t-tp) > 1e-6 tp = t t = t - ev5(a5,a4,a3,a2,a1,a0,t)/ev5p(a5,a4,a3,a2,a1,a0,t) next local aa = (a + b*t^2 + c*t^3)/(d + e*t + f*t^2)/(3*t) asetpos x0 y0 bezier x0+aa*dx1 y0+aa*dy1 x3+aa*dx2 y3+aa*dy2 x3 y3 return aa end sub ! draw the curved arrow head sub curved_arrow_head x0 y0 a1 a2 deco outline t0 = torad(a1) tm = torad((a1 + a2)/2) t1 = torad(a2) ! top side (pm = +1) local dx11 = apx_norm(t0,t1,-1,+1) local dy11 = apy_norm(t0,t1,-1,+1) local dx21 = apx_norm(t0,t0,+1,+1) local dy21 = apy_norm(t0,t0,+1,+1) local x01 = ax(t0,t1,+1) + x0 local y01 = ay(t0,t1,+1) + y0 local x31 = ax(t0,t0,+1) + x0 local y31 = ay(t0,t0,+1) + y0 local xp1 = ax(t0,tm,+1) + x0 local yp1 = ay(t0,tm,+1) + y0 ! bottom side (pm = -1) local dx12 = apx_norm(t0,t0,+1,-1) local dy12 = apy_norm(t0,t0,+1,-1) local dx22 = apx_norm(t0,t1,-1,-1) local dy22 = apy_norm(t0,t1,-1,-1) local x02 = ax(t0,t0,-1) + x0 local y02 = ay(t0,t0,-1) + y0 local x32 = ax(t0,t1,-1) + x0 local y32 = ay(t0,t1,-1) + y0 local xp2 = ax(t0,tm,-1) + x0 local yp2 = ay(t0,tm,-1) + y0 ! only draw the outline or fill it in green? if outline = 1 then begin path stroke local aa1 = bezier_slope_pt(x01,y01,dx11,dy11,dx21,dy21,x31,y31,xp1,yp1) local aa2 = bezier_slope_pt(x02,y02,dx12,dy12,dx22,dy22,x32,y32,xp2,yp2) closepath end path else print "dx1 " dx11 " dy1 " dy11 " dx2 " dx21 " dy2 " dy21 begin path fill forestgreen local aa1 = bezier_slope_pt(x01,y01,dx11,dy11,dx21,dy21,x31,y31,xp1,yp1) local aa2 = bezier_slope_pt(x02,y02,dx12,dy12,dx22,dy22,x32,y32,xp2,yp2) closepath end path end if ! draw decorations? if deco = 1 then gsave set color black lwidth 0.025 amove x01 y01 aline x32 y32 amove xp1 yp1 aline xp2 yp2 yellow_circle x01 y01 yellow_circle xp1 yp1 yellow_circle x32 y32 yellow_circle xp2 yp2 set color red amove x01 y01 aline x01+dx11*aa1 y01+dy11*aa1 amove x31 y31 aline x31+dx21*aa1 y31+dy21*aa1 amove x02 y02 aline x02+dx12*aa2 y02+dy12*aa2 amove x32 y32 aline x32+dx22*aa2 y32+dy22*aa2 grestore end if ! name some crucial points on the arrow head amove x0+r*cos(torad(a2)) y0+r*sin(torad(a2)) save tcenter rmove -2*sin(torad(a2)) 2*cos(torad(a2)) save ttangent amove x01 y01 save tnormal amove x31 y31 save btip end sub ! some general settings set lwidth 0.1 join mitre set_arr_angle_size 20 2.75 a1 = 20 r = +8 x0 = -3 y0 = -1 ! draw a line at angle 20 degrees amove x0 y0 aline x0+(r+3.2)*cos(torad(a1)) y0+(r+3.2)*sin(torad(a1)) ! draw the first arc amove x0 y0 arc r a1 90 ! draw the arc's arrow head a2 = a1+get_delta_theta(2.75) curved_arrow_head x0 y0 a1 a2 1 0 ! draw another arc and arrow head r = +10.25 set color black amove x0 y0 arc r a1 90 set lwidth 0.03 a2 = a1+get_delta_theta(2.75) curved_arrow_head x0 y0 a1 a2 0 1 ! draw the math equation of the curve yellow_circle x0+r*cos(torad(53)) y0+r*sin(torad(53)) hair_line 0.3 0 set just lc arrowsize 0.15 arrowangle 25 hei 0.25 tex "$c(t) = (x(t),y(t))$" ! annotate with the "tangent" set color red amove ptx(tcenter) pty(tcenter) aline ptx(ttangent) pty(ttangent) arrow end rmove 0.2 0 set color black tex "$\vec{T}(c(t_1))$" nx = ptx(tnormal)-ptx(tcenter) ny = pty(tnormal)-pty(tcenter) d = norm(nx,ny) nx = nx/d; ny = ny/d ! annotate with the "normal" set color red amove ptx(tcenter) pty(tcenter) aline ptx(tcenter)+nx*2 pty(tcenter)+ny*2 arrow end rmove 0.05 0 set color black tex "$\vec{N}(c(t_1))$" ! annotate with the distance along the arc set color red amove x0 y0 d = 0.6 arc r+d a1 a2 arrow both set color black amove x0+(r+d)*cos(torad((a1+a2)/2))+0.1 y0+(r+d)*sin(torad((a1+a2)/2)) tex "$d(c(t),t_0,t_1)$" ! annotate with the height gsave set lwidth 0.0125 just bc curly_bracket ptx(tcenter) pty(tcenter) ptx(tnormal) pty(tnormal) 0.12 amove (ptx(tcenter)+ptx(tnormal))/2-0.25 (pty(tcenter)+pty(tnormal))/2+0.25 tex "$h(t_1)$" grestore ! indicate points t0 and t1 on the arrow head yellow_circle ptx(btip) pty(btip) hair_line 0 -0.3 set just tc tex "$c(t_0)$" yellow_circle ptx(tcenter) pty(tcenter) hair_line -0.3 0 set just rc tex "$c(t_1)$" yellow_circle ptx(tnormal) pty(tnormal) hair_line 0.3 0 set just lc tex "$a(t_1)$" ! add all mathematical equations set just tr amove pagewidth()-0.2 pageheight()-0.2 begin box add 0.1 fill rgb255(240,240,240) round 0.2 begin tex \begin{tabular}{l} $c(t) = (r\cos{t},r\sin{t})$\\ $\vec{T}(c(t)) = \frac{c'(t)}{||c'(t)||} = (-\sin{t},\cos{t})$ \\ $\vec{N}(c(t)) = (\vec{T_y}(c(t)), -\vec{T_x}(c(t))) = (\cos{t},\sin{t})$\\ $d(c(u),t_0,t) = r\cdot(t-t_0)$\\ $h(t) = d(c(u),t_0,t)\cdot\tan{\alpha}$\\ $a(t) = c(t) \pm h(t) \cdot \vec{N}(c(t))$\\ $a_x(t) = (1 \pm (t-t_0)\tan{\alpha}) r \cos{t}$\\ $a_y(t) = (1 \pm (t-t_0)\tan{\alpha}) r \sin{t}$\\ \end{tabular} end tex end box ! test the arrow functions from GLE set arrowsize 0.3 arrowangle 15 amove 0.25 2 aline 2.25 2 amove 1.25 3 aline 1.25 1 amove 1.25 2 set arrowstyle filled arc 0.75 0 90 arrow both arc 0.75 180 270 arrow both set arrowstyle empty arc 0.75 90 180 arrow both arc 0.75 270 0 arrow both
[Return to examples page]