![]() |
Forum Index : Microcontroller and PC projects : CMM2 - ARC, Two Questions
Author | Message | ||||
Andrew_G Guru ![]() Joined: 18/10/2016 Location: AustraliaPosts: 871 |
Hi all, I'm playing with Lunar Lander and I'm trying to create a number of gauges using the ARC statement. Some questions: 1) Is there a suite of gauge code like for the MM+? 2) Is it possible to have an aspect ratio (as in the CIRCLE command)? 3) More confusing, is some strange behavior I've observed (the following code ties to illustrate it - but not very well). If you count up from -90 to +90 (eg ARC x,y, R1, R2, A1, A2, Colour, as you pass through A1 or A2=0 ARC throws an error (I can understand that). BUT it appears to be in the section between -1 and 1 that it occurs. Thus the code below, which does nothing between -1 and 1, is fine. Any suggestions how to do it better? Cheers, Andrew 'ARC_PLAY.BAS 'The objective is to plot simple circular gauges from 0 to -90 and 0 to +90 degrees 'The line "CASE -1 to 1" seems to be required - The code below works. dim integer I Const X_Hzt = MM.Hres/2 const Y_Hzt = MM.VRES/2 cls for I = -100 to 100 step 1 'Just to confirm it works beyond 90deg select case I case <-90 ARC X_Hzt, Y_Hzt, 40,50 , 270, 360, RGB(red) 'Red for port = left case -90 to -1 '0 If this is changed to 0 AND the line "CASE -1 to 1" commented out it fails ARC X_Hzt, Y_Hzt, 40,50 , 360+I, 360, RGB(red) 'B case -1 to 1 'with this in it works, with this commented out AND the line "CASE -90 to 0" it fails 'Do nothing - is there any better way than this? case 1 to 90 ARC X_Hzt, Y_Hzt, 40,50 , 360, 360+I, RGB(Green) 'Green for starboard = right case > 90 ARC X_Hzt, Y_Hzt, 40,50 , 0, 90, RGB(Green) case Else text 400,520,"Else", CM, 1,1,rgb(Green) 'Just to check all options covered pause 1000 text 400,520," ", CM, 1,1,rgb(Black) end select text 400,500," ", CM, 1,1,rgb(Black) 'Blank out old text text 400,500,str$(I), CM, 1,1,rgb(Green) 'Text new angle pause 200 'Just to see what is happening ARC X_Hzt, Y_Hzt, 40,50 , 270, 90, RGB(black) 'Blank out the old arc Next I do:loop while inkey$ = "" End Edited 2020-07-17 12:46 by Andrew_G |
||||
panky![]() Guru ![]() Joined: 02/10/2012 Location: AustraliaPosts: 1114 |
Andrew, Below is some code I used for a tacho on a narrow boat (barge). I have checked on a CMM2 and seems to work - hope this may be of some assistance. Doug ' Test code to show tacho cls '... some global variables needed by the subs below ' ... some of these could be moved into locals in ' the subroutines dim t_x%=400 ' gauge centre dim t_y%=240 dim t_r%=118 ' radius dim w_start%=-150 ' white start dim g_start%=-50 ' green " dim y_start%r=50 ' yellow " dim r_start%=80 ' red " dim b_start%=150 ' black -the non-display section dim x% dim y% dim radius% dim lastx1%,lastx2%,lastx3% dim lasty1%,lasty2%,lasty3% dim angle% dim rpm% dim col%=rgb(150,150,150) ' needle colour ' sample code to show tacho working InitTacho do rpm% = int(rnd()*3000) UpDateTacho pause 2000 loop end 'Tacho - code based on examples from Geoff, Peter ' and other backshedders - thanks. ' Sub Routine to initialise tacho gauge ' - this is not GUI so needs to be re-painted after any GUI ' that overlays it. eg. setup Sub InitTacho Local ticks% ' background to create the outer bezel Circle t_x%, t_y%, t_r%+42,3,, RGB(150,150,150),-1 Circle t_x%, t_y%, t_r%+41,3,, RGB(220,220,220),-1 Circle t_x%, t_y%, t_r%+40,3,, RGB(white),-1 Circle t_x%, t_y%, t_r%+39,3,, RGB(220,220,220),-1 Circle t_x%, t_y%, t_r%+38,3,, RGB(180,180,180),-1 Circle t_x%, t_y%, t_r%+37,3,, RGB(150,150,150),RGB(60,60,60) segment(t_x%, t_y%, t_r%, w_start%, g_start%, RGB(white), 0) segment(t_x%, t_y%, t_r%, g_start%, y_start%, RGB(0,180,0), 0) segment(t_x%, t_y%, t_r%, y_start%, r_start%, RGB(200,200,0), 0) segment(t_x%, t_y%, t_r%, r_start%, b_start%, RGB(red), 0) segment(t_x%, t_y%, t_r%, b_start%, w_start%+360,RGB(60,60,60), 0) For ticks%=w_start% To b_start% Step 20 segment(t_x%, t_y%, t_r%, ticks%, ticks%, 0, (t_r%*19)\20) Next ticks% ' now for inner circle which determines how wide the colour bands are Circle t_x%,t_y%,t_r%-20,0,,RGB(0,0,0),RGB(60,60,60)'(t_r%*4)\5,0,,0,0 Text t_x%, t_y%+75,"RPM x100",C,1,1,RGB(white),RGB(60,60,60)' string centred in black segment Text t_x%,t_y%+100,"Engine Hrs",C,1,1,RGB(white),RGB(60,60,60) Font 4 RBox t_x%-42,t_y%+118,84,28,5,RGB(white),RGB(100,100,150) Font 2 ' the following is all for use by needle display x%=t_x% y%=t_y% radius%=t_r% lastx1%=t_x% lastx2%=t_x%+2 lastx3%=t_x%+2 lasty1%=t_y% lasty2%=t_y%+2 lasty3%=t_y%+2 End Sub ' ' Routine to draw a segment of a circle ' Parameters are: ' x-coordinate of centre of circle ' y-coordinate of centre of circle ' radius of circle ' start radial of segment to be drawn (0-360 degrees) ' end radial of segment to be drawn (0-360 degrees) ' colour to draw segment ' inner radius for drawing radial lines, leave blank or set to zero if not required ' NB if start radial and end radial are the same a line will be drawn Sub segment(x%, y%, outsize%, startradial%, endradial%, col%, insize%) Local integer i,j, x1, x2, y1, y2, sr, er, xx0, yy0, xx1, yy1, xx2, yy2, tcol Local INTEGER xtxt,ytxt,txtradial Local stepsize% = 1 If startradial%=endradial% Then x2=Sin(Rad(startradial%))*outsize% + x% y2=-Cos(Rad(startradial%))*outsize% + y% x1=Sin(Rad(startradial%))*insize% + x% 'insize is 0 if not specified so a complete line from the centre is drawn y1=-Cos(Rad(startradial%))*insize% + y% Line x1,y1,x2,y2,,col% ' now put in values outside rim txtradial = (startradial% + 150)/10 ' adjust degrees to 0 to 2400 rpm xtxt=Sin(Rad(startradial%))*(outsize% + 20 ) + x% ytxt=-Cos(Rad(startradial%))*(outsize% + 20) + y% Font 2 Text xtxt-12,ytxt-10,Str$(txtradial,2),L,2,1,RGB(white),RGB(60,60,60) ' character positioning offset applied Else If startradial% < endradial% Then sr=startradial% er=endradial% Else er=startradial% sr=endradial% EndIf For i%=sr+stepsize% To er Step stepsize% x2=Sin(Rad(i%))*outsize% + x% y2=-Cos(Rad(i%))*outsize% + y% x1=Sin(Rad(i%-stepsize%))*outsize% + x% y1=-Cos(Rad(i%-stepsize%))*outsize% + y% xx0=x% yy0=y% xx1=x1 yy1=y1 xx2=x2 yy2=y2 tcol=col% Triangle xx0,yy0,xx1,yy1,xx2,yy2,tcol,tcol Next i% EndIf End Sub ' ' Routine to draw a pointer ' Parameters are: ' radial of pointer to be drawn (0-360 degrees) ' colour to draw pointer ' value to be drawn as a number in lower area of dial Sub needle(angle%, col%) Local integer x1,y1,x2,y2,x3,y3,j, xx1,yy1,xx2,yy2,xx3,yy3, tcol, size size= radius%\5*4-1 x1=Sin(Rad(angle%-90))*size/10 + x% y1=-Cos(Rad(angle%-90))*size/10 + y% x2=Sin(Rad(angle%))*size + x% y2=-Cos(Rad(angle%))*size + y% x3=Sin(Rad(angle%+90))*size/10 + x% y3=-Cos(Rad(angle%+90))*size/10 + y% ' overwrite last needle position xx1=lastx1% yy1=lasty1% xx2=lastx2% yy2=lasty2% xx3=lastx3% yy3=lasty3% tcol = 0 Triangle xx1, yy1, xx2, yy2, xx3, yy3,RGB(60,60,60),RGB(60,60,60) ' now setup to write new needle position xx1=x1 yy1=y1 xx2=x2 yy2=y2 xx3=x3 yy3=y3 tcol=col% Triangle xx1, yy1, xx2, yy2, xx3, yy3,RGB(gray),RGB(white) ' write out needle centre pin Circle x%, y%, size\10, 0, , col%, col%) Circle x%, y%, size\15, 0, , 0, 0 Circle x%, y%, size\20, 0, , RGB(gray), RGB(gray) ' save the current needle position as last needle position for next write lastx1%=x1 lastx2%=x2 lastx3%=x3 lasty1%=y1 lasty2%=y2 lasty3%=y3 End Sub ' ' Update tacho RPM needle position Sub UpdateTacho ' convert rpm value of 0 to 3000 into angle for needle display angle% = (rpm%-1500)\10 needle(angle%,RGB(white)) Print ""; ' needed to stop needle memory error End Sub ' End of tacho subroutines ... almost all of the Maximites, the MicromMites, the MM Extremes, the ArmMites, the PicoMite and loving it! |
||||
Andrew_G Guru ![]() Joined: 18/10/2016 Location: AustraliaPosts: 871 |
Thanks Panky, It works very nicely and doesn't use the ARC statement. It will take me a while to understand it though - thanks for all the comments throughout. Cheers, Andrew |
||||
vegipete![]() Guru ![]() Joined: 29/01/2013 Location: CanadaPosts: 1132 |
You have indeed found something odd. The arc command seems to have trouble when the first angle is negative. A work around is to add 360 if an angle is less than 0. Also, if the radii are small, nothing is drawn for small delta angles. The following might help: (Flicker can be prevented by drawing on a page N other than 0 and then doing a "page copy N,0,B") 'ARC_PLAY.BAS 'The objective is to plot simple circular gauges from 0 to -90 and 0 to +90 degrees 'The line "CASE -1 to 1" seems to be required - The code below works. dim integer I Const X_Hzt = MM.Hres/2 const Y_Hzt = MM.VRES/2 cls for I = -120 to 120 step 1 'Just to confirm it works beyond 90deg ARC X_Hzt, Y_Hzt, 40,50 , 240, 120, RGB(black) 'Blank out the old arc ' CIRCLE X_Hzt, Y_Hzt, 50, 10, 1, RGB(Black) ' Blank out the old arc - which method is better? if I < 0 then ARC X_Hzt, Y_Hzt, 40,50 , I+360, 0, RGB(Red) elseif I > 0 then ARC X_Hzt, Y_Hzt, 40,50 , 0, I, RGB(Green) else ' special case when I = 0 line X_Hzt, Y_Hzt-41, X_Hzt, Y_Hzt-50, 1, RGB(Yellow) endif ' text 400,500," ", CM, 1,1,rgb(Black) 'Blank out old text text X_Hzt,Y_Hzt," "+str$(I)+" ", CM, 1,1,rgb(Green) 'Text new angle pause 20 'Just to see what is happening Next I do:loop while inkey$ = "" End Visit Vegipete's *Mite Library for cool programs. |
||||
Andrew_G Guru ![]() Joined: 18/10/2016 Location: AustraliaPosts: 871 |
Thanks Vegipete, It's good to see that someone else can reproduce it. I also suspect that it behaves differently from the Command line but I wasn't sure so didn't whinge in the first instance. That is a good work around - thanks. I redraw the arc rather than a circle because there are edges to the arc that I can't be bothered redrawing each time (I've simplified the code a bit). I should have a new version of Lunar Lander this weekend (eg with sunlight on the hills) but I do have some domestic distractions (like COVID-19). Any comments on the Aspect Ratio?? Cheers, Andrew Edit: NOT that I've got COVID but it is keeping me in hiding. Edited 2020-07-17 17:46 by Andrew_G |
||||
![]() |
![]() |
The Back Shed's forum code is written, and hosted, in Australia. | © JAQ Software 2025 |