Author Topic: SB scale and rotate  (Read 1704 times)

B+

  • Guest
SB scale and rotate
« on: April 11, 2016, 07:08:05 pm »
Here is demo of recent projects of creating scale-able font and drawing scale and rotation:

Code: [Select]
'SB rotation.bas for SmallBASIC 0.12.2 [B+=MGA] 2016-04-11

cx=xmax/2:cy=ymax/2
secwide=275
sechigh=50
dim sect(secwide,sechigh)
sz=50
color 15,0:cls
post 18,8,sz,15,"SmallBASIC"
getsec 0,0
color 15,4:cls
rotate
pause

'scale for 1x2 cells
sub post(x,y,scale,fore,mess)
  local lm,i,c,p1,p2,p3,p4,px,gf
  thick=1/40*scale
  dr=1/6*scale-.5*thick
  gf=.04*scale
  color fore
  p1=.16*scale : p2=.32*scale : p3=.48*scale : p4 =.64*scale
  lm=len(mess) : py=y+.5*thick
  if lm*scale*.5+x-xmax>0 then Beep 'draw it anyway
  for i=1 to lm
    c=mid(mess,i,1)
    px=x+(i-1)*scale*.5+.5*thick
    select case c
    case "a":ac px+p1,py+p3,0,360:lx=px+p2:ly=py+p2-gf:tl 0,p2:tl 0,2*gf
    case "l":lx=px+p1-gf:ly=py:tl gf,0:tl 0,p4:tl gf,0:tl -2*gf,0
    case "m":lx=px:ly=py+p2:tl 0,p2:lx=px+p1:ly=py+p4:tl 0,-p2:tl -p1,p1:lx=px+p2:ly=py+p4:tl 0,-p2:tl -p1,p1
    case "A":lx=px:ly=py+p4:tl p1-gf,-p4:tl 2*gf,0:tl p1-gf,p4:lx=px+p1-2*gf:ly=py+p2:tl p1,0
    case "B":ac px+p1,py+p1,270,450:ac px+p1,py+p3,270,450
             lx=px:ly=py:tl 0,p4:tl p1,0:lx=px:ly=py+p2:tl p1,0:lx=px:ly=py:tl p1,0     
    case "C":ac px+p1,py+p1,180,320:ac px+p1,py+p3,40,180:lx=px:ly=py+p1:tl 0,p2   
    case "I":lx=px+p1*.5:ly=py:tl p1,0:lx=px+p1*.5:ly=py+p4:tl p1,0:lx=px+p1:ly=py:tl 0,p4
    case "M":lx=px:ly=py+p4:tl 0,-p4:tl p1,p2:tl p1,-p2:tl 0,p4
    case "S":ac px+p1,py+p1,90,360:ac px+p1,py+p3,270,540
    end select
  next
end

'ac is for arc, x,y is radius center, das=degree angle start, dae=degree angle end
sub ac(x,y,das,dae)
  'note dr, drawing radius has to be global, use COLOR globally sets color
  'note thick also made globals by POST sub
  local a,x1,y1,stepper
  if dr then
    if int(thick)=0 then stepper=1/(dr*pi) else stepper=(thick/2)/(dr*pi/2)
    for a=das to dae step stepper
      x1=dr*cos(rad(a)) : y1=dr*sin(rad(a))
      if int(thick)<1 then  pset x+x1,y+y1 else circle x+x1,y+y1,thick filled
    next
  fi
end

'tl stands for thick line in the LINE STEP x,y format
sub tl(stepx,stepy) 'tl=thickline 
  'lastx, lasty globals for last drawn position
  'thick has to be global
  'note thick=0 still draws a line, use COLOR so line is drawn from this global
  local length,dx,dy,i
  length=((stepx)^2 +(stepy)^2)^.5
  if length then
    dx=stepx/length : dy=stepy/length
    for i=0 to length
      circle lx+dx*i,ly+dy*i,thick filled
    next
  end if
  lx=lx+stepx : ly=ly+stepy
end

sub getsec(xstart,ystart)
  local x,y
  'these are all global
  for y=0 to sechigh
    for x=0 to secwide
      sect(x,y)=POINT(xstart+x,ystart+y) '<== data from screen points
    next
  next
end

sub rotate 'and scale
  local cax,cay,ra,cc,d,anew,ax,ay
  dx=(xmax/secwide)/720 :dy=(ymax/sechigh)/720
  cax=secwide/2:cay=sechigh/2  'array center
  for i=1 to 721
    cls
    for y=0 to sechigh
      for x=0 to secwide
        cc=sect(x,y)
        if (x-cax)<>0 and cc<>0 then
          d=((x-cax)^2+(y-cay)^2)^.5
          anew=atan((y-cay)/(x-cax))
          if x-cax<0 and y-cay<0 then anew=anew+pi+rad(ra)  '-x,-y
          if x-cax<0 and y-cay>=0 then anew=anew+pi+rad(ra) '-x,+y
          if x-cax>=0 and y-cay<0 then anew=anew+rad(ra)    '+x,-y
          if x-cax>=0 and y-cay>=0 then anew=anew+rad(ra)   '+x,+y
          ax=d*cos(anew):ay=d*sin(anew)
          cc=sect(x,y)
          rect cx+ax*i*dx,cy+ay*i*dy step i*dx,i*dy filled
        end if
      next
    next
    ra+=1
    ra=ra%360
    showpage
    delay 60
  next
end
« Last Edit: April 12, 2016, 01:03:18 am by B+ »

n00b

  • Guest
Re: SB scale and rotate
« Reply #1 on: April 13, 2016, 05:43:04 am »
Is this for using a bitmap font or true type?

ZXDunny

  • Guest
Re: SB scale and rotate
« Reply #2 on: April 13, 2016, 09:14:56 am »
Looks like it builds the font itself and renders using points, lines and circles.

Which reminds me, SpecBAS sorely needs thick line support and rotated text - currently the only way to get that is to render text to an in-memory backbuffer and rotate that to the screen with the blitting commands.

I may look at that after I've finished the new expression operators.

B+

  • Guest
Re: SB scale and rotate
« Reply #3 on: April 13, 2016, 02:12:07 pm »
Yes, the font is hand made so to speak. I started playing with turtle like draw strings and ended up drawing font letters because SmallBASIC has only one sized font. But first I needed thick lines and arcs which SmallBASIC also did not have (subs ac and tl, short names for short drawing commands, most drawing instructions for letters fit on one line).

So the font can be scaled to whatever pixel size height you want to POST but the rotation comes from printing text on screen and then loading the POINTS into array like a section of an image.

Then I worked out code for rotating an array of image points so that I can rotate not just fonts but any drawing that is captured into an array of POINT colors.

I was surprised that it did not take that much code to write instructions to draw 66 characters on screen with control over their size.

It might have been cleaner to draw circles instead of rectangles but I liked the effect of using rectangles when the image was rotated on screen.

I guess I should also confess a sort of happy accident. As the text grows from a point to filling the whole screen all the time rotating, it also has a sort of 2.5D effect because it is not a simple rectangle merely spinning about at a point, the size of rectangle area that contains the letters seems to grow and shrink according to it's angle.

« Last Edit: April 13, 2016, 02:38:18 pm by B+ »