|
| 1 | +! test2 |
| 2 | +! |
| 3 | +! We'll see in this test code |
| 4 | +! - Create a 480x480 image |
| 5 | +! - Set the background colour |
| 6 | +! - Move the origin coordinates to the centre of image |
| 7 | +! - Make the Y-axis increase from bottom to top |
| 8 | +! - Create an internal workspace 100x100 x=(-50:50), y=(-50,50) |
| 9 | +! - Draw axis and grid lines |
| 10 | +! - Plot a function i(t) = I|\cos(\omega t + \phi)| |
| 11 | +! - Draw a line |
| 12 | +! - Save the image to disk |
| 13 | + |
| 14 | +program test2 |
| 15 | +use cairo |
| 16 | +use cairo_enums |
| 17 | +use cairo_types, only: cairo_matrix_t |
| 18 | +use iso_c_binding, only: c_ptr, c_int, c_double, c_null_char, c_loc |
| 19 | + |
| 20 | +implicit none |
| 21 | +type(c_ptr) :: surface, c |
| 22 | +integer(c_int) :: r |
| 23 | +real(c_double), parameter :: IMAGE_WIDTH = 480.0d0 |
| 24 | +real(c_double), parameter :: IMAGE_HEIGHT = IMAGE_WIDTH |
| 25 | +real(c_double), parameter :: WORKSPACE_SIZE = 100.d0 |
| 26 | +real(c_double), parameter :: WORKSPACE_FACTOR = IMAGE_WIDTH/WORKSPACE_SIZE |
| 27 | +real(c_double), parameter :: WORKSPACE_HALF = WORKSPACE_SIZE/2.0d0 |
| 28 | +integer, parameter :: GRID_STEP = int(WORKSPACE_SIZE/10.0) |
| 29 | +integer, parameter :: NUM_POINTS = 500 |
| 30 | +real :: t(NUM_POINTS) |
| 31 | +real :: y(NUM_POINTS) |
| 32 | +real, parameter :: PLOT_STEP = real(WORKSPACE_SIZE)/NUM_POINTS |
| 33 | +type(cairo_matrix_t), target :: m |
| 34 | +integer :: i |
| 35 | + |
| 36 | +! Initialize |
| 37 | +surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, int(IMAGE_WIDTH), int(IMAGE_HEIGHT)) |
| 38 | +c = cairo_create(surface) |
| 39 | +call cairo_set_antialias(c, CAIRO_ANTIALIAS_BEST) |
| 40 | + |
| 41 | +! Set background colour |
| 42 | +call cairo_set_source_rgb(c, 0.05d0, 0.05d0, 0.05d0) |
| 43 | +call cairo_move_to(c, 0.d0, 0.d0) |
| 44 | +call cairo_rectangle(c, 0.d0, 0.d0, IMAGE_WIDTH, IMAGE_HEIGHT) |
| 45 | +call cairo_fill(c) |
| 46 | + |
| 47 | +! Move origin, invert Y-axis |
| 48 | +call cairo_matrix_init(c_loc(m), +WORKSPACE_FACTOR, 0.0d0, 0.0d0, -WORKSPACE_FACTOR, IMAGE_WIDTH/2.0d0, IMAGE_HEIGHT/2.0d0) |
| 49 | +call cairo_transform(c, c_loc(m)) |
| 50 | + |
| 51 | +! Draw grid |
| 52 | +do i = -int(WORKSPACE_HALF - GRID_STEP), int(WORKSPACE_HALF - GRID_STEP), GRID_STEP |
| 53 | + if (i .eq. 0) then |
| 54 | + call cairo_set_line_width(c, 0.25d0) |
| 55 | + call cairo_set_source_rgb(c, 1.0d0, 1.0d0, 1.0d0) |
| 56 | + else |
| 57 | + call cairo_set_line_width(c, 0.05d0) |
| 58 | + call cairo_set_source_rgb(c, 0.8d0, 0.8d0, 0.8d0) |
| 59 | + end if |
| 60 | + |
| 61 | + ! Vertical lines |
| 62 | + call cairo_move_to(c, real(i, kind=c_double), -WORKSPACE_HALF) |
| 63 | + call cairo_line_to(c, real(i, kind=c_double), +WORKSPACE_HALF) |
| 64 | + call cairo_stroke(c) |
| 65 | + |
| 66 | + ! Horizontal lines |
| 67 | + call cairo_move_to(c, -WORKSPACE_HALF, real(i, kind=c_double)) |
| 68 | + call cairo_line_to(c, +WORKSPACE_HALF, real(i, kind=c_double)) |
| 69 | + call cairo_stroke(c) |
| 70 | +end do |
| 71 | + |
| 72 | +! Poor man linspace() |
| 73 | +do i = 1, size(t) |
| 74 | + t(i) = -real(WORKSPACE_HALF) + PLOT_STEP*real(i) |
| 75 | +end do |
| 76 | + |
| 77 | +y = current(I=20.0, omega=0.22, t=t, phi=0.0) |
| 78 | + |
| 79 | +! Draw function points |
| 80 | +call cairo_set_line_width(c, 0.5d0) |
| 81 | +call cairo_set_source_rgb(c, 0.95d0, 0.0230d0, 0.95330d0) |
| 82 | +call cairo_move_to(c, real(t(1), kind=c_double), real(y(1), kind=c_double)) |
| 83 | +do i = 2, size(t) - 1 |
| 84 | + call cairo_line_to(c, real(t(i), kind=c_double), real(y(i), kind=c_double)) |
| 85 | +end do |
| 86 | +call cairo_stroke(c) |
| 87 | + |
| 88 | +! Draw Green Line |
| 89 | +call cairo_set_line_width(c, 1.0d0) |
| 90 | +call cairo_set_source_rgb(c, 0.05d0, 0.9230d0, 0.05330d0) |
| 91 | +call cairo_move_to(c, -40.d0, -40.d0) |
| 92 | +call cairo_line_to(c, 40.d0, -40.d0) |
| 93 | +call cairo_stroke(c) |
| 94 | + |
| 95 | +! Write .png |
| 96 | +r = cairo_surface_write_to_png(surface, "axis.png"//c_null_char) |
| 97 | + |
| 98 | +! Destroy |
| 99 | +call cairo_destroy(c) |
| 100 | +call cairo_surface_destroy(surface) |
| 101 | + |
| 102 | +contains |
| 103 | + |
| 104 | +elemental pure function current(I, omega, t, phi) result(r) |
| 105 | + real, intent(in) :: I |
| 106 | + real, intent(in) :: omega |
| 107 | + real, intent(in) :: t |
| 108 | + real, intent(in) :: phi |
| 109 | + real :: r |
| 110 | + |
| 111 | + r = I*abs(cos(omega*t + phi)) |
| 112 | +end function |
| 113 | + |
| 114 | +end program test2 |
0 commit comments