Page 1 of 1

Sprite -Swirl- shaping

Posted: Thu Mar 10, 2016 5:22 am
by Operator
Here is a port of a swirl effect...

Code: Select all

REM Swirl Effect
REM ported out of: http://www.petesqbsite.com/sections/express/issue24/index.html#swirl
REM sB 5.3 / iPhone 4 / iOS 6.1 / by Operator
REM a bit slow...

OPTION IMAGE POS CENTRAL
OPTION ANGLE DEGREES
GRAPHICS
GRAPHICS CLEAR 0,0,0
scw.h = SCREEN_WIDTH()/2
sch.h = SCREEN_HEIGHT()/2

angle_inc = 30 'swirl-factor
rr = 100       '+/- HALF range/radius of
               'picture-pixels to be swirled, 
sc.x1 = scw.h  'x-centre of source image
sc.y1 = 120    'y-centre of source image
tc.x1 = scw.h  'x-centre of target image
tc.y1 = 300    'y-centre of target image

FIELD "info" TEXT "" AT 0,0 SIZE 200,20 RO
FIELD "info" FONT COLOR 1,1,1
FIELD "info" BACK ALPHA 0

'draw rect over source data, scale fac. 2
DRAW COLOR 1,1,1
DRAW RECT sc.x1,sc.y1 SIZE 5+rr/2,5+rr/2
DRAW COLOR 1,0,0
DRAW SIZE 3
DRAW LINE sc.x1,sc.y1-rr/2 TO sc.x1,sc.y1+rr/2

IMAGE$ = "/Examples/Graphics/images/snowflake.png"
DRAW IMAGE IMAGE$ AT sc.x1, sc.y1 SCALE 0.95 ANGLE 30

FIELD "info" TEXT "Data to be acquiered"

'color r g b -> cr, cg, cb array for the pixels
maxx = (2*(rr+1))^2
DIM cr(maxx) ! DIM cg(maxx) ! DIM cb(maxx)

'sin cos look up tables -> st / ct arrays
pi = ATN(1)*4
range = 359
DIM st(range+1) ! DIM ct(range+1)
FOR x = 0 TO range
  st(x) = SIN(x)
  ct(x) = COS(x)
NEXT x

'distance lookup-table
DIM distance_lut(rr+1,rr+1)
FOR x = 0 TO rr
  FOR y = 0 TO rr
    distance_lut(x,y) = SQRT(x^2 + y^2)
  NEXT y
NEXT x

'store picture color data, scale factor = 2
FOR x = -rr TO rr
  FOR y = -rr TO rr
    i = i+1
    GET PIXEL x+2*sc.x1,y+2*sc.y1 COLOR r,g,b
    cr(i)=r ! cg(i)=g ! cb(i)=b
    ' get pixel can't store into array (?)
  NEXT y
NEXT x

'draw rect of target (swirled data)
DRAW COLOR 1,1,1
DRAW SIZE 1
DRAW RECT tc.x1,tc.y1 SIZE 5+rr/2,5+rr/2
FIELD "info" TEXT "Swirling Data..."
REFRESH OFF

LOOP:
a = (a + angle_inc)%range
i=0
FOR x = -rr TO rr 
  FOR y = -rr TO rr
    i=i+1
    'limit swirl to circular shape
    distance = distance_lut(ABS(x),ABS(y))
    IF distance <= rr THEN
      ANGLE = INT(a*(rr-distance)/rr)
      rotatedx = x*ct(ANGLE) - y*st(ANGLE)
      rotatedy = x*st(ANGLE) + y*ct(ANGLE)
      DRAW PIXEL rotatedx+2*tc.x1, rotatedy+2*tc.y1 COLOR cr(i),cg(i),cb(i)
      END IF
    NEXT y
    REFRESH
  NEXT x
GOTO LOOP

Re: Sprite -Swirl- shaping

Posted: Thu Mar 10, 2016 8:21 am
by Mr. Kibernetik
Very nice program!
Little update to make it 2 times faster:

Code: Select all

REM Swirl Effect
REM ported out of: http://www.petesqbsite.com/sections/express/issue24/index.html#swirl
REM sB 5.3 / iPhone 4 / iOS 6.1 / by Operator
REM a bit slow...

OPTION IMAGE POS CENTRAL
OPTION ANGLE DEGREES
GRAPHICS
GRAPHICS CLEAR 0,0,0
scw.h = SCREEN_WIDTH()/2
sch.h = SCREEN_HEIGHT()/2

angle_inc = 30 'swirl-factor
rr = 100       '+/- HALF range/radius of
               'picture-pixels to be swirled, 
sc.x1 = scw.h  'x-centre of source image
sc.y1 = 120    'y-centre of source image
tc.x1 = scw.h  'x-centre of target image
tc.y1 = 300    'y-centre of target image

FIELD "info" TEXT "" AT 0,0 SIZE 200,20 RO
FIELD "info" FONT COLOR 1,1,1
FIELD "info" BACK ALPHA 0

'draw rect over source data, scale fac. 2
DRAW COLOR 1,1,1
DRAW RECT sc.x1,sc.y1 SIZE 5+rr/2,5+rr/2
DRAW COLOR 1,0,0
DRAW SIZE 3
DRAW LINE sc.x1,sc.y1-rr/2 TO sc.x1,sc.y1+rr/2

IMAGE$ = "/Examples/Graphics/images/snowflake.png"
DRAW IMAGE IMAGE$ AT sc.x1, sc.y1 SCALE 0.95 ANGLE 30

FIELD "info" TEXT "Data to be acquiered"

'color r g b -> cr, cg, cb array for the pixels
maxx = (2*(rr+1))^2
DIM cr(maxx) ! DIM cg(maxx) ! DIM cb(maxx)

'sin cos look up tables -> st / ct arrays
pi = ATN(1)*4
range = 360
DIM st(range+1) ! DIM ct(range+1)
FOR x = 0 TO range
  st(x) = SIN(x)
  ct(x) = COS(x)
NEXT x

'distance lookup-table
DIM distance_lut(rr+1,rr+1)
FOR x = 0 TO rr
  FOR y = 0 TO rr
    distance_lut(x,y) = SQRT(x^2 + y^2)
  NEXT y
NEXT x

'store picture color data, scale factor = 2
FOR x = -rr TO rr
  FOR y = -rr TO rr
    i += 1
    GET PIXEL x+2*sc.x1,y+2*sc.y1 COLOR cr(i),cg(i),cb(i)
  NEXT y
NEXT x

'draw rect of target (swirled data)
DRAW COLOR 1,1,1
DRAW SIZE 1
DRAW RECT tc.x1,tc.y1 SIZE 5+rr/2,5+rr/2

REFRESH OFF
LOOP:
a += angle_inc
FIELD "info" TEXT a
i = 0
FOR x = -rr TO rr 
  FOR y = -rr TO rr
    i += 1
    'limit swirl to circular shape
    distance = distance_lut(ABS(x),ABS(y))
    IF distance <= rr THEN
      ANGLE = INT(a*(rr-distance)/rr)
      rotatedx = x*ct(ANGLE) - y*st(ANGLE)
      rotatedy = x*st(ANGLE) + y*ct(ANGLE)
      DRAW PIXEL rotatedx+2*tc.x1, rotatedy+2*tc.y1 COLOR cr(i),cg(i),cb(i)
    END IF
  NEXT y
NEXT x
REFRESH
IF a < 360 THEN LOOP
P.S. There is no problem with reading pixel data directly into arrays.

Re: Sprite -Swirl- shaping

Posted: Thu Mar 10, 2016 4:53 pm
by Operator
:) Thanks for speed up by shifting the
refresh cmd. out of inner loop, but I prefer
to see that something is happening (my work
horse) is the slow iPhone 4 ...
I think in sB 4.6 or 4.7 I got an error when
storing the color data directly into an array...

Re: Sprite -Swirl- shaping

Posted: Fri Mar 11, 2016 3:26 am
by rbytes
Useful program. Thanks for porting it. I have been playing with it today and have a variation to show you. I capture each rendered frame into a sprite and then add them one-by-one to a sprite of the original image. There are 12 frames, and as each one is captured, it is previewed at half size on the left half of the screen.

You can watch the playback change as each new frame is added to the multi-frame sprite. I used SWAY mode, and it looks as though we are watching a mutant Ninja turtle doing calisthenics. As he warms up, he gets more and more flexible! :lol:

Code: Select all

REM Sprite Swirl Animation
REM iPad Air 1 / iPhone 5s / iOS 9.2.1 / by ricardobytes March 2016
REM Based on Swirl Effect,
REM ported out of: http://www.petesqbsite.com/sections/express/issue24/index.html#swirl
REM sB 5.3 / iPhone 4 / iOS 6.1 / by Operator
REM a bit slow, but no problem letting it render while you do other stuff!

OPTION IMAGE POS CENTRAL
OPTION SPRITE POS CENTRAL
OPTION ANGLE DEGREES
GRAPHICS
GRAPHICS CLEAR 0,0,0
scw.h = SCREEN_WIDTH()/2
sch.h = SCREEN_HEIGHT()/2

angle_inc = 30 'swirl-factor
rr = 200       '+/- HALF range/radius of
               'picture-pixels to be swirled, 
sc.x1 = scw.h  'x-centre of source image
sc.y1 = 120    'y-centre of source image
tc.x1 = scw.h  'x-centre of target image
tc.y1 = 400    'y-centre of target image

FIELD "info" TEXT "" AT 780,170 SIZE 200,20 RO
FIELD "info" FONT COLOR 1,1,1
FIELD "info" BACK ALPHA 0
FIELD "info1" TEXT "Multi-frame sprite" AT 770,440
FIELD "info1" BACK ALPHA 0
FIELD "info1" FONT COLOR 1,1,1
FIELD "info2" TEXT "in SWAY mode" AT 785,480
FIELD "info2" BACK ALPHA 0
FIELD "info2" FONT COLOR 1,1,1

'draw rect over source data, scale fac. 2
DRAW COLOR 1,1,1
DRAW RECT sc.x1,sc.y1 SIZE 1+rr/2,1+rr/2

'draw original image
IMAGE$ = "turtle.png"
DRAW IMAGE IMAGE$ AT sc.x1, sc.y1 'SCALE 0.95 'ANGLE 30
DRAW IMAGE IMAGE$ AT 510, 400 'SCALE 0.95 ANGLE 30
DRAW RECT tc.x1,tc.y1 SIZE 1+rr/2,1+rr/2
FIELD "info" TEXT "Data to be acquired"

'color r g b -> cr, cg, cb array for the pixels
maxx = (2*(rr+1))^2
DIM cr(maxx) ! DIM cg(maxx) ! DIM cb(maxx)

'sin cos look up tables -> st / ct arrays
pi = ATN(1)*4
range = 359
DIM st(range+1) ! DIM ct(range+1)
FOR x = 0 TO range
  st(x) = SIN(x)
  ct(x) = COS(x)
NEXT x

'distance lookup-table
DIM distance_lut(rr+1,rr+1)
FOR x = 0 TO rr
  FOR y = 0 TO rr
    distance_lut(x,y) = SQRT(x^2 + y^2)
  NEXT y
NEXT x

'store picture color data, scale factor = 2
FOR x = -rr TO rr
  FOR y = -rr TO rr
    i = i+1
    GET PIXEL x+2*sc.x1,y+2*sc.y1 COLOR r,g,b
    cr(i)=r ! cg(i)=g ! cb(i)=b
    ' get pixel can't store into array (?)
  NEXT y
NEXT x

'draw rect of target (swirled data)
DRAW COLOR 1,1,1
DRAW SIZE 1
DRAW RECT tc.x1,tc.y1 SIZE 1+rr/2,1+rr/2

FIELD "info" TEXT "Swirling Data..."
REFRESH OFF

'scan original image into a sprite
SPRITE "FrameAll" SCAN tc.x1-102,tc.y1-102,204,204
SPRITE "FrameAll" AT 850,310
SPRITE "FrameAll" COPY "Frame1"
SPRITE "FrameAll" SHOW
SPRITE "Frame1" AT 100,60 SCALE .5
SPRITE "Frame1" SHOW
SPRITE "FrameAll" DELAY .2
SPRITE "FrameAll" SWAY
DRAW TEXT "1" AT 25,50
FIELD "info" TEXT "Frame 1 "&" scanned"
frm=1!frm$=frm
FIELD "info3" TEXT "Total frames = "&frm$&"  " AT 775,520
FIELD "info3" BACK ALPHA 0
FIELD "info3" FONT COLOR 1,1,1
FILL COLOR 0,0,0
FILL RECT tc.x1,tc.y1 SIZE rr/2,rr/2

LOOP:
frm+=1
IF EVEN(frm) THEN rshift=110 ELSE rshift=0
frm$=frm
a = (a + angle_inc)%range
i=0
FOR x = -rr TO rr 
  FOR y = -rr TO rr
    i=i+1
    'limit swirl to circular shape
    distance = distance_lut(ABS(x),ABS(y))
    IF distance <= rr THEN
      ANGLE = INT(a*(rr-distance)/rr)
      rotatedx = x*ct(ANGLE) - y*st(ANGLE)
      rotatedy = x*st(ANGLE) + y*ct(ANGLE)
      DRAW PIXEL rotatedx+2*tc.x1, rotatedy+2*tc.y1 COLOR cr(i),cg(i),cb(i)
      END IF
    NEXT y
    REFRESH
  NEXT x
  FIELD "info" TEXT "Frame "&frm$&" scanned"
  FIELD "info3" TEXT "Total frames = "&frm$

  ' display each new sprite on screen left, and add it to sprite "FrameAll"
  SPRITE "Frame"&frm$ SCAN tc.x1-102,tc.y1-102,204,204
  SPRITE "Frame"&frm$ AT 100+rshift,60+(frm-1)*55 SCALE .5
  IF rshift THEN
    DRAW TEXT frm$ AT 160+rshift,50+(frm-1)*55
  ELSE
    DRAW TEXT frm$ AT 25,50+(frm-1)*55
  ENDIF
  REFRESH
  SPRITE "Frame"&frm$ SHOW
  SPRITE "FrameAll" ADD "Frame"&frm$
  
  'check for completion
  IF frm=12 THEN       ' at maximum swirl
    FIELD "complete" TEXT "Completed" AT 800,130
    PAUSE 3600         ' let play for 60 minutes
    END
  ENDIF
  FILL COLOR 0,0,0
  FILL RECT tc.x1,tc.y1 SIZE rr/2,rr/2
GOTO LOOP

Re: Sprite -Swirl- shaping

Posted: Sun Mar 13, 2016 5:37 pm
by rbytes
With the DRAW IN command, coming soon to smart BASIC, some perspective animation effects will be possible in real time, instead of taking about 80 seconds to render all the frames!