AKTIVE

selements.tcl at trunk
Login

selements.tcl at trunk

File etc/generator/virtual/pattern/selements.tcl artifact 5bb5fe9369 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
   102
   103
   104
   105
## -*- mode: tcl ; fill-column: 90 -*-
# # ## ### ##### ######## ############# #####################
## Generators -- Virtual Image - structuring elements for morphology
#
## - square
## - disc
## - circle
## - horizontal bar
## - vertical bar
## - axis-aligned cross (+)
## - main diagonal
## - cross (secondary) diagonal
## - diagonal-aligned cross (x)

# # ## ### ##### ######## ############# #####################

operator image::square {
    section generator virtual

    note Returns single-band white square with radius. Default radius 1.

    example {radius 32}

    uint? 1 radius	Radius of the square. Full size is 2*radius + 1.

    body {
	set size [expr {2 * $radius + 1}]
	aktive image from value width $size height $size depth 1 value 1
    }
}

# # ## ### ##### ######## ############# #####################

operator {desc w dw psetup ispixel} {
    image::cbar   {cross diagonal bar}      1 0 {}              { fabs (dx+dy) <= w }
    image::circle {circle (disc perimeter)} 1 1 { double rxy; } { rxy = hypot (dx, dy), ((r - w) <= rxy) && (rxy < r) }
    image::cross  cross                     1 0 {}              { (fabs (dx) <= w) || (fabs (dy) <= w) }
    image::dbar   {diagonal bar}            1 0 {}              { fabs (dx-dy) <= w }
    image::disc   {filled disc}             0 - {}              { hypot (dx, dy) < r }
    image::hbar   {horizontal bar}          1 0 {}              { fabs (dy) <= w }
    image::vbar   {vertical bar}            1 0 {}              { fabs (dx) <= w }
    image::xcross {diagonal cross}          1 0 {}              { (fabs (dx-dy) <= w) || (fabs (dx+dy) <= w) }
} {
    section generator virtual

    note Returns square single-band image containing a ${desc}. The image has size `2*radius + 1` squared.

    uint? 1 radius	Radius of the ${desc}.

    if {!$w} {
	example {radius 32}

	def wsetup {}
	def wcheck {}
    } else {
	example {radius 32 width 8}

	uint? $dw width	Width of the element. Default $dw. Has to be less or equal to the radius.

	def wsetup { aktive_uint w = param->width; }
	def wcheck {
	    if (param->radius < param->width) {
		aktive_failf ("width %u too large, not less than radius %u",
			      param->width, param->radius);
	    }
	}
    }

    state -setup  {
	@@wcheck@@
	aktive_uint size = 2 * param->radius + 1;
	aktive_geometry_set (domain, 0, 0, size, size, 1);
    }

    blit seblit {
	{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 {
	ISPIXEL (x, y, z)
    }}

    pixels {
	aktive_uint r = param->radius;
	TRACE("radius = %d", r);
	double dx, dy;
	@@wsetup@@
	@@psetup@@

	#define SD (idomain->depth)
	#define SH (idomain->height)
	#define SW (idomain->width)
	#define SX (request->x)
	#define SY (request->y)
	#define MID (r)
	#define ISPIXEL(x,y,z) (dx = x, dy = y, dx -= MID, dy -= MID, (@@ispixel@@) ? 1 : 0)
	@@seblit@@
	#undef ISPIXEL
	#undef MID
    }
}

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