Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.
|
Forum Index : Microcontroller and PC projects : MM2: 4.7b Bezier curves
Author | Message | ||||
matherp Guru Joined: 11/12/2012 Location: United KingdomPosts: 8592 |
One of the new features in 4.7b8 is the ability to work with floating point numbers inside Cfunctions. The attached example wouldn't have been possible previously option default none option explicit dim integer i timer=0 i=bezier(10,10,106,80,212,80,309,10,rgb(yellow)) i=bezier(10,230,106,150,212,150,309,230,rgb(yellow)) i=bezier(10,10,80,80,80,160,10,230,rgb(green)) i=bezier(309,10,239,80,239,160,309,230,rgb(green)) text 85,110,"Cubic Bezier Curves" print timer end ' Function to plot Bezier Cubic Splines ' ' Parameters are: ' X coordinate of start point ' Y coordinate of start point ' X coordinate of first control point ' Y coordinate of first control point ' X coordinate of second control point ' Y coordinate of second control point ' X coordinate of end point ' Y coordinate of end point ' Colour of curve ' CFunction bezier 00000000 27bdff78 afb00060 3c109d00 8e020080 afb10064 00a08821 8c850004 8c840000 afbf0084 afa70054 afb50074 afa6005c afbe0080 afb7007c afb60078 afb40070 afb3006c afb20068 0040f809 8fb500a8 8fa6005c afa20030 8cc40000 8e020080 0040f809 8cc50004 afa20034 8fa20098 8c440000 8c450004 8e020080 0040f809 00000000 afa20038 8fa200a0 8c440000 8c450004 8e020080 0040f809 00000000 afa2003c 8e240000 8e020080 0040f809 8e250004 8fa70054 afa20040 8ce40000 8e020080 0040f809 8ce50004 afa20044 8fa2009c 8c440000 8c450004 8e020080 0040f809 00000000 8fa300a4 afa20048 8c640000 8e020080 0040f809 8c650004 afa2004c 3c023f80 00409821 3c024000 0040a021 3c024040 00409021 3c023a83 3442126f 00401021 2403ffff afa20050 afa3002c 2416ffff 10000098 00008821 02602021 0040f809 02202821 0040b821 8e020074 02202021 0040f809 02402821 afa20018 8e020074 02e02021 0040f809 02402821 afa2001c 8e020074 02202021 0040f809 02802821 0040f021 8e020074 02e02021 0040f809 02802821 afa20020 8e020058 02402021 0040f809 02202821 afa20024 8e020058 03c02821 0040f809 02402021 afa20028 8fa4001c 8fa50030 8e020058 0040f809 8e1e005c 8e030058 8fa40020 8fa50034 afa30058 0060f809 afa2005c 8fa30058 8fa40024 0060f809 00402821 8fa6005c 00402821 03c0f809 00c02021 8e030058 8fa50038 02e02021 afa30058 0060f809 afa2005c 8fa30058 8fa40028 0060f809 00402821 8fa6005c 00402821 03c0f809 00c02021 00401821 8fa40018 8e020058 8fa5003c 0040f809 afa30058 8fa30058 00402821 03c0f809 00602021 00403021 8fa4001c 8e020058 8fa50040 8e1e005c 0040f809 afa6005c 8e030058 8fa40020 8fa50044 afa30058 0060f809 afa20054 8fa30058 8fa40024 0060f809 00402821 8fa70054 00402821 03c0f809 00e02021 8e030058 8fa50048 02e02021 afa30058 0060f809 afa20054 8fa30058 8fa40028 0060f809 00402821 8fa70054 00402821 03c0f809 00e02021 0040b821 8fa40018 8e020058 0040f809 8fa5004c 00402821 03c0f809 02e02021 8fa6005c 0040f021 8e02007c 0040f809 00c02021 0040b821 8e02007c 0040f809 03c02021 56f60005 8ea30000 8fa3002c 5043000d 8e02005c 8ea30000 00402821 afa30010 8e030048 00403821 afa20054 02e02021 0060f809 02e03021 8fa20054 afa2002c 8e02005c 8fa50050 0040f809 02202021 00408821 02e0b021 8e020068 02202021 0040f809 02602821 2403ffff 5043ff63 8e020060 8fbf0084 00001021 00001821 8fbe0080 8fb7007c 8fb60078 8fb50074 8fb40070 8fb3006c 8fb20068 8fb10064 8fb00060 03e00008 27bd0088 End CFunction 'MIPS32 M4K ' ' 'long long bezier (long long *xx0, long long *yy0, long long *xx1, long long *yy1,long long *xx2, long long *yy2, long long *xx3, long long *yy3, long long *colour) '{ ' float tmp,tmp1,tmp2,tmp3,tmp4,tmp5,tmp6,t,xt,yt; ' float x0=IntToFloat(*xx0),x1=IntToFloat(*xx1),x2=IntToFloat(*xx2),x3=IntToFloat(*xx3); ' float y0=IntToFloat(*yy0),y1=IntToFloat(*yy1),y2=IntToFloat(*yy2),y3=IntToFloat(*yy3); ' int xti,yti,xtlast=-1, ytlast=-1; ' K_1(one) ' K_2(two) ' K_3(three) ' K_ANY(inc,0x3A83126F) //0.001 ' ' for (t = 0x0; FCmp(t , one)==-1; t=FAdd(t,inc)) ' { ' tmp=FSub(one,t); ' tmp1=FPow(t, three); ' tmp2=FPow(tmp, three); ' tmp3=FPow(t, two); ' tmp4=FPow(tmp, two); ' tmp5=FMul(three , t); ' tmp6=FMul(three , tmp3); ' xt = FAdd(FAdd(FAdd(FMul(tmp2 , x0) , ' FMul(tmp5 , FMul(tmp4 , x1))) , ' FMul(tmp6 , FMul(tmp , x2))) , ' FMul(tmp1 , x3)); ' ' yt = FAdd(FAdd(FAdd(FMul(tmp2 ,y0) , ' FMul(tmp5 , FMul(tmp4 , y1))) , ' FMul(tmp6 , FMul(tmp , y2))) , ' FMul(tmp1 , y3)); ' xti=FloatToInt(xt); ' yti=FloatToInt(yt); ' ' if((xti!=xtlast) || (yti!=ytlast)) { ' DrawPixel(xti, yti, *colour); ' xtlast=xti; ' ytlast=yti; ' } ' } ' return 0; ' |
||||
paceman Guru Joined: 07/10/2011 Location: AustraliaPosts: 1328 |
We'll be smoothing skewed Gaussian distributions soon Peter - just when I thought I'd forgotten my X-ray diffraction days! Now what was that pattern recognition job for the Micromite we were all thinking about. Greg |
||||
matherp Guru Joined: 11/12/2012 Location: United KingdomPosts: 8592 |
One thing you can do with Bezier curves is use them to plot arcs. To do this a bit of maths is required to calculate the control points. But you can then plot any arbitrary arcs option default none option explicit dim integer i timer=0 for i=0 to 99 step 4 LargeArc(mm.hres/2,mm.vres/2,20+i,325+2*i,5+5*i,rgb(yellow)) next i print timer end ' ' subroutine to calculate points to use cubic Bezier splines to plot arcs greater than 90 degrees ' ' Parameters are: ' X coordinate of centre of arc ' Y coordinate of centre of arc ' radius of arc ' start radial of arc in degrees ' end radial of arc in degrees ' sub LargeArc(x as integer, y as integer, r as integer, a1i as integer, a2i as integer, col as integer) local integer amid, astart=a1i if a2i<a1i then a2i=a2i+360 do while a2i-astart>90 SmallArc(x , y , r , astart, astart+90 , col) astart=astart+90 loop SmallArc(x , y , r , astart, a2i , col) end sub ' ' subroutine to calculate points to use cubic Bezier splines to plot arcs less than 90 degrees ' ' Parameters are: ' X coordinate of centre of arc ' Y coordinate of centre of arc ' radius of arc ' start radial of arc in degrees ' end radial of arc in degrees sub SmallArc(x as integer, y as integer, ri as integer, a1i as integer, a2i as integer, col as integer) ' Compute all four points for an arc that subtends the same total angle ' but is centered on the X-axis local float r,a1,a2,a,x1,y1,x2,y2,x3,y3,x4,y4,k,f,ar,cos_ar,sin_ar local integer j,x1i,x2i,x3i,x4i,y1i,y2i,y3i,y4i r=ri a1=rad(a1i)- pi/2 a2=rad(a2i) -pi/2 a = (a2-a1) / 2.0 x4 = r * cos(a) y4 = r * sin(a) x1= x4 y1= -y4 k = 0.5522847498 f = k * tan(a) x2 = x1 + f * y4 y2 = y1 + f * x4 x3 = x2 y3= -y2 ' Find the arc points actual locations by computing x1,y1 and x4,y4 ' and rotating the control points by a + a1 ar = a + a1 cos_ar = cos(ar) sin_ar = sin(ar) x1i = r * cos(a1) + x y1i = r * sin(a1) + y x2i = x2 * cos_ar - y2 * sin_ar + x y2i = x2 * sin_ar + y2 * cos_ar + y x3i = x3 * cos_ar - y3 * sin_ar + x y3i = x3 * sin_ar + y3 * cos_ar + y x4i = r * cos(a2) + x y4i = r * sin(a2) + y j=bezier(x1i,y1i,x2i,y2i,x3i,y3i,x4i,y4i,col) end sub ' ' Function to plot Bezier Cubic Splines ' ' Parameters are: ' X coordinate of start point ' Y coordinate of start point ' X coordinate of first control point ' Y coordinate of first control point ' X coordinate of second control point ' Y coordinate of second control point ' X coordinate of end point ' Y coordinate of end point ' Colour of curve ' CFunction bezier 00000000 27bdff78 afb00060 3c109d00 8e020080 afb10064 00a08821 8c850004 8c840000 afbf0084 afa70054 afb50074 afa6005c afbe0080 afb7007c afb60078 afb40070 afb3006c afb20068 0040f809 8fb500a8 8fa6005c afa20030 8cc40000 8e020080 0040f809 8cc50004 afa20034 8fa20098 8c440000 8c450004 8e020080 0040f809 00000000 afa20038 8fa200a0 8c440000 8c450004 8e020080 0040f809 00000000 afa2003c 8e240000 8e020080 0040f809 8e250004 8fa70054 afa20040 8ce40000 8e020080 0040f809 8ce50004 afa20044 8fa2009c 8c440000 8c450004 8e020080 0040f809 00000000 8fa300a4 afa20048 8c640000 8e020080 0040f809 8c650004 afa2004c 3c023f80 00409821 3c024000 0040a021 3c024040 00409021 3c023a83 3442126f 00401021 2403ffff afa20050 afa3002c 2416ffff 10000098 00008821 02602021 0040f809 02202821 0040b821 8e020074 02202021 0040f809 02402821 afa20018 8e020074 02e02021 0040f809 02402821 afa2001c 8e020074 02202021 0040f809 02802821 0040f021 8e020074 02e02021 0040f809 02802821 afa20020 8e020058 02402021 0040f809 02202821 afa20024 8e020058 03c02821 0040f809 02402021 afa20028 8fa4001c 8fa50030 8e020058 0040f809 8e1e005c 8e030058 8fa40020 8fa50034 afa30058 0060f809 afa2005c 8fa30058 8fa40024 0060f809 00402821 8fa6005c 00402821 03c0f809 00c02021 8e030058 8fa50038 02e02021 afa30058 0060f809 afa2005c 8fa30058 8fa40028 0060f809 00402821 8fa6005c 00402821 03c0f809 00c02021 00401821 8fa40018 8e020058 8fa5003c 0040f809 afa30058 8fa30058 00402821 03c0f809 00602021 00403021 8fa4001c 8e020058 8fa50040 8e1e005c 0040f809 afa6005c 8e030058 8fa40020 8fa50044 afa30058 0060f809 afa20054 8fa30058 8fa40024 0060f809 00402821 8fa70054 00402821 03c0f809 00e02021 8e030058 8fa50048 02e02021 afa30058 0060f809 afa20054 8fa30058 8fa40028 0060f809 00402821 8fa70054 00402821 03c0f809 00e02021 0040b821 8fa40018 8e020058 0040f809 8fa5004c 00402821 03c0f809 02e02021 8fa6005c 0040f021 8e02007c 0040f809 00c02021 0040b821 8e02007c 0040f809 03c02021 56f60005 8ea30000 8fa3002c 5043000d 8e02005c 8ea30000 00402821 afa30010 8e030048 00403821 afa20054 02e02021 0060f809 02e03021 8fa20054 afa2002c 8e02005c 8fa50050 0040f809 02202021 00408821 02e0b021 8e020068 02202021 0040f809 02602821 2403ffff 5043ff63 8e020060 8fbf0084 00001021 00001821 8fbe0080 8fb7007c 8fb60078 8fb50074 8fb40070 8fb3006c 8fb20068 8fb10064 8fb00060 03e00008 27bd0088 End CFunction 'MIPS32 M4K ' ' 'long long bezier (long long *xx0, long long *yy0, long long *xx1, long long *yy1,long long *xx2, long long *yy2, long long *xx3, long long *yy3, long long *colour) '{ ' float tmp,tmp1,tmp2,tmp3,tmp4,tmp5,tmp6,t,xt,yt; ' float x0=IntToFloat(*xx0),x1=IntToFloat(*xx1),x2=IntToFloat(*xx2),x3=IntToFloat(*xx3); ' float y0=IntToFloat(*yy0),y1=IntToFloat(*yy1),y2=IntToFloat(*yy2),y3=IntToFloat(*yy3); ' int xti,yti,xtlast=-1, ytlast=-1; ' K_1(one) ' K_2(two) ' K_3(three) ' K_ANY(inc,0x3A83126F) //0.001 ' ' for (t = 0x0; FCmp(t , one)==-1; t=FAdd(t,inc)) ' { ' tmp=FSub(one,t); ' tmp1=FPow(t, three); ' tmp2=FPow(tmp, three); ' tmp3=FPow(t, two); ' tmp4=FPow(tmp, two); ' tmp5=FMul(three , t); ' tmp6=FMul(three , tmp3); ' xt = FAdd(FAdd(FAdd(FMul(tmp2 , x0) , ' FMul(tmp5 , FMul(tmp4 , x1))) , ' FMul(tmp6 , FMul(tmp , x2))) , ' FMul(tmp1 , x3)); ' ' yt = FAdd(FAdd(FAdd(FMul(tmp2 ,y0) , ' FMul(tmp5 , FMul(tmp4 , y1))) , ' FMul(tmp6 , FMul(tmp , y2))) , ' FMul(tmp1 , y3)); ' xti=FloatToInt(xt); ' yti=FloatToInt(yt); ' ' if((xti!=xtlast) || (yti!=ytlast)) { ' DrawPixel(xti, yti, *colour); ' xtlast=xti; ' ytlast=yti; ' } ' } ' return 0; ' |
||||
paceman Guru Joined: 07/10/2011 Location: AustraliaPosts: 1328 |
That's sure making it work Peter - took around 6420mS on mine, but it's very pretty! I'm also pretty sure at this stage my head is hurting. I Googled 'Bezier curves' yesterday and one of the links here mentioned that PostScript fonts are defined using them these days. Interesting stuff - you can certainly understand that when you look at your demo above. Greg |
||||
matherp Guru Joined: 11/12/2012 Location: United KingdomPosts: 8592 |
Hi paceman I've spent a bit of time optimising - try this now averaging 40msec / arc which seems OK option default none option explicit cpu 48 const k = 0.5522847498 const pidiv2=pi/2 dim integer i timer=0 for i=0 to 99 step 4 LargeArc(mm.hres/2,mm.vres/2,20+i,325+2*i,5+5*i,rgb(yellow)) next i print timer end ' ' subroutine to calculate points to use cubic Bezier splines to plot arcs greater than 90 degrees ' ' Parameters are: ' X coordinate of centre of arc ' Y coordinate of centre of arc ' radius of arc ' start radial of arc in degrees ' end radial of arc in degrees sub LargeArc(x as integer, y as integer, r as integer, a1i as integer, a2i as integer, col as integer) local integer amid, astart=a1i if a2i<a1i then a2i=a2i+360 do while a2i-astart>90 SmallArc(x , y , r , astart, astart+90 , col) astart=astart+90 loop SmallArc(x , y , r , astart, a2i , col) end sub ' ' subroutine to calculate points to use cubic Bezier splines to plot arcs less than 90 degrees ' ' Parameters are: ' X coordinate of centre of arc ' Y coordinate of centre of arc ' radius of arc ' start radial of arc in degrees ' end radial of arc in degrees sub SmallArc(x as integer, y as integer, ri as integer, a1i as integer, a2i as integer, col as integer) ' First compute all four points for an arc that subtends the same total angle ' but is centered on the X-axis local float r,a1,a2,a,x1,y1,x2,y2,x3,y3,x4,y4,f,ar,cos_ar,sin_ar local integer j local float x2i,x3i,y2i,y3i r=ri a1=rad(a1i)- pidiv2 a2=rad(a2i)- pidiv2 a = (a2-a1) / 2.0 x4 = r * cos(a) y4 = r * sin(a) x1= x4 y1= -y4 f = k * tan(a) x2 = x1 + f * y4 y2 = y1 + f * x4 x3 = x2 y3= -y2 ' Now find the arc points actual locations by computing x1,y1 and x4,y4 ' and rotating the control points by a + a1 ar = a + a1 cos_ar = cos(ar) sin_ar = sin(ar) x1 = r * cos(a1) + x y1 = r * sin(a1) + y x2i = x2 * cos_ar - y2 * sin_ar + x y2i = x2 * sin_ar + y2 * cos_ar + y x3i = x3 * cos_ar - y3 * sin_ar + x y3i = x3 * sin_ar + y3 * cos_ar + y x4 = r * cos(a2) + x y4 = r * sin(a2) + y j=fbezier(x1,y1,x2i,y2i,x3i,y3i,x4,y4,col) end sub ' ' Function to plot Bezier Cubic Splines ' ' Parameters are: ' X coordinate of start point ' Y coordinate of start point ' X coordinate of first control point ' Y coordinate of first control point ' X coordinate of second control point ' Y coordinate of second control point ' X coordinate of end point ' Y coordinate of end point ' Colour of curve ' CFunction fbezier 00000000 27bdffa0 2402ffff afbe0058 afb70054 afb60050 afb5004c afb40048 afb30044 afb1003c afb00038 00c0a821 afbf005c afb20040 0080b821 00a0b021 00e0a021 8fbe0080 241301f4 afa20028 2406ffff 00008821 10000002 3c109d00 02403021 3c023f80 00402021 8e020060 02202821 0040f809 afa60034 00409021 8e020058 02202021 0040f809 02202821 afa20018 8e020058 02402021 0040f809 02402821 afa2001c 8fa40018 8e020058 0040f809 02202821 afa20020 8fa4001c 8e020058 0040f809 02402821 afa20024 3c024040 00402021 8e020058 0040f809 02202821 00403821 3c024040 00402021 8e020058 8fa50018 0040f809 afa7002c 8fa7002c 00401821 8fa5001c 8e020058 00e02021 0040f809 afa30030 8fa30030 afa20018 8e020058 00602021 0040f809 02402821 afa2001c 8ee50000 8fa40024 8e020058 0040f809 8e12005c 00401821 8ea50000 8e020058 8fa40018 0040f809 afa30030 8fa30030 00402821 0240f809 00602021 8fa40070 00401821 8c850000 8e020058 8fa4001c 0040f809 afa30030 8fa30030 00402821 0240f809 00602021 8fa40078 00401821 8c850000 8e020058 8fa40020 0040f809 afa30030 8fa30030 00402821 0240f809 00602021 00401821 8ec50000 8e020058 8fa40024 8e12005c 0040f809 afa30030 00403821 8e850000 8e020058 8fa40018 0040f809 afa7002c 8fa7002c 00402821 0240f809 00e02021 8fa40074 00403821 8c850000 8e020058 8fa4001c 0040f809 afa7002c 8fa7002c 00402821 0240f809 00e02021 8fa4007c 00403821 8c850000 8e020058 8fa40020 0040f809 afa7002c 8fa7002c 00402821 0240f809 00e02021 8fa30030 00402821 8e02007c 00602021 0040f809 afa5002c 8fa5002c 00409021 8e02007c 0040f809 00a02021 8fa60034 56460005 8fc30000 8fa30028 1043000c 00000000 8fc30000 00402821 afa30010 8e030048 00403821 afa2002c 02402021 0060f809 02403021 8fa2002c afa20028 3c023b03 3442126f 00402821 8e02005c 0040f809 02202021 2673ffff 1660ff5a 00408821 8fbf005c 00001021 00001821 8fbe0058 8fb70054 8fb60050 8fb5004c 8fb40048 8fb30044 8fb20040 8fb1003c 8fb00038 03e00008 27bd0060 End CFunction 'MIPS32 M4K 'long long fbezier (float *x0, float *y0, float *x1, float *y1,float *x2, float *y2, float *x3, float *y3, long long *colour) '{ ' float tmp,tmp1,tmp2,tmp3,tmp4,tmp5,tmp6,tmp7,tmp8,t,xt,yt; ' int xti,yti,xtlast=-1, ytlast=-1; ' int i; ' t = 0x0; ' for (i=0;i<500;i++) ' { ' tmp =FSub(M_1,t); ' tmp3=FMul(t,t); ' tmp4=FMul(tmp,tmp); ' tmp1=FMul(tmp3,t); ' tmp2=FMul(tmp4,tmp); ' tmp5=FMul(M_3, t); ' tmp6=FMul(M_3, tmp3); ' tmp7=FMul(tmp5,tmp4); ' tmp8=FMul(tmp6,tmp); ' xt = FAdd(FAdd(FAdd(FMul(tmp2 , *x0) , ' FMul(tmp7 , *x1)) , ' FMul(tmp8 , *x2)) , ' FMul(tmp1 , *x3)); ' ' yt = FAdd(FAdd(FAdd(FMul(tmp2 ,*y0) , ' FMul(tmp7 , *y1)) , ' FMul(tmp8 , *y2)) , ' FMul(tmp1 , *y3)); ' xti=FloatToInt(xt); ' yti=FloatToInt(yt); ' if((xti!=xtlast) || (yti!=ytlast)) { ' DrawPixel(xti, yti, *colour); ' xtlast=xti; ' ytlast=yti; ' } ' t=FAdd(t,M_ANY(0x3B03126F)); ' } ' return 0; ' |
||||
paceman Guru Joined: 07/10/2011 Location: AustraliaPosts: 1328 |
That's 2250 on mine to run the whole thing above - 25 arcs plus all the other calcs, about a third of the previous code run time. It's difficult now to see each arc being plotted, they just individually appear whereas before you could follow them being plotted. Quite impressive Peter, I'm glad you seem to know what you're doing. |
||||
WhiteWizzard Guru Joined: 05/04/2013 Location: United KingdomPosts: 2794 |
Greg, Peter, What are the resolutions of the TFTs you are using? And also which controller - Thanks WW For everything Micromite visit micromite.org Direct Email: whitewizzard@micromite.o |
||||
matherp Guru Joined: 11/12/2012 Location: United KingdomPosts: 8592 |
240x320 ili9341 |
||||
paceman Guru Joined: 07/10/2011 Location: AustraliaPosts: 1328 |
Same here: 240x320 ILI9341. I'm using a 2.8" and a 2.4", they both have pretty much exactly the same timing. Greg |
||||
Print this page |