Cairo animated spiral

Post your FreeBASIC source, examples, tips and tricks here. Please don’t post code without including an explanation.
Roland Chastain
Posts: 1008
Joined: Nov 24, 2011 19:49
Location: France
Contact:

Cairo animated spiral

Post by Roland Chastain »

Hello everybody!

Here is a little thing I have made. It's an animated spiral using Cairo (idea taken here).

Warning: Don't keep your eyes fixed on the animation, otherwise you will feel dizzy. :)

Code: Select all

#include once "cairo/cairo.bi"

const WINDOW_W = 480
const WINDOW_H = 480

screenres WINDOW_W, WINDOW_H, 32

line (0, 0)-(WINDOW_W, WINDOW_H), rgb(192, 192, 192), BF

const IMAGE_W = 464
const IMAGE_H = 464

dim as any ptr image = imagecreate(IMAGE_W, IMAGE_H)
dim as any ptr pixels

imageinfo(image, IMAGE_W, IMAGE_H,,, pixels)

dim as long stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, IMAGE_W) ' https://www.freebasic.net/forum/viewtopic.php?p=215065#p215065
dim as cairo_surface_t ptr surface = cairo_image_surface_create_for_data(pixels, CAIRO_FORMAT_ARGB32, IMAGE_W, IMAGE_H, stride)

dim as cairo_t ptr context = cairo_create(surface)

const POINT_NUM = 180
const PI = 3.1415926535897932

sub DrawSpiral(surface as cairo_surface_t ptr, context as cairo_t ptr, angle_diff as double)
	cairo_set_source_rgb(context, 1, 1, 1)
	cairo_paint(context)
	cairo_set_source_rgb(context, 0, 0, 0)
  
	const POINT_RAD = 3
	const RADIUS_MAX = 216
	const CX = IMAGE_W \ 2
	const CY = IMAGE_H \ 2

	dim as double x, y
	dim as double angle = 0
	dim as double radius = 0
	dim as double radius_diff = RADIUS_MAX / POINT_NUM

	for i as integer = 1 to POINT_NUM
	  x = radius * cos(angle) + CX
	  y = radius * sin(angle) + CY
	  
	  cairo_arc(context, x, y, POINT_RAD, 0, 2 * PI)
	  cairo_fill(context)
	  
	  angle += angle_diff
	  radius += radius_diff
	next i
end sub

dim as double angle_diff = 0

const ANGLE_DIFF_DIFF = (PI / 180) / POINT_NUM
const DELAY = 10

do
  screenlock()
  DrawSpiral(surface, context, angle_diff)
  put (8, 8), image, PSET
  angle_diff += ANGLE_DIFF_DIFF
  screenunlock()
  sleep(DELAY)
loop until len(inkey)

cairo_destroy(context)
cairo_surface_destroy(surface)

imagedestroy image

sleep
Makoto WATANABE
Posts: 232
Joined: Apr 10, 2010 11:41
Location: Japan
Contact:

Re: Cairo animated spiral

Post by Makoto WATANABE »

I can't find the Cairo header in my environment.
Please tell me where I can get it.
I'm already dizzy before running the program.

FreeBASIC\bin\win32\ld.exe: cannot find -lcairo
srvaldez
Posts: 3390
Joined: Sep 25, 2005 21:54

Re: Cairo animated spiral

Post by srvaldez »

hello Makoto WATANABE :)
you are missing the cairo library, you can find an all-in-one cairo dll here https://github.com/preshing/cairo-windows/releases
just place the dll in the same location where your program resides
deltarho[1859]
Posts: 4315
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Re: Cairo animated spiral

Post by deltarho[1859] »

What would we do without srvaldez?

Image
UEZ
Posts: 996
Joined: May 05, 2017 19:59
Location: Germany

Re: Cairo animated spiral

Post by UEZ »

srvaldez wrote: Mar 27, 2024 13:25 hello Makoto WATANABE :)
you are missing the cairo library, you can find an all-in-one cairo dll here https://github.com/preshing/cairo-windows/releases
just place the dll in the same location where your program resides
What is the difference between 1.17.2 and 1.17.2-with-tee?

Is 1.17.2-with-tea the UK version? :lol:
Last edited by UEZ on Mar 28, 2024 7:28, edited 1 time in total.
srvaldez
Posts: 3390
Joined: Sep 25, 2005 21:54

Re: Cairo animated spiral

Post by srvaldez »

now I wish that I had the witty humor of Pete from the QB64 forum
deltarho[1859], I wondered what the tee was about but never curious enough to find out
deltarho[1859]
Posts: 4315
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Re: Cairo animated spiral

Post by deltarho[1859] »

Tee surface — Redirect input to multiple surfaces.
Makoto WATANABE
Posts: 232
Joined: Apr 10, 2010 11:41
Location: Japan
Contact:

Re: Cairo animated spiral

Post by Makoto WATANABE »

Dear srvaldez;

Thanks for your quick reply.
Thanks to you, I am free to feel dizzy.
I am now enjoying the animated spiral.
Roland Chastain
Posts: 1008
Joined: Nov 24, 2011 19:49
Location: France
Contact:

Re: Cairo animated spiral

Post by Roland Chastain »

Makoto WATANABE wrote: Mar 28, 2024 2:01 I am now enjoying the animated spiral.
The interesting point in this example (if I may say) is that it uses an image for drawing, instead of drawing directly on the screen (as do almost all examples that you can find in the forum).

I posted it here a version using sGUI2, where the animation can be started and stopped by pushing a button.
Muttonhead
Posts: 139
Joined: May 28, 2009 20:07

Re: Cairo animated spiral

Post by Muttonhead »

Yes it works :) , thanks for testing/using it.
Mutton
hhr
Posts: 216
Joined: Nov 29, 2019 10:41

Re: Cairo animated spiral

Post by hhr »

Interesting example. I wanted to know what Cairo was needed for and simply removed Cairo.
Without Cairo the points are shaking, with Cairo the points are calm.
This is achieved by transparency (or grayscale) in the outer pixels, which is why the dots appear smaller when Cairo is used.
But it's a mystery to me how to do that.

Code: Select all

const WINDOW_W = 480
const WINDOW_H = 480

screenres WINDOW_W, WINDOW_H, 32

line (0, 0)-(WINDOW_W, WINDOW_H), rgb(192, 192, 192), BF

const IMAGE_W = 464
const IMAGE_H = 464

dim shared as any ptr image

const POINT_NUM = 180
const PI = 4*atn(1)

sub DrawSpiral(angle_diff as double)
   const POINT_RAD = 3
   const RADIUS_MAX = 216
   const CX = IMAGE_W \ 2
   const CY = IMAGE_H \ 2
   
   dim as double x, y
   dim as double angle = 0
   dim as double radius = 0
   dim as double radius_diff = RADIUS_MAX / POINT_NUM
   
   for i as integer = 1 to POINT_NUM
      x = radius * cos(angle) + CX
      y = radius * sin(angle) + CY
      
      circle image,(x,y),POINT_RAD,0,,,,F
      
      angle += angle_diff
      radius += radius_diff
   next i
end sub

dim as double angle_diff = 0

const ANGLE_DIFF_DIFF = (PI / 180) / POINT_NUM
const DELAY = 10

do
   image = imagecreate(IMAGE_W, IMAGE_H, rgb(255,255,255))
   screenlock
   DrawSpiral(angle_diff)
   put (8, 8), image, pset
   angle_diff += ANGLE_DIFF_DIFF
   screenunlock
   sleep(DELAY)
   imagedestroy image
loop until len(inkey)

sleep
dafhi
Posts: 1673
Joined: Jun 04, 2005 9:51

Re: Cairo animated spiral

Post by dafhi »

now im inspired to make integer anti-aliased dots

a few have done integer non-aa lines, and they render fast
hhr
Posts: 216
Joined: Nov 29, 2019 10:41

Re: Cairo animated spiral

Post by hhr »

Compiling this takes a very long time. I don't know why this is the case.

Code: Select all

dim shared as any ptr image

'No transparency, only gray values.
'To determine the gray values, a power function abs(x)^exponent is used with the minimum at the exact coordinates.
'The gray values are read from the pixel coordinates.
function GrayScaleValue(a as double,b as double,POINT_RAD as byte) as double
   dim as double r = sqr(a*a+b*b),e = 2
   if r > POINT_RAD then r = POINT_RAD
   return 255 * ((r/POINT_RAD)^e)
end function

sub DrawPoint(x as double,y as double,POINT_RAD as byte)
   dim as double a,b,c,d,cd,i,j
   a = int(x)
   b = int(y)
   for i = -POINT_RAD to POINT_RAD
      for j = -POINT_RAD to POINT_RAD
         c = GrayScaleValue(i-x+a,j-y+b,POINT_RAD)
         
         'Determine the existing gray value of the pixel.
         'Because all color values are the same, only the red value is used.
         d = lobyte(hiword(point(a+i,b+j,image)))
         
         'Combine the two gray values.
         cd = c+(d-255)
         
         if cd < 0 then cd = 0
         pset image,(a+i,b+j),rgb(cd,cd,cd)
      next j
   next i
end sub

const WINDOW_W = 480
const WINDOW_H = 480

screenres WINDOW_W, WINDOW_H, 32

line (0, 0)-(WINDOW_W, WINDOW_H), rgb(192, 192, 192), BF

const IMAGE_W = 464
const IMAGE_H = 464



const POINT_NUM = 180
const PI = 4*atn(1)

sub DrawSpiral(angle_diff as double)
   dim as byte POINT_RAD = 3
   const RADIUS_MAX = 216
   const CX = IMAGE_W \ 2
   const CY = IMAGE_H \ 2
   
   dim as double x, y
   dim as double angle = 0
   dim as double radius = 0
   dim as double radius_diff = RADIUS_MAX / POINT_NUM
   
   for i as integer = 1 to POINT_NUM
      x = radius * cos(angle) + CX
      y = radius * sin(angle) + CY
      
      DrawPoint(x,y,POINT_RAD)
      
      angle += angle_diff
      radius += radius_diff
   next i
end sub

dim as double angle_diff = 0

const ANGLE_DIFF_DIFF = (PI / 180) / POINT_NUM
const DELAY = 10

do
   image = imagecreate(IMAGE_W, IMAGE_H, rgb(255,255,255))
   screenlock
   DrawSpiral(angle_diff)
   put (8, 8), image, pset
   angle_diff += ANGLE_DIFF_DIFF
   screenunlock
   sleep(DELAY)
   imagedestroy image
loop until len(inkey)
Last edited by hhr on May 10, 2024 17:55, edited 1 time in total.
UEZ
Posts: 996
Joined: May 05, 2017 19:59
Location: Germany

Re: Cairo animated spiral

Post by UEZ »

Try to turn off the AV program.
hhr
Posts: 216
Joined: Nov 29, 2019 10:41

Re: Cairo animated spiral

Post by hhr »

That was the problem, thank you.
Post Reply