## -*- 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