AKTIVE

swirl.tcl at trunk
Login

swirl.tcl at trunk

File etc/generator/virtual/warp/swirl.tcl artifact 2d12949c67 on branch trunk


     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
   100
   101
## -*- mode: tcl ; fill-column: 90 -*-
# # ## ### ##### ######## ############# #####################
## Generators -- Virtual Image - Origin map of a swirl effect

operator warp::swirl {
    section generator virtual warp

    example {width 11 height 11 center {5 5} decay 1 | -matrix}

    note Returns the origin map for a swirl effect around the \
	specified __center__, with fixed rotation __phi__, \
	a base rotation __from__, and a __decay__ factor.

    note The rotation angle added to a pixel is given by \
	`phi + from * exp(-radius * decay)`, \
	where __radius__ is the distance of the pixel from the \
	__center__. A large decay reduces the swirl at shorter \
	radii. A decay of zero disables the decay.

    note All parameters except for the center are optional.

    note The result is designed to be usable with the \
	"<!xref: aktive op warp bicubic>" operation and its relatives.

    note At the technical level the result is a 2-band image \
	where each pixel declares its origin position.

    ref https://juliaimages.org/previews/PR218/examples/transformations/operations/swirl/

    # image configuration
    uint       width   Width of the returned image
    uint       height  Height of the returned image
    int?     0 x       X location of the returned image in the 2D plane
    int?     0 y       Y location of the returned image in the 2D plane

    # swirl configuration
    point        center Center of the swirl
    double?   0  phi    In degrees, fixed rotation to apply.
    double?  45  from   In degrees, swirl rotation at distance 0 from center.
    double? 0.1  decay  Rotation decay with distance from center.

    # see also effect::swirl, keep matching

    state -setup {
	aktive_geometry_set (domain, param->x, param->y, param->width, param->height, 2);
    }

    blit indexed {
	{AH {y AY 1 up} {y SY 1 up}}
	{AW {x AX 1 up} {x SX 1 up}}
	{DD {z  0 1 up} {z  0 1 up}}
    } {point { MAP }}

    pixels {
	#define SD (idomain->depth)
	#define SH (idomain->height)
	#define SW (idomain->width)
	#define SX (request->x)
        #define SY (request->y)

	double phi   = param->phi   * M_PI / 180.0 ;
	double base  = param->from  * M_PI / 180.0 ;
	double decay = param->decay;
	double cx    = param->center.x;
	double cy    = param->center.y;

	// fprintf(stderr, "ZZ phi    %f\n", phi);
	// fprintf(stderr, "ZZ base   %f\n", base);
	// fprintf(stderr, "ZZ decay  %f\n", decay);
	// fprintf(stderr, "ZZ center (%f, %f)\n", cx, cy);

	#define DX    (((int) srcx) - cx)
	#define DY    (((int) srcy) - cy)
	#define THETA (atan2 (DY, DX))
	#define RAD   (hypot (DX, DY))

	#define RHO   (THETA + phi + (base * exp(-RAD * decay)))
	#define U     (cx + RAD * cos (RHO))
	#define V     (cy + RAD * sin (RHO))

	#define MAP (srcz == 0) ? (U) : (V)

	// Note: Let the compiler sort out all the common expressions
	//       in the equations for U and V.

	@@indexed@@

	#undef DX
	#undef DY
	#undef THETA
	#undef RAD
	#undef RHO
	#undef U
	#undef V
	#undef MAP
    }
}

##
# # ## ### ##### ######## ############# #####################
::return