AKTIVE

Check-in [dfc3fb00c0]
Login

Check-in [dfc3fb00c0]

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:feat: switched sdf element configuration to floating point (locations) where sensible note: IOW, sdf elements now can have fractional positions and dimensions relative to the pixel grid chore: updated examples and tests
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: dfc3fb00c079339f21a23be331af474ddf54c595c938dcb58dbd5bb968a60f6e
User & Date: aku 2025-03-28 22:22:06.567
Context
2025-03-28
22:25
chore: regenerated embedded docs check-in: 2660b263c6 user: aku tags: trunk
22:22
feat: switched sdf element configuration to floating point (locations) where sensible note: IOW, sdf elements now can have fractional positions and dimensions relative to the pixel grid chore: updated examples and tests check-in: dfc3fb00c0 user: aku tags: trunk
22:19
feat: new types for fractional (floating point) 2d locations and rectangles, plus basic functionality check-in: f854da796b user: aku tags: trunk
Changes
Unified Diff Ignore Whitespace Patch
Changes to etc/generator/virtual/sdf.tcl.
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
    note Note that a thickness of zero devolves this operation to a plain \
	outline.

    ref https://iquilezles.org/articles/distfunctions2d

    input

    uint thickness Desired border thickness.

    body {
	round [outline $src] radius $thickness
    }
}

operator op::sdf::outline {







|







249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
    note Note that a thickness of zero devolves this operation to a plain \
	outline.

    ref https://iquilezles.org/articles/distfunctions2d

    input

    double thickness Desired border thickness.

    body {
	round [outline $src] radius $thickness
    }
}

operator op::sdf::outline {
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
	SDF as the input to compensate the changes made by this operator.

    note A radius of zero is ignored.

    ref https://iquilezles.org/articles/distfunctions2d

    input
    uint radius Expansion/Shrinkage radius for the SDF.

    body {
	if {$radius == 0} { return $src }
	aktive op math1 shift $src offset [expr {- $radius}]
    }
}








|







301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
	SDF as the input to compensate the changes made by this operator.

    note A radius of zero is ignored.

    ref https://iquilezles.org/articles/distfunctions2d

    input
    double radius Expansion/Shrinkage radius for the SDF.

    body {
	if {$radius == 0} { return $src }
	aktive op math1 shift $src offset [expr {- $radius}]
    }
}

Changes to etc/generator/virtual/sdf/coding/box-rounded.tcl.
1
2







3
4
5
6
7
8
9

state -setup {







    aktive_geometry_set (domain, param->x, param->y, param->width, param->height, 1);
}

blit box-rounded-sdf {
    {AH {y AY 1 up} {y SY 1 up}}
    {AW {x AX 1 up} {x SX 1 up}}
} {point/2d {


>
>
>
>
>
>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

state -setup {
    if (param->ewidth          <= 0) aktive_fail("expected element width > 0");
    if (param->eheight         <= 0) aktive_fail("expected element height > 0");
    if (param->downrightradius  < 0) aktive_fail("expected down right radius >= 0");
    if (param->uprightradius    < 0) aktive_fail("expected up right radius >= 0");
    if (param->downleftradius   < 0) aktive_fail("expected down left radius >= 0");
    if (param->upleftradius     < 0) aktive_fail("expected up left radius >= 0");

    aktive_geometry_set (domain, param->x, param->y, param->width, param->height, 1);
}

blit box-rounded-sdf {
    {AH {y AY 1 up} {y SY 1 up}}
    {AW {x AX 1 up} {x SX 1 up}}
} {point/2d {
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
    double r[4];                    // <-/

    r[0] = param->downrightradius;
    r[1] = param->uprightradius;
    r[2] = param->downleftradius;
    r[3] = param->upleftradius;

    TRACE("center            = @%d,%d", param->center.x, param->center.y);
    TRACE("box width         =  %d", param->ewidth);
    TRACE("box height        =  %d", param->eheight);
    TRACE("up   left  radius =  %d", param->upleftradius);
    TRACE("up   right radius =  %d", param->uprightradius);
    TRACE("down left  radius =  %d", param->downleftradius);
    TRACE("down right radius =  %d", param->downrightradius);

    #define BOX(x,y) aktive_sdf_box_rounded (aktive_sdf_translate (x, y, cx, cy), w, h, r)
    #define SD         (idomain->depth)
    #define SH         (idomain->height)
    #define SW         (idomain->width)
    #define SX         (request->x)
    #define SY         (request->y)

    @@box-rounded-sdf@@

    #undef BOX
}







|
|
|
|
|
|
|












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
    double r[4];                    // <-/

    r[0] = param->downrightradius;
    r[1] = param->uprightradius;
    r[2] = param->downleftradius;
    r[3] = param->upleftradius;

    TRACE("center            = @%f,%f", param->center.x, param->center.y);
    TRACE("box width         =  %f", param->ewidth);
    TRACE("box height        =  %f", param->eheight);
    TRACE("up   left  radius =  %f", param->upleftradius);
    TRACE("up   right radius =  %f", param->uprightradius);
    TRACE("down left  radius =  %f", param->downleftradius);
    TRACE("down right radius =  %f", param->downrightradius);

    #define BOX(x,y) aktive_sdf_box_rounded (aktive_sdf_translate (x, y, cx, cy), w, h, r)
    #define SD         (idomain->depth)
    #define SH         (idomain->height)
    #define SW         (idomain->width)
    #define SX         (request->x)
    #define SY         (request->y)

    @@box-rounded-sdf@@

    #undef BOX
}
Changes to etc/generator/virtual/sdf/coding/box.tcl.
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

state -setup {


    aktive_geometry_set (domain, param->x, param->y, param->width, param->height, 1);
}

blit box-sdf {
    {AH {y AY 1 up} {y SY 1 up}}
    {AW {x AX 1 up} {x SX 1 up}}
} {point/2d {
    BOX (x, y)
}}

pixels {
    double w  = param->ewidth;
    double h  = param->eheight;
    double cx = param->center.x;
    double cy = param->center.y;

    TRACE("center     = @%d,%d", param->center.x, param->center.y);
    TRACE("box width  =  %d", param->ewidth);
    TRACE("box height =  %d", param->eheight);

    #define BOX(x,y) aktive_sdf_box (aktive_sdf_translate (x, y, cx, cy), w, h)
    #define SD         (idomain->depth)
    #define SH         (idomain->height)
    #define SW         (idomain->width)
    #define SX         (request->x)
    #define SY         (request->y)

    @@box-sdf@@

    #undef BOX
}


>
>
















|
|
|












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

state -setup {
    if (param->ewidth  <= 0) aktive_fail("expected element width > 0");
    if (param->eheight <= 0) aktive_fail("expected element height > 0");
    aktive_geometry_set (domain, param->x, param->y, param->width, param->height, 1);
}

blit box-sdf {
    {AH {y AY 1 up} {y SY 1 up}}
    {AW {x AX 1 up} {x SX 1 up}}
} {point/2d {
    BOX (x, y)
}}

pixels {
    double w  = param->ewidth;
    double h  = param->eheight;
    double cx = param->center.x;
    double cy = param->center.y;

    TRACE("center     = @%f,%f", param->center.x, param->center.y);
    TRACE("box width  =  %f", param->ewidth);
    TRACE("box height =  %f", param->eheight);

    #define BOX(x,y) aktive_sdf_box (aktive_sdf_translate (x, y, cx, cy), w, h)
    #define SD         (idomain->depth)
    #define SH         (idomain->height)
    #define SW         (idomain->width)
    #define SX         (request->x)
    #define SY         (request->y)

    @@box-sdf@@

    #undef BOX
}
Changes to etc/generator/virtual/sdf/coding/circle.tcl.
1

2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
state -setup {

    aktive_geometry_set (domain, param->x, param->y, param->width, param->height, 1);
}

blit circle-sdf {
    {AH {y AY 1 up} {y SY 1 up}}
    {AW {x AX 1 up} {x SX 1 up}}
} {point/2d {
    CIRCLE (x, y)
}}

pixels {
    double r  = param->radius;	// early cast to the type need during blit
    double cx = param->center.x;	// ditto
    double cy = param->center.y;	// ditto

    TRACE("center = @%d,%d", param->center.x, param->center.y);
    TRACE("radius = %d",     param->radius);

    #define CIRCLE(x,y) aktive_sdf_circle (aktive_sdf_translate (x, y, cx, cy), r)

>











|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
state -setup {
    if (param->radius <= 0) aktive_fail("expected radius > 0");
    aktive_geometry_set (domain, param->x, param->y, param->width, param->height, 1);
}

blit circle-sdf {
    {AH {y AY 1 up} {y SY 1 up}}
    {AW {x AX 1 up} {x SX 1 up}}
} {point/2d {
    CIRCLE (x, y)
}}

pixels {
    double r  = param->radius;		// early cast to the type need during blit
    double cx = param->center.x;	// ditto
    double cy = param->center.y;	// ditto

    TRACE("center = @%d,%d", param->center.x, param->center.y);
    TRACE("radius = %d",     param->radius);

    #define CIRCLE(x,y) aktive_sdf_circle (aktive_sdf_translate (x, y, cx, cy), r)
Changes to etc/generator/virtual/sdf/coding/circles.tcl.
1
2
3
4
5
6
7
8
9
10
11
12

13
14
15
16
17
18
19

if 0 {
    # binary tree of circles. heavy overhead due to the number of operators in play.
    body {
        aktive op sdf or {*}[lmap c $centers {
	    aktive image sdf circle x $x y $y width $width height $height \
	        radius $radius center $c
	}]
    }
}

state -setup {

    aktive_geometry_set (domain, param->x, param->y, param->width, param->height, 1);
}

blit circle-sdf {
    {AH {y AY 1 up} {y SY 1 up}}
    {AW {x AX 1 up} {x SX 1 up}}
} {point/2d {












>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

if 0 {
    # binary tree of circles. heavy overhead due to the number of operators in play.
    body {
        aktive op sdf or {*}[lmap c $centers {
	    aktive image sdf circle x $x y $y width $width height $height \
	        radius $radius center $c
	}]
    }
}

state -setup {
    if (param->radius <= 0) aktive_fail("expected radius > 0");
    aktive_geometry_set (domain, param->x, param->y, param->width, param->height, 1);
}

blit circle-sdf {
    {AH {y AY 1 up} {y SY 1 up}}
    {AW {x AX 1 up} {x SX 1 up}}
} {point/2d {
Changes to etc/generator/virtual/sdf/coding/line.tcl.
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
    {AH {y AY 1 up} {y SY 1 up}}
    {AW {x AX 1 up} {x SX 1 up}}
} {point/2d {
    SEGMENT (x, y)
}}

pixels {
    TRACE("from      = @%d,%d", param->from.x, param->from.y);
    TRACE("to        = @%d,%d", param->to.x,   param->to.y);
    TRACE("delta     = %f, %f", istate->spec.delta.x, istate->spec.delta.y);
    TRACE("dot.delta = %f",     istate->spec.ddot);

    #define SEGMENT(x,y) aktive_sdf_segment_precoded (x, y, &istate->spec)
    #define SD         (idomain->depth)
    #define SH         (idomain->height)
    #define SW         (idomain->width)







|
|







20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
    {AH {y AY 1 up} {y SY 1 up}}
    {AW {x AX 1 up} {x SX 1 up}}
} {point/2d {
    SEGMENT (x, y)
}}

pixels {
    TRACE("from      = @%f,%f", param->from.x, param->from.y);
    TRACE("to        = @%f,%f", param->to.x,   param->to.y);
    TRACE("delta     = %f, %f", istate->spec.delta.x, istate->spec.delta.y);
    TRACE("dot.delta = %f",     istate->spec.ddot);

    #define SEGMENT(x,y) aktive_sdf_segment_precoded (x, y, &istate->spec)
    #define SD         (idomain->depth)
    #define SH         (idomain->height)
    #define SW         (idomain->width)
Changes to etc/generator/virtual/sdf/coding/parallelogram.tcl.
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

state -setup {


    aktive_geometry_set (domain, param->x, param->y, param->width, param->height, 1);
}

blit parallelogram-sdf {
    {AH {y AY 1 up} {y SY 1 up}}
    {AW {x AX 1 up} {x SX 1 up}}
} {point/2d {
    PARALLELOGRAM (x, y)
}}

pixels {
    double w    = param->ewidth;
    double h    = param->eheight;
    double skew = param->eskew;
    double cx   = param->center.x;
    double cy   = param->center.y;

    TRACE("center               = @%d,%d", param->center.x, param->center.y);
    TRACE("parallelogram width  =  %d", param->ewidth);
    TRACE("parallelogram height =  %d", param->eheight);
    TRACE("parallelogram skew   =  %d", param->eskew);

    #define PARALLELOGRAM(x,y) aktive_sdf_parallelogram \
	(aktive_sdf_translate (x, y, cx, cy), \
	     w, h, skew)
    #define SD         (idomain->depth)
    #define SH         (idomain->height)
    #define SW         (idomain->width)


>
>

















|
|
|
|







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

state -setup {
    if (param->ewidth  <= 0) aktive_fail("expected element width > 0");
    if (param->eheight <= 0) aktive_fail("expected element height > 0");
    aktive_geometry_set (domain, param->x, param->y, param->width, param->height, 1);
}

blit parallelogram-sdf {
    {AH {y AY 1 up} {y SY 1 up}}
    {AW {x AX 1 up} {x SX 1 up}}
} {point/2d {
    PARALLELOGRAM (x, y)
}}

pixels {
    double w    = param->ewidth;
    double h    = param->eheight;
    double skew = param->eskew;
    double cx   = param->center.x;
    double cy   = param->center.y;

    TRACE("center               = @%f,%f", param->center.x, param->center.y);
    TRACE("parallelogram width  =  %f", param->ewidth);
    TRACE("parallelogram height =  %f", param->eheight);
    TRACE("parallelogram skew   =  %f", param->eskew);

    #define PARALLELOGRAM(x,y) aktive_sdf_parallelogram \
	(aktive_sdf_translate (x, y, cx, cy), \
	     w, h, skew)
    #define SD         (idomain->depth)
    #define SH         (idomain->height)
    #define SW         (idomain->width)
Changes to etc/generator/virtual/sdf/coding/rhombus.tcl.
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
state -setup {


    aktive_geometry_set (domain, param->x, param->y, param->width, param->height, 1);
}

blit rhombus-sdf {
    {AH {y AY 1 up} {y SY 1 up}}
    {AW {x AX 1 up} {x SX 1 up}}
} {point/2d {
    RHOMBUS (x, y)
}}

pixels {
    double w  = param->ewidth;
    double h  = param->eheight;
    double cx = param->center.x;
    double cy = param->center.y;

    TRACE("center         = @%d,%d", param->center.x, param->center.y);
    TRACE("rhombus width  =  %d", param->ewidth);
    TRACE("rhombus height =  %d", param->eheight);

    #define RHOMBUS(x,y) aktive_sdf_rhombus (aktive_sdf_translate (x, y, cx, cy), w, h)
    #define SD         (idomain->depth)
    #define SH         (idomain->height)
    #define SW         (idomain->width)
    #define SX         (request->x)
    #define SY         (request->y)

    @@rhombus-sdf@@

    #undef RHOMBUS
}

>
>
















|
|
|












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
state -setup {
    if (param->ewidth  <= 0) aktive_fail("expected element width > 0");
    if (param->eheight <= 0) aktive_fail("expected element height > 0");
    aktive_geometry_set (domain, param->x, param->y, param->width, param->height, 1);
}

blit rhombus-sdf {
    {AH {y AY 1 up} {y SY 1 up}}
    {AW {x AX 1 up} {x SX 1 up}}
} {point/2d {
    RHOMBUS (x, y)
}}

pixels {
    double w  = param->ewidth;
    double h  = param->eheight;
    double cx = param->center.x;
    double cy = param->center.y;

    TRACE("center         = @%f,%f", param->center.x, param->center.y);
    TRACE("rhombus width  =  %f", param->ewidth);
    TRACE("rhombus height =  %f", param->eheight);

    #define RHOMBUS(x,y) aktive_sdf_rhombus (aktive_sdf_translate (x, y, cx, cy), w, h)
    #define SD         (idomain->depth)
    #define SH         (idomain->height)
    #define SW         (idomain->width)
    #define SX         (request->x)
    #define SY         (request->y)

    @@rhombus-sdf@@

    #undef RHOMBUS
}
Changes to etc/generator/virtual/sdf/definitions.tcl.
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
sdf-def polyline {set of lines}
sdf-def rhombus
sdf-def triangle

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

proc sdf-whc {} {
    uint? 1  ewidth   Element width
    uint? 1  eheight  Element height
    sdf-centered
}

proc sdf-centered {} {
    point    center   Element center
    # TODO: rotation, scaling
}

proc sdf-common-params {} {
    uint     width   Image width
    uint     height  Image height
    int?  0  x       Image location, X coordinate







|
|




|







13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
sdf-def polyline {set of lines}
sdf-def rhombus
sdf-def triangle

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

proc sdf-whc {} {
    double? 1 ewidth   Element width
    double? 1 eheight  Element height
    sdf-centered
}

proc sdf-centered {} {
    fpoint   center   Element center
    # TODO: rotation, scaling
}

proc sdf-common-params {} {
    uint     width   Image width
    uint     height  Image height
    int?  0  x       Image location, X coordinate
Changes to etc/generator/virtual/sdf/note.tcl.
1
2
3
4

note Beware, the location and size of the $element are independent of image location and \
    dimensions. The operator is perfectly fine computing the SDF of a $element located \
    completely outside of the image domain.

|
|
|
1
2
3
4

note __Beware__. The location and size of the $element are independent of image location \
    and dimensions. The operator is perfectly fine computing the SDF of a $element \
    located completely outside of the image domain.
Changes to etc/generator/virtual/sdf/parameter/box-rounded.tcl.
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
note The box is axis-aligned, of width `2*ewidth+1`, height `2*eheight+1`, \
    with rounded corners per the radii, and placed at the specified center.

if {$mode eq "sdf"} {
    # core sdf
    example {
	center {64 64} width 128 height 128 ewidth 32 eheight 32 | sdf-fit ; sdf-smooth ; sdf-pixelated
    }
    example {
	center {64 64} width 128 height 128 ewidth 32 eheight 32 upleftradius 32 | sdf-fit ; sdf-smooth ; sdf-pixelated
    }
} elseif {$on} {
    # draw on
    example {
	butterfly
	@1 center {64 64} ewidth 32 eheight 32 upleftradius 32 outlined 1 color {1 0 0}
    }
} else {
    # just draw
    example {
	center {64 64} width 128 height 128 ewidth 32 eheight 32
    }
    example {
	center {64 64} width 128 height 128 ewidth 32 eheight 32 upleftradius 32 outlined 1
    }
    example {
	center {64 64} width 128 height 128 ewidth 32 eheight 32 upleftradius 32 antialiased 0
    }
}

uint? 0  upleftradius     Radius of element at upper left corner
uint? 0  uprightradius    Radius of element at upper right corner
uint? 0  downleftradius   Radius of element at lower left corner
uint? 0  downrightradius  Radius of element at lower right corner

note The radii default to 0, i.e. no rounded corners.

sdf-whc






|


|





|




|


|


|



|
|
|
|




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
note The box is axis-aligned, of width `2*ewidth+1`, height `2*eheight+1`, \
    with rounded corners per the radii, and placed at the specified center.

if {$mode eq "sdf"} {
    # core sdf
    example {
	center {64.25 64.75} width 128 height 128 ewidth 32.2 eheight 32.8 | sdf-fit ; sdf-smooth ; sdf-pixelated
    }
    example {
	center {64.25 64.75} width 128 height 128 ewidth 32.2 eheight 32.8 upleftradius 32.32 | sdf-fit ; sdf-smooth ; sdf-pixelated
    }
} elseif {$on} {
    # draw on
    example {
	butterfly
	@1 center {64.25 64.75} ewidth 32.2 eheight 32.8 upleftradius 32.32 outlined 1.1 color {1 0 0}
    }
} else {
    # just draw
    example {
	center {64.25 64.75} width 128 height 128 ewidth 32.2 eheight 32.8
    }
    example {
	center {64.25 64.75} width 128 height 128 ewidth 32.2 eheight 32.8 upleftradius 32.32 outlined 1.1
    }
    example {
	center {64.25 64.75} width 128 height 128 ewidth 32.2 eheight 32.8 upleftradius 32.32 antialiased 0
    }
}

double? 0  upleftradius     Radius of element at upper left corner
double? 0  uprightradius    Radius of element at upper right corner
double? 0  downleftradius   Radius of element at lower left corner
double? 0  downrightradius  Radius of element at lower right corner

note The radii default to 0, i.e. no rounded corners.

sdf-whc
Changes to etc/generator/virtual/sdf/parameter/box.tcl.
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
note The box is axis-aligned, of width `2*ewidth+1`, height `2*eheight+1`, \
    and placed at the specified center.

sdf-whc

if {$mode eq "sdf"} {
    # core sdf
    example {
	center {64 64} width 128 height 128 ewidth 32 eheight 32 | sdf-fit ; sdf-smooth ; sdf-pixelated
    }
} elseif {$on} {
    # draw on
    example {
	butterfly
	@1 center {64 64} ewidth 32 eheight 32 color {1 0 0} outlined 1
    }
} else {
    # just draw
    example {
	center {64 64} width 128 height 128 ewidth 32 eheight 32
    }
    example {
	center {64 64} width 128 height 128 ewidth 32 eheight 32 outlined 1
    }
    example {
	center {64 64} width 128 height 128 ewidth 32 eheight 32 antialiased 0
    }
}









|





|




|


|


|



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
note The box is axis-aligned, of width `2*ewidth+1`, height `2*eheight+1`, \
    and placed at the specified center.

sdf-whc

if {$mode eq "sdf"} {
    # core sdf
    example {
	center {64.25 64.75} width 128 height 128 ewidth 32.2 eheight 32.8 | sdf-fit ; sdf-smooth ; sdf-pixelated
    }
} elseif {$on} {
    # draw on
    example {
	butterfly
	@1 center {64.25 64.75} ewidth 32.2 eheight 32.8 outlined 1.1 color {1 0 0}
    }
} else {
    # just draw
    example {
	center {64.25 64.75} width 128 height 128 ewidth 32.2 eheight 32.8
    }
    example {
	center {64.25 64.75} width 128 height 128 ewidth 32.2 eheight 32.8 outlined 1.1
    }
    example {
	center {64.25 64.75} width 128 height 128 ewidth 32.2 eheight 32.8 antialiased 0
    }
}

Changes to etc/generator/virtual/sdf/parameter/circle.tcl.
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
note The circle has the `radius`, and is placed at the specified center.


if {$mode eq "sdf"} {
    # core sdf
    example {
	center {64 64} width 128 height 128 radius 32 | sdf-fit ; sdf-smooth ; sdf-pixelated
    }
} elseif {$on} {
    # draw on
    example {
	butterfly
	@1 center {64 64} radius 32 color {1 0 0} outlined 1
    }
} else {
    # just draw
    example {
	center {64 64} width 128 height 128 radius 32
    }
    example {
	center {64 64} width 128 height 128 radius 32 outlined 1
    }
    example {
	center {64 64} width 128 height 128 radius 32 antialiased 0
    }
}

uint? 1  radius     Circle radius
sdf-centered






|





|




|


|


|



|

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
note The circle has the `radius`, and is placed at the specified center.


if {$mode eq "sdf"} {
    # core sdf
    example {
	center {64.25 64.75} width 128 height 128 radius 32.5 | sdf-fit ; sdf-smooth ; sdf-pixelated
    }
} elseif {$on} {
    # draw on
    example {
	butterfly
	@1 center {64.25 64.75} radius 32.5 color {1 0 0} outlined 1.1
    }
} else {
    # just draw
    example {
	center {64.25 64.75} width 128 height 128 radius 32.5
    }
    example {
	center {64.25 64.75} width 128 height 128 radius 32.5 outlined 1.1
    }
    example {
	center {64.25 64.75} width 128 height 128 radius 32.5 antialiased 0
    }
}

double? 1  radius     Circle radius
sdf-centered
Changes to etc/generator/virtual/sdf/parameter/circles.tcl.
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
# multi-element, no common center, angling, scaling

note The circles all have the same `radius`, and are placed at the specified centers.

uint? 1  radius     Circle radius
point... centers    Circle centers

if {$mode eq "sdf"} {
    # core sdf
    example {
	width 128 height 128 radius 8 centers {10 10} {30 80} {80 30} | sdf-fit ; sdf-smooth ; sdf-pixelated
    }
} elseif {$on} {
    # draw on
    example {
	butterfly
	@1 radius 8 color {1 0 0} outlined 1 centers {10 10} {30 80} {80 30}
    }
} else {
    # just draw
    example {
	width 128 height 128 radius 8 centers {10 10} {30 80} {80 30}
    }
    example {
	width 128 height 128 radius 8 outlined 1 centers {10 10} {30 80} {80 30}
    }
    example {
	width 128 height 128 radius 8 antialiased 0 centers {10 10} {30 80} {80 30}
    }
}




|
|




|





|




|


|


|


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
# multi-element, no common center, angling, scaling

note The circles all have the same `radius`, and are placed at the specified centers.

double? 1 radius     Circle radius
fpoint... centers    Circle centers

if {$mode eq "sdf"} {
    # core sdf
    example {
	width 128 height 128 radius 8 centers {10.25 10.75} {30.3 80.6} {80.1 30.9} | sdf-fit ; sdf-smooth ; sdf-pixelated
    }
} elseif {$on} {
    # draw on
    example {
	butterfly
	@1 radius 8 color {1 0 0} outlined 1.1 centers {10.25 10.75} {30.3 80.6} {80.1 30.9}
    }
} else {
    # just draw
    example {
	width 128 height 128 radius 8 centers {10.25 10.75} {30.3 80.6} {80.1 30.9}
    }
    example {
	width 128 height 128 radius 8 outlined 1.1 centers {10.25 10.75} {30.3 80.6} {80.1 30.9}
    }
    example {
	width 128 height 128 radius 8 antialiased 0 centers {10.25 10.75} {30.3 80.6} {80.1 30.9}
    }
}
Changes to etc/generator/virtual/sdf/parameter/line.tcl.
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
# single element without center, angling, scaling

note The line connects the two specified locations.

point    from  Starting location
point    to    End location

if {$mode eq "sdf"} {
    # core sdf
    example {
	width 128 height 128 from {10 10} to {30 80} | sdf-fit ; sdf-smooth ; sdf-pixelated
    }
} elseif {$on} {
    # draw on
    example {
	butterfly
	@1 from {10 10} to {30 80} color {1 0 0} strokewidth 1
    }
} else {
    # just draw
    example {
	width 128 height 128 from {10 10} to {30 80}
    }
    example {
	width 128 height 128 from {10 10} to {30 80} strokewidth 1
    }
    example {
	width 128 height 128 from {10 10} to {30 80} antialiased 0
    }
}




|
|




|





|




|


|


|


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
# single element without center, angling, scaling

note The line connects the two specified locations.

fpoint   from  Starting location
fpoint   to    End location

if {$mode eq "sdf"} {
    # core sdf
    example {
	width 128 height 128 from {10.1 10.9} to {30.3 80.6} | sdf-fit ; sdf-smooth ; sdf-pixelated
    }
} elseif {$on} {
    # draw on
    example {
	butterfly
	@1 from {10.1 10.9} to {30.3 80.6} color {1 0 0} strokewidth 1.1
    }
} else {
    # just draw
    example {
	width 128 height 128 from {10.1 10.9} to {30.3 80.6}
    }
    example {
	width 128 height 128 from {10.1 10.9} to {30.3 80.6} strokewidth 1.1
    }
    example {
	width 128 height 128 from {10.1 10.9} to {30.3 80.6} antialiased 0
    }
}
Changes to etc/generator/virtual/sdf/parameter/outlined.tcl.
1
2
3
4

5
6
7
8
9

uint? 0 outlined	Outline thickness. Draw filled if zero (Default).

def modifier {

    if {$outlined != 0} {
	set outlined [expr {$outlined - [tcl::mathfunc::sign $outlined]}]
	set sdf [aktive op sdf ring $sdf thickness $outlined]
    }
}

|


>
|




1
2
3
4
5
6
7
8
9
10

double? 0 outlined	Outline thickness. Draw filled if zero (Default).

def modifier {
    if {$outlined < 0} { aktive error "expected an outline thickness >= 0" }
    if {$outlined > 0} {
	set outlined [expr {$outlined - [tcl::mathfunc::sign $outlined]}]
	set sdf [aktive op sdf ring $sdf thickness $outlined]
    }
}
Changes to etc/generator/virtual/sdf/parameter/parallelogram.tcl.
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
note The parallelogram is axis-aligned, of width `2*ewidth+1`, height `2*eheight+1`, \
    skewed by `eskew`, and placed at the specified center.

uint? 1  eskew    Element skew
sdf-whc

if {$mode eq "sdf"} {
    # core sdf
    example {
	center {64 64} width 128 height 128 ewidth 32 eheight 32 eskew 8 | sdf-fit ; sdf-smooth ; sdf-pixelated
    }
} elseif {$on} {
    # draw on
    example {
	butterfly
	@1 center {64 64} ewidth 32 eheight 32 eskew 8 color {1 0 0} outlined 1
    }
} else {
    # just draw
    example {
	center {64 64} width 128 height 128 ewidth 32 eheight 32 eskew 8
    }
    example {
	center {64 64} width 128 height 128 ewidth 32 eheight 32 eskew 8 outlined 1
    }
    example {
	center {64 64} width 128 height 128 ewidth 32 eheight 32 eskew 8 antialiased 0
    }
}



|





|





|




|


|


|


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
note The parallelogram is axis-aligned, of width `2*ewidth+1`, height `2*eheight+1`, \
    skewed by `eskew`, and placed at the specified center.

double? 1  eskew    Element skew
sdf-whc

if {$mode eq "sdf"} {
    # core sdf
    example {
	center {64.25 64.75} width 128 height 128 ewidth 32.2 eheight 32.8 eskew 8.1 | sdf-fit ; sdf-smooth ; sdf-pixelated
    }
} elseif {$on} {
    # draw on
    example {
	butterfly
	@1 center {64.25 64.75} ewidth 32.2 eheight 32.8 eskew 8.1 color {1 0 0} outlined 1.1
    }
} else {
    # just draw
    example {
	center {64.25 64.75} width 128 height 128 ewidth 32.2 eheight 32.8 eskew 8.1
    }
    example {
	center {64.25 64.75} width 128 height 128 ewidth 32.2 eheight 32.8 eskew 8.1 outlined 1.1
    }
    example {
	center {64.25 64.75} width 128 height 128 ewidth 32.2 eheight 32.8 eskew 8.1 antialiased 0
    }
}
Changes to etc/generator/virtual/sdf/parameter/polyline.tcl.
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
# multi-element, no common center, angling, scaling

note The lines form a polyline through the specified points.

point... points    Points of the poly-line

if {$mode eq "sdf"} {
    # core sdf
    example {
	width 128 height 128 points {10 10} {30 80} {80 30} | sdf-fit ; sdf-smooth ; sdf-pixelated
    }
} elseif {$on} {
    # draw on
    example {
	butterfly
	@1 color {1 0 0} strokewidth 1 points {10 10} {30 80} {80 30}
    }
} else {
    # just draw
    example {
	width 128 height 128 points {10 10} {30 80} {80 30}
    }
    example {
	width 128 height 128 strokewidth 1 points {10 10} {30 80} {80 30}
    }
    example {
	width 128 height 128 antialiased 0 points {10 10} {30 80} {80 30}
    }
}




|




|





|




|


|


|


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
# multi-element, no common center, angling, scaling

note The lines form a polyline through the specified points.

fpoint... points   Points of the poly-line

if {$mode eq "sdf"} {
    # core sdf
    example {
	width 128 height 128 points {10.25 10.75} {30.3 80.6} {80.1 30.9} | sdf-fit ; sdf-smooth ; sdf-pixelated
    }
} elseif {$on} {
    # draw on
    example {
	butterfly
	@1 color {1 0 0} strokewidth 1.1 points {10.25 10.75} {30.3 80.6} {80.1 30.9}
    }
} else {
    # just draw
    example {
	width 128 height 128 points {10.25 10.75} {30.3 80.6} {80.1 30.9}
    }
    example {
	width 128 height 128 strokewidth 1.1 points {10.25 10.75} {30.3 80.6} {80.1 30.9}
    }
    example {
	width 128 height 128 antialiased 0 points {10.25 10.75} {30.3 80.6} {80.1 30.9}
    }
}
Changes to etc/generator/virtual/sdf/parameter/rhombus.tcl.
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
note The rhombus is axis-aligned, of width `2*ewidth+1`, height `2*eheight+1`, \
    and placed at the specified center.

sdf-whc

if {$mode eq "sdf"} {
    # core sdf
    example {
	center {64 64} width 128 height 128 ewidth 32 eheight 32 | sdf-fit ; sdf-smooth ; sdf-pixelated
    }
} elseif {$on} {
    # draw on
    example {
	butterfly
	@1 center {64 64} ewidth 32 eheight 32 outlined 1 color {1 0 0} outlined 1
    }
} else {
    # just draw
    example {
	center {64 64} width 128 height 128 ewidth 32 eheight 32
    }
    example {
	center {64 64} width 128 height 128 ewidth 32 eheight 32 outlined 1
    }
    example {
	center {64 64} width 128 height 128 ewidth 32 eheight 32 antialiased 0
    }
}








|





|




|


|


|


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
note The rhombus is axis-aligned, of width `2*ewidth+1`, height `2*eheight+1`, \
    and placed at the specified center.

sdf-whc

if {$mode eq "sdf"} {
    # core sdf
    example {
	center {64.25 64.75} width 128 height 128 ewidth 32.2 eheight 32.8 | sdf-fit ; sdf-smooth ; sdf-pixelated
    }
} elseif {$on} {
    # draw on
    example {
	butterfly
	@1 center {64.25 64.75} ewidth 32.2 eheight 32.8 outlined 1.1 color {1 0 0} outlined 1
    }
} else {
    # just draw
    example {
	center {64.25 64.75} width 128 height 128 ewidth 32.2 eheight 32.8
    }
    example {
	center {64.25 64.75} width 128 height 128 ewidth 32.2 eheight 32.8 outlined 1.1
    }
    example {
	center {64.25 64.75} width 128 height 128 ewidth 32.2 eheight 32.8 antialiased 0
    }
}
Changes to etc/generator/virtual/sdf/parameter/strokewidth.tcl.
1
2
3
4

5
6

uint? 0 strokewidth	Stroke width. Lines are `2*strokewidth+1` wide.

def modifier {

    if {$strokewidth != 0} { set sdf [aktive op sdf round $sdf radius $strokewidth] }
}

|


>
|

1
2
3
4
5
6
7

double? 0 strokewidth	Stroke width. Lines are `2*strokewidth+1` wide.

def modifier {
    if {$strokewidth < 0} { aktive error "expected a stroke width >= 0" }
    if {$strokewidth > 0} { set sdf [aktive op sdf round $sdf radius $strokewidth] }
}
Changes to etc/generator/virtual/sdf/parameter/triangle.tcl.
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
# single element without center, angling, scaling

note The triangle connects the points A, B, and C, in this order.

point    a          Triangle point A
point    b          Triangle point B
point    c          Triangle point C

if {$mode eq "sdf"} {
    # core sdf
    example {
	width 128 height 128 a {10 10} b {30 80} c {80 30} | sdf-fit ; sdf-smooth ; sdf-pixelated
    }
} elseif {$on} {
    # draw on
    example {
	butterfly
	@1 a {10 10} b {30 80} c {80 30} color {1 0 0} outlined 1
    }
} else {
    # just draw
    example {
	width 128 height 128 a {10 10} b {30 80} c {80 30}
    }
    example {
	width 128 height 128 a {10 10} b {30 80} c {80 30} outlined 1
    }
    example {
	width 128 height 128 a {10 10} b {30 80} c {80 30} antialiased 0
    }
}





|
|
|




|





|




|


|


|



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
# single element without center, angling, scaling

note The triangle connects the points A, B, and C, in this order.

fpoint   a          Triangle point A
fpoint   b          Triangle point B
fpoint   c          Triangle point C

if {$mode eq "sdf"} {
    # core sdf
    example {
	width 128 height 128 a {10.25 10.75} b {30.2 80.6} c {80.1 30.9} | sdf-fit ; sdf-smooth ; sdf-pixelated
    }
} elseif {$on} {
    # draw on
    example {
	butterfly
	@1 a {10.25 10.75} b {30.2 80.6} c {80.1 30.9} color {1 0 0} outlined 1.1
    }
} else {
    # just draw
    example {
	width 128 height 128 a {10.25 10.75} b {30.2 80.6} c {80.1 30.9}
    }
    example {
	width 128 height 128 a {10.25 10.75} b {30.2 80.6} c {80.1 30.9} outlined 1.1
    }
    example {
	width 128 height 128 a {10.25 10.75} b {30.2 80.6} c {80.1 30.9} antialiased 0
    }
}

Changes to etc/runtime.tcl.
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
# -*- mode: tcl ; fill-column: 90 -*-
# # ## ### ##### ######## ############# #####################
## Core runtime definitions
## Separately processed.

# # ## ### ##### ######## ############# #####################
## Types for parameters and results

# __ id __________ critcl ___________    C type _______ Conversion ______________________________
type point         aktive_point          -              {aktive_new_point_obj (value)}
type range         aktive_range          -              {aktive_new_range_obj (value)}
type rect          aktive_rectangle      -              {aktive_new_rectangle_obj (value)}
type geometry      aktive_geometry       -              {aktive_new_geometry_obj (value)}


type image-type    aktive_image_type_ptr -              {Tcl_NewStringObj ((*value)->name, -1)}
type image         aktive_image          -              {aktive_new_image_obj (*value)}
type region        aktive_region         -              {0 /* INTERNAL -- No Tcl_Obj* equivalent */}
type uint          aktive_uint           -              {aktive_new_uint_obj (*value)}
type double        -                     -              {Tcl_NewDoubleObj (*value)}
type str           aktive_string         aktive_string  {Tcl_NewStringObj (*value, -1)}

vector region image point range rect uint double str

# # ## ### ##### ######## ############# #####################
## Generally useful blocks of code

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













>
>







|







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
# -*- mode: tcl ; fill-column: 90 -*-
# # ## ### ##### ######## ############# #####################
## Core runtime definitions
## Separately processed.

# # ## ### ##### ######## ############# #####################
## Types for parameters and results

# __ id __________ critcl ___________    C type _______ Conversion ______________________________
type point         aktive_point          -              {aktive_new_point_obj (value)}
type range         aktive_range          -              {aktive_new_range_obj (value)}
type rect          aktive_rectangle      -              {aktive_new_rectangle_obj (value)}
type geometry      aktive_geometry       -              {aktive_new_geometry_obj (value)}
type fpoint        aktive_fpoint         -              {aktive_new_fpoint_obj (value)}
type frect         aktive_frectangle     -              {aktive_new_frectangle_obj (value)}
type image-type    aktive_image_type_ptr -              {Tcl_NewStringObj ((*value)->name, -1)}
type image         aktive_image          -              {aktive_new_image_obj (*value)}
type region        aktive_region         -              {0 /* INTERNAL -- No Tcl_Obj* equivalent */}
type uint          aktive_uint           -              {aktive_new_uint_obj (*value)}
type double        -                     -              {Tcl_NewDoubleObj (*value)}
type str           aktive_string         aktive_string  {Tcl_NewStringObj (*value, -1)}

vector region image point range rect uint double str fpoint frect

# # ## ### ##### ######## ############# #####################
## Generally useful blocks of code

##
# # ## ### ##### ######## ############# #####################
::return
Changes to op/sdf.c.
1
2
3
4
5
6
7
8
9
10
/*
 * - - -- --- ----- -------- -------------
 ** (c) 2024 Andreas Kupries http://wiki.tcl.tk/andreas%20kupries
 *
 * -- signed distance functions
 */

#include <sdf.h>
#include <amath.h>



|







1
2
3
4
5
6
7
8
9
10
/*
 * - - -- --- ----- -------- -------------
 ** (c) 2024-2025 Andreas Kupries http://wiki.tcl.tk/andreas%20kupries
 *
 * -- signed distance functions
 */

#include <sdf.h>
#include <amath.h>

89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
}

double aktive_sdf_circle (double x, double y, double radius)
{
    return VLENGTH (x, y) - radius;
}

double aktive_sdf_polycircle (double x, double y, double radius, aktive_point_vector* centers)
{
    double mindist = INFINITY;
    aktive_uint k;
    for (k = 0; k < centers->c; k++) {
    	double d = aktive_sdf_circle (aktive_sdf_translate (x, y, centers->v[k].x, centers->v[k].y),
				      radius);
	mindist = MIN (mindist, d);







|







89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
}

double aktive_sdf_circle (double x, double y, double radius)
{
    return VLENGTH (x, y) - radius;
}

double aktive_sdf_polycircle (double x, double y, double radius, aktive_fpoint_vector* centers)
{
    double mindist = INFINITY;
    aktive_uint k;
    for (k = 0; k < centers->c; k++) {
    	double d = aktive_sdf_circle (aktive_sdf_translate (x, y, centers->v[k].x, centers->v[k].y),
				      radius);
	mindist = MIN (mindist, d);
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170

    double d  = VLENGTH (x - 0.5 * w * (1 - hh),
			 y - 0.5 * h * (1 + hh));

    return d * aktive_sign ( x*h + y*w - w*h );
}

double aktive_sdf_segment (double x, double y, AP from, AP to)
{
    // ref https://www.shadertoy.com/view/3tdSDj
    // ref https://www.youtube.com/watch?v=PMltMdi1Wzg
    //
    // line segment between the points FROM and TO
    //
    // optimization: pre-compute to-from, DOTSELF(to-from)







|







156
157
158
159
160
161
162
163
164
165
166
167
168
169
170

    double d  = VLENGTH (x - 0.5 * w * (1 - hh),
			 y - 0.5 * h * (1 + hh));

    return d * aktive_sign ( x*h + y*w - w*h );
}

double aktive_sdf_segment (double x, double y, APD from, APD to)
{
    // ref https://www.shadertoy.com/view/3tdSDj
    // ref https://www.youtube.com/watch?v=PMltMdi1Wzg
    //
    // line segment between the points FROM and TO
    //
    // optimization: pre-compute to-from, DOTSELF(to-from)
Changes to op/sdf.h.
1
2
3
4
5
6
7
8
9
10
/* -*- c -*-
 *
 ** (c) 2024 Andreas Kupries http://wiki.tcl.tk/andreas%20kupries
 *
 * -- Signed distance functions
 */
#ifndef AKTIVE_SDF_H
#define AKTIVE_SDF_H

#include <math.h>


|







1
2
3
4
5
6
7
8
9
10
/* -*- c -*-
 *
 ** (c) 2024-2025 Andreas Kupries http://wiki.tcl.tk/andreas%20kupries
 *
 * -- Signed distance functions
 */
#ifndef AKTIVE_SDF_H
#define AKTIVE_SDF_H

#include <math.h>
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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
 *
 * Examples:
 *  - A circle is rotation invariant.             Rotation makes no sense.
 *  - A circle's size is specified by its radius. Scaling is not necessary.
 */

#define AP  aktive_point*
#define APD aktive_point_d*

typedef struct aktive_point_d {
    double x;
    double y;
} aktive_point_d;

typedef struct aktive_segment_spec {
    aktive_point_d from;
    aktive_point_d delta;
    double         ddot;
} aktive_segment_spec;

typedef struct aktive_triangle_spec {
    aktive_point_d a;
    aktive_point_d b;
    aktive_point_d c;
    aktive_point_d ba;
    aktive_point_d cb;
    aktive_point_d ac;
    double         badot;
    double         cbdot;
    double         acdot;
    double         bacsign;
} aktive_triangle_spec;

#define aktive_sdf_hard(f) (fabs(f) < 0.5)
#define aktive_sdf_soft(f) (1 - fmax (0, fmin (1, fabs (f))))
/* soft has inlined aktive_clamp */

#define aktive_sdf_translate(x,y,cx,cy) (x)-(cx), (y)-(cy)
#define aktive_sdf_rotate(x,y,c,s)      ((x)*(c)-(y)*(s)), ((x)*(s)+(y)*(c))

#define aktive_sdf_annular(th,f) (fabs (f) - (th))
#define aktive_sdf_widen(th,f)   (fmax (0, aktive_sdf_annular (th, f)))

// R = /c -s\  | /x'\ = /c -s\ * /x\  | x' =  x*c - y*s
//     \s  c/  | \y'/   \s  c/   \y/  | y' =  x*s + y*c

double aktive_sdf_box                  (double x, double y, double w, double h);
double aktive_sdf_box_rounded          (double x, double y, double w, double h, double r[4]);
double aktive_sdf_circle               (double x, double y, double radius);
double aktive_sdf_polycircle           (double x, double y, double radius, aktive_point_vector* centers);
double aktive_sdf_parallelogram        (double x, double y, double w, double h, double skew);
double aktive_sdf_rhombus              (double x, double y, double w, double h);
double aktive_sdf_segment              (double x, double y, AP from, AP to);
double aktive_sdf_segment_precoded     (double x, double y, aktive_segment_spec* seg);
double aktive_sdf_polysegment_precoded (double x, double y, aktive_uint n, aktive_segment_spec* seg);
double aktive_sdf_triangle_precoded    (double x, double y, aktive_triangle_spec* tri);

// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
#if 0
double aktive_sdf_arc            (double x, double y, AP sc, double ra, double rb );		// https://www.shadertoy.com/view/wl23RK
double aktive_sdf_bezier         (double x, double y, AP a, AP b, AP c);			// https://www.shadertoy.com/view/MlKcDD

double aktive_sdf_box_oriented   (double x, double y, AP from, AP to, double thickness);	// https://www.shadertoy.com/view/stcfzn
double aktive_sdf_box_rounded    (double x, double y, double w, double h, double r);		// https://www.shadertoy.com/view/4llXD7
double aktive_sdf_cross          (double x, double y, AP b, double r);				// https://www.shadertoy.com/view/XtGfzw
double aktive_sdf_cross_blobby   (double x, double y, double he);				// https://www.shadertoy.com/view/NssXWM
double aktive_sdf_cross_rounded  (double x, double y, double h);				// https://www.shadertoy.com/view/NslXDM
double aktive_sdf_cut_disk       (double x, double y, double r, double h	);		// https://www.shadertoy.com/view/ftVXRc
double aktive_sdf_ellipse        (double x, double y, AP ab);					// https://www.shadertoy.com/view/4sS3zz
double aktive_sdf_hexagon        (double x, double y, double r);       				//
double aktive_sdf_hexagram       (double x, double y, double r);				// https://www.shadertoy.com/view/tt23RR
double aktive_sdf_octogon        (double x, double y, double r);				// https://www.shadertoy.com/view/llGfDG

double aktive_sdf_pentagon       (double x, double y, double r);				// https://www.shadertoy.com/view/llVyWW
double aktive_sdf_pie            (double x, double y, AP c, double r);				// https://www.shadertoy.com/view/3l23RK
double aktive_sdf_polygon        (double x, double y, AP* v, int n);				// https://www.shadertoy.com/view/wdBXRW
double aktive_sdf_quad_circle    (double x, double y);						// https://www.shadertoy.com/view/Nd3cW8

double aktive_sdf_ring           (double x, double y, AP n, double r, double th);		// https://www.shadertoy.com/view/DsccDH
double aktive_sdf_star           (double x, double y, double r, double n, double m);		// https://www.shadertoy.com/view/3tSGDy
double aktive_sdf_star5          (double x, double y, double r, double rf);			// https://www.shadertoy.com/view/3tSGDy
double aktive_sdf_trapezoid      (double x, double y, double r1, double r2, double h);		// https://www.shadertoy.com/view/MlycD3
double aktive_sdf_vesica_oriented(double x, double y, AP a, AP b, double  w);			// https://www.shadertoy.com/view/cs2yzG
double aktive_sdf_xcross_rounded (double x, double y, double w, double  r);			// https://www.shadertoy.com/view/3dKSDc
#endif

#if 0
double aktive_sdf_circle_wave    (double x, double y, double tb, double ra);			// https://www.shadertoy.com/view/stGyzt
double aktive_sdf_cool_s         (double x, double y);						// https://www.shadertoy.com/view/clVXWc
double aktive_sdf_egg            (double x, double y, double ra, double  rb);			// https://www.shadertoy.com/view/Wdjfz3
double aktive_sdf_heart          (double x, double y);						// https://www.shadertoy.com/view/3tyBzV
double aktive_sdf_horseshoe      (double x, double y, AP c, double r, AP w);			// https://www.shadertoy.com/view/WlSGW1
double aktive_sdf_hyperbola      (double x, double y, double k, double  he );	// 0 <= k <= inf   https://www.shadertoy.com/view/DtjXDG
double aktive_sdf_moon           (double x, double y, double d, double ra, double  rb);		// https://www.shadertoy.com/view/WtdBRS
double aktive_sdf_parabola       (double x, double y, double k);				// https://www.shadertoy.com/view/ws3GD7
double aktive_sdf_parabola_seg   (double x, double y, double wi, double  he);			// https://www.shadertoy.com/view/3lSczz
double aktive_sdf_stairs         (double x, double y, double w, double  h, double  n);		// https://www.shadertoy.com/view/7tKSWt
double aktive_sdf_triangle_equi  (double x, double y, double r);				// https://www.shadertoy.com/view/Xl2yDW
double aktive_sdf_triangle_isosc (double x, double y, AP q);					// https://www.shadertoy.com/view/MldcD7
double aktive_sdf_tunnel         (double x, double y, double w, double h  );			// https://www.shadertoy.com/view/flSSDy
double aktive_sdf_uneven_capsule (double x, double y, double r1, double r2, double h);		// https://www.shadertoy.com/view/4lcBWn
double aktive_sdf_vesica         (double x, double y, double r, double  d);			// https://www.shadertoy.com/view/XtVfRW
#endif

//double aktive_sdf_ (double x, double y  );
//double aktive_sdf_ (double x, double y  );







|

<
<
<
<
<

|
|
|



|
|
|
|
|
|
|
|
|
|


















|


|







|
|

|

|



|





|



|



|








|






|







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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
 *
 * Examples:
 *  - A circle is rotation invariant.             Rotation makes no sense.
 *  - A circle's size is specified by its radius. Scaling is not necessary.
 */

#define AP  aktive_point*
#define APD aktive_fpoint*






typedef struct aktive_segment_spec {
    aktive_fpoint from;
    aktive_fpoint delta;
    double        ddot;
} aktive_segment_spec;

typedef struct aktive_triangle_spec {
    aktive_fpoint a;
    aktive_fpoint b;
    aktive_fpoint c;
    aktive_fpoint ba;
    aktive_fpoint cb;
    aktive_fpoint ac;
    double        badot;
    double        cbdot;
    double        acdot;
    double        bacsign;
} aktive_triangle_spec;

#define aktive_sdf_hard(f) (fabs(f) < 0.5)
#define aktive_sdf_soft(f) (1 - fmax (0, fmin (1, fabs (f))))
/* soft has inlined aktive_clamp */

#define aktive_sdf_translate(x,y,cx,cy) (x)-(cx), (y)-(cy)
#define aktive_sdf_rotate(x,y,c,s)      ((x)*(c)-(y)*(s)), ((x)*(s)+(y)*(c))

#define aktive_sdf_annular(th,f) (fabs (f) - (th))
#define aktive_sdf_widen(th,f)   (fmax (0, aktive_sdf_annular (th, f)))

// R = /c -s\  | /x'\ = /c -s\ * /x\  | x' =  x*c - y*s
//     \s  c/  | \y'/   \s  c/   \y/  | y' =  x*s + y*c

double aktive_sdf_box                  (double x, double y, double w, double h);
double aktive_sdf_box_rounded          (double x, double y, double w, double h, double r[4]);
double aktive_sdf_circle               (double x, double y, double radius);
double aktive_sdf_polycircle           (double x, double y, double radius, aktive_fpoint_vector* centers);
double aktive_sdf_parallelogram        (double x, double y, double w, double h, double skew);
double aktive_sdf_rhombus              (double x, double y, double w, double h);
double aktive_sdf_segment              (double x, double y, APD from, APD to);
double aktive_sdf_segment_precoded     (double x, double y, aktive_segment_spec* seg);
double aktive_sdf_polysegment_precoded (double x, double y, aktive_uint n, aktive_segment_spec* seg);
double aktive_sdf_triangle_precoded    (double x, double y, aktive_triangle_spec* tri);

// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
#if 0
double aktive_sdf_arc            (double x, double y, APD sc, double ra, double rb );		// https://www.shadertoy.com/view/wl23RK
double aktive_sdf_bezier         (double x, double y, APD a, APD b, APD c);			// https://www.shadertoy.com/view/MlKcDD

double aktive_sdf_box_oriented   (double x, double y, APD from, APD to, double thickness);	// https://www.shadertoy.com/view/stcfzn
double aktive_sdf_box_rounded    (double x, double y, double w, double h, double r);		// https://www.shadertoy.com/view/4llXD7
double aktive_sdf_cross          (double x, double y, APD b, double r);				// https://www.shadertoy.com/view/XtGfzw
double aktive_sdf_cross_blobby   (double x, double y, double he);				// https://www.shadertoy.com/view/NssXWM
double aktive_sdf_cross_rounded  (double x, double y, double h);				// https://www.shadertoy.com/view/NslXDM
double aktive_sdf_cut_disk       (double x, double y, double r, double h	);		// https://www.shadertoy.com/view/ftVXRc
double aktive_sdf_ellipse        (double x, double y, APD ab);					// https://www.shadertoy.com/view/4sS3zz
double aktive_sdf_hexagon        (double x, double y, double r);       				//
double aktive_sdf_hexagram       (double x, double y, double r);				// https://www.shadertoy.com/view/tt23RR
double aktive_sdf_octogon        (double x, double y, double r);				// https://www.shadertoy.com/view/llGfDG

double aktive_sdf_pentagon       (double x, double y, double r);				// https://www.shadertoy.com/view/llVyWW
double aktive_sdf_pie            (double x, double y, APD c, double r);				// https://www.shadertoy.com/view/3l23RK
double aktive_sdf_polygon        (double x, double y, AP* v, int n);				// https://www.shadertoy.com/view/wdBXRW
double aktive_sdf_quad_circle    (double x, double y);						// https://www.shadertoy.com/view/Nd3cW8

double aktive_sdf_ring           (double x, double y, APD n, double r, double th);		// https://www.shadertoy.com/view/DsccDH
double aktive_sdf_star           (double x, double y, double r, double n, double m);		// https://www.shadertoy.com/view/3tSGDy
double aktive_sdf_star5          (double x, double y, double r, double rf);			// https://www.shadertoy.com/view/3tSGDy
double aktive_sdf_trapezoid      (double x, double y, double r1, double r2, double h);		// https://www.shadertoy.com/view/MlycD3
double aktive_sdf_vesica_oriented(double x, double y, APD a, APD b, double  w);			// https://www.shadertoy.com/view/cs2yzG
double aktive_sdf_xcross_rounded (double x, double y, double w, double  r);			// https://www.shadertoy.com/view/3dKSDc
#endif

#if 0
double aktive_sdf_circle_wave    (double x, double y, double tb, double ra);			// https://www.shadertoy.com/view/stGyzt
double aktive_sdf_cool_s         (double x, double y);						// https://www.shadertoy.com/view/clVXWc
double aktive_sdf_egg            (double x, double y, double ra, double  rb);			// https://www.shadertoy.com/view/Wdjfz3
double aktive_sdf_heart          (double x, double y);						// https://www.shadertoy.com/view/3tyBzV
double aktive_sdf_horseshoe      (double x, double y, APD c, double r, APD w);			// https://www.shadertoy.com/view/WlSGW1
double aktive_sdf_hyperbola      (double x, double y, double k, double  he );	// 0 <= k <= inf   https://www.shadertoy.com/view/DtjXDG
double aktive_sdf_moon           (double x, double y, double d, double ra, double  rb);		// https://www.shadertoy.com/view/WtdBRS
double aktive_sdf_parabola       (double x, double y, double k);				// https://www.shadertoy.com/view/ws3GD7
double aktive_sdf_parabola_seg   (double x, double y, double wi, double  he);			// https://www.shadertoy.com/view/3lSczz
double aktive_sdf_stairs         (double x, double y, double w, double  h, double  n);		// https://www.shadertoy.com/view/7tKSWt
double aktive_sdf_triangle_equi  (double x, double y, double r);				// https://www.shadertoy.com/view/Xl2yDW
double aktive_sdf_triangle_isosc (double x, double y, APD q);					// https://www.shadertoy.com/view/MldcD7
double aktive_sdf_tunnel         (double x, double y, double w, double h  );			// https://www.shadertoy.com/view/flSSDy
double aktive_sdf_uneven_capsule (double x, double y, double r1, double r2, double h);		// https://www.shadertoy.com/view/4lcBWn
double aktive_sdf_vesica         (double x, double y, double r, double  d);			// https://www.shadertoy.com/view/XtVfRW
#endif

//double aktive_sdf_ (double x, double y  );
//double aktive_sdf_ (double x, double y  );
Changes to tests/sdf.test.
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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197

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

set base {width 11 height 11 x 0 y 0}

test aktive-image-sdf-box-2.0 "aktive image sdf box" -body {
    astclx 11 aktive image sdf box {*}$base ewidth 5 eheight 3 center {5 5}
} -match image -result [makei image::sdf::box 0 0 11 11 1 "$base ewidth 5 eheight 3 center {5 5}" {
    	2  2  2  2  2  2  2  2  2  2 2
	1  1  1  1  1  1  1  1  1  1 1
	0  0  0  0  0  0  0  0  0  0 0
	0 -1 -1 -1 -1 -1 -1 -1 -1 -1 0
	0 -1 -2 -2 -2 -2 -2 -2 -2 -1 0
	0 -1 -2 -3 -3 -3 -3 -3 -2 -1 0
	0 -1 -2 -2 -2 -2 -2 -2 -2 -1 0
	0 -1 -1 -1 -1 -1 -1 -1 -1 -1 0
	0  0  0  0  0  0  0  0  0  0 0
	1  1  1  1  1  1  1  1  1  1 1
    	2  2  2  2  2  2  2  2  2  2 2
}]

test aktive-image-sdf-box-rounded-2.0 "aktive image sdf box-rounded" -body {
    astclx 11 aktive image sdf box-rounded {*}$base \
	upleftradius 1 uprightradius 1 downleftradius 1 downrightradius 1 \
	ewidth 5 eheight 3 center {5 5}
} -match image -result [makei image::sdf::box-rounded 0 0 11 11 1 "$base upleftradius 1 uprightradius 1 downleftradius 1 downrightradius 1 ewidth 5 eheight 3 center {5 5}" {

    2.1623  2      2       2       2       2       2       2       2       2      2.1623
    1.2361  1      1       1       1       1       1       1       1       1      1.2361
    0.4142  0      0       0       0       0       0       0       0       0      0.4142
    0      -1     -1      -1      -1      -1      -1      -1      -1      -1      0
    0      -1     -2      -2      -2      -2      -2      -2      -2      -1      0
    0      -1     -2      -3      -3      -3      -3      -3      -2      -1      0
    0      -1     -2      -2      -2      -2      -2      -2      -2      -1      0
    0      -1     -1      -1      -1      -1      -1      -1      -1      -1      0
    0.4142  0      0       0       0       0       0       0       0       0      0.4142
    1.2361  1      1       1       1       1       1       1       1       1      1.2361
    2.1623  2      2       2       2       2       2       2       2       2      2.1623

}]

test aktive-image-sdf-circle-2.0 "aktive image sdf circle" -body {
    astclx 11 aktive image sdf circle {*}$base radius 3 center {5 5}
} -match image -result [makei image::sdf::circle 0 0 11 11 1 "$base radius 3 center {5 5}" {
    4.0711 3.4031 2.8310  2.3852  2.0990  2       2.0990  2.3852 2.8310 3.4031 4.0711
    3.4031 2.6569 2       1.4721  1.1231  1       1.1231  1.4721 2      2.6569 3.4031
    2.8310 2      1.2426  0.6056  0.1623  0       0.1623  0.6056 1.2426 2      2.8310
    2.3852 1.4721 0.6056 -0.1716 -0.7639 -1      -0.7639 -0.1716 0.6056 1.4721 2.3852
    2.0990 1.1231 0.1623 -0.7639 -1.5858 -2      -1.5858 -0.7639 0.1623 1.1231 2.0990
    2      1      0      -1      -2      -3      -2      -1      0      1      2
    2.0990 1.1231 0.1623 -0.7639 -1.5858 -2      -1.5858 -0.7639 0.1623 1.1231 2.0990
    2.3852 1.4721 0.6056 -0.1716 -0.7639 -1      -0.7639 -0.1716 0.6056 1.4721 2.3852
    2.8310 2      1.2426  0.6056  0.1623  0       0.1623  0.6056 1.2426 2      2.8310
    3.4031 2.6569 2       1.4721  1.1231  1       1.1231  1.4721 2      2.6569 3.4031
    4.0711 3.4031 2.8310  2.3852  2.0990  2       2.0990  2.3852 2.8310 3.4031 4.0711
}]

test aktive-image-sdf-parallelogram-2.0 "aktive image sdf parallelogram" -body {
    astclx 11 aktive image sdf parallelogram {*}$base ewidth 5 eheight 3 eskew 1 center {5 5}
} -match image -result [makei image::sdf::parallelogram 0 0 11 11 1 "$base ewidth 5 eheight 3 eskew 1 center {5 5}" {
    =  2       2       2       2       2       2       2       2       2       2       2.2361
    =  1       1       1       1       1       1       1       1       1       1       1.4142
    =  0       0       0       0       0       0       0       0       0       0       0.9487
    = -0.6325 -1      -1      -1      -1      -1      -1      -1      -1      -0.3162  0.6325
    = -0.3162 -1.2649 -2      -2      -2      -2      -2      -2      -1.5811 -0.6325  0.3162
    =  0      -0.9487 -1.8974 -2.8460 -3      -3      -3      -2.8460 -1.8974 -0.9487  0
    =  0.3162 -0.6325 -1.5811 -2      -2      -2      -2      -2      -2      -1.2649 -0.3162
    =  0.6325 -0.3162 -1      -1      -1      -1      -1      -1      -1      -1      -0.6325
    =  0.9487  0       0       0       0       0       0       0       0       0       0
    =  1.4142  1       1       1       1       1       1       1       1       1       1
    =  2.2361  2       2       2       2       2       2       2       2       2       2
}]

test aktive-image-sdf-rhombus-2.0 "aktive image sdf rhombus" -body {
    astclx 11 aktive image sdf rhombus {*}$base ewidth 5 eheight 3 center {5 5}
} -match image -result [makei image::sdf::rhombus 0 0 11 11 1 "$base ewidth 5 eheight 3 center {5 5}" {
    4.2875  3.7730  3.2585  2.7440  2.2361  2       2.2361  2.7440  3.2585  3.7730 4.2875
    3.4300  2.9155  2.4010  1.8865  1.3720  1       1.3720  1.8865  2.4010  2.9155 3.4300
    2.5725  2.0580  1.5435  1.0290  0.5145  0       0.5145  1.0290  1.5435  2.0580 2.5725
    1.7150  1.2005  0.6860  0.1715 -0.3430 -0.8575 -0.3430  0.1715  0.6860  1.2005 1.7150
    0.8575  0.3430 -0.1715 -0.6860 -1.2005 -1.7150 -1.2005 -0.6860 -0.1715  0.3430 0.8575
    0      -0.5145 -1.0290 -1.5435 -2.0580 -2.5725 -2.0580 -1.5435 -1.0290 -0.5145 0
    0.8575  0.3430 -0.1715 -0.6860 -1.2005 -1.7150 -1.2005 -0.6860 -0.1715  0.3430 0.8575
    1.7150  1.2005  0.6860  0.1715 -0.3430 -0.8575 -0.3430  0.1715  0.6860  1.2005 1.7150
    2.5725  2.0580  1.5435  1.0290  0.5145  0       0.5145  1.0290  1.5435  2.0580 2.5725
    3.4300  2.9155  2.4010  1.8865  1.3720  1       1.3720  1.8865  2.4010  2.9155 3.4300
    4.2875  3.7730  3.2585  2.7440  2.2361  2       2.2361  2.7440  3.2585  3.7730 4.2875
}]

test aktive-image-sdf-line-2.0 "aktive image sdf line" -body {
    astclx 11 aktive image sdf line {*}$base from {1 2} to {8 9}
} -match image -result [makei image::sdf::line 0 0 11 11 1 "$base from {1 2} to {8 9}" {

    2.2361 2      2.2361 2.8284 3.5355 4.2426 4.9497 5.6569 6.3640 7.0711 7.7782
    1.4142 1      1.4142 2.1213 2.8284 3.5355 4.2426 4.9497 5.6569 6.3640 7.0711
    1      0      0.7071 1.4142 2.1213 2.8284 3.5355 4.2426 4.9497 5.6569 6.3640
    1.4142 0.7071 0      0.7071 1.4142 2.1213 2.8284 3.5355 4.2426 4.9497 5.6569
    2.1213 1.4142 0.7071 0      0.7071 1.4142 2.1213 2.8284 3.5355 4.2426 4.9497
    2.8284 2.1213 1.4142 0.7071 0      0.7071 1.4142 2.1213 2.8284 3.5355 4.2426
    3.5355 2.8284 2.1213 1.4142 0.7071 0      0.7071 1.4142 2.1213 2.8284 3.5355
    4.2426 3.5355 2.8284 2.1213 1.4142 0.7071 0      0.7071 1.4142 2.1213 2.8284
    4.9497 4.2426 3.5355 2.8284 2.1213 1.4142 0.7071 0      0.7071 1.4142 2.2361
    5.6569 4.9497 4.2426 3.5355 2.8284 2.1213 1.4142 0.7071 0      1      2
    6.3640 5.6569 4.9497 4.2426 3.5355 2.8284 2.1213 1.4142 1      1.4142 2.2361
}]

test aktive-image-sdf-triangle-2.0 "aktive image sdf triangle" -body {
    astclx 11 aktive image sdf triangle {*}$base a {1 1} b {3 8} c {8 3}
} -match image -result [makei image::sdf::triangle 0 0 11 11 1 "$base a {1 1} b {3 8} c {8 3}" {
    1.4142  1       1.2362  1.5110  1.7857  2.0604  2.3351  2.6099  2.8846 3.1623 3.6056
    1      -0       0.2747  0.5494  0.8242  1.0989  1.3736  1.6483  1.9230 2.2361 2.8284
    1.2362  0.2747 -0.6868 -0.4121 -0.1374  0.1374  0.4121  0.6868  0.9615 1.4142 2.2361
    1.5110  0.5494 -0.4121 -1.3736 -1.0989 -0.8242 -0.5494 -0.2747 -0      1      2
    1.7857  0.8242 -0.1374 -1.0989 -2.0604 -1.4142 -0.7071 -0       0.7071 1.4142 2.2361
    2.0604  1.0989  0.1374 -0.8242 -1.4142 -0.7071 -0       0.7071  1.4142 2.1213 2.8284
    2.3351  1.3736  0.4121 -0.5494 -0.7071 -0       0.7071  1.4142  2.1213 2.8284 3.5355
    2.6099  1.6483  0.6868 -0.2747 -0       0.7071  1.4142  2.1213  2.8284 3.5355 4.2426
    2.8846  1.9230  0.9615 -0       0.7071  1.4142  2.1213  2.8284  3.5355 4.2426 4.9497
    3.1623  2.2361  1.4142  1       1.4142  2.1213  2.8284  3.5355  4.2426 4.9497 5.6569
    3.6056  2.8284  2.2361  2       2.2361  2.8284  3.5355  4.2426  4.9497 5.6569 6.3640
}]

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

test aktive-image-sdf-circles-2.0 "aktive image sdf circles" -body {
    astclx 11 aktive image sdf circles {*}$base radius 1 centers {2 2} {7 3} {5 7}
} -match image -result [makei image::sdf::circles 0 0 11 11 1 {width 11 height 11 x 0 y 0 radius 1 centers {{2 2} {7 3} {5 7}}} {
    1.8284 1.2361  1      1.2361 1.8284  2.6056 2.1623  2      2.1623 2.6056 3.2426
    1.2361 0.4142  0      0.4142 1.2361  1.8284 1.2361  1      1.2361 1.8284 2.6056
    1      0      -1      0      1       1.2361 0.4142  0      0.4142 1.2361 2.1623
    1.2361 0.4142  0      0.4142 1.2361  1      0      -1      0      1      2
    1.8284 1.2361  1      1.2361 1.8284  1.2361 0.4142  0      0.4142 1.2361 2.1623
    2.6056 2.1623  2      1.8284 1.2361  1      1.2361  1      1.2361 1.8284 2.6056
    3.4721 3.1231  2.1623 1.2361 0.4142  0      0.4142  1.2361 2.1623 2.6056 3.2426
    4      3       2      1      0      -1      0       1      2      3      4
    4.0990 3.1231  2.1623 1.2361 0.4142  0      0.4142  1.2361 2.1623 3.1231 4.0990
    4.3852 3.4721  2.6056 1.8284 1.2361  1      1.2361  1.8284 2.6056 3.4721 4.3852
    4.8310 4       3.2426 2.6056 2.1623  2      2.1623  2.6056 3.2426 4      4.8310
}]

test aktive-image-sdf-polyline-2.0 "aktive image sdf polyline" -body {
    astclx 11 aktive image sdf polyline {*}$base points {2 2} {7 3} {5 7}
} -match image -result [makei image::sdf::polyline 0 0 11 11 1 {width 11 height 11 x 0 y 0 points {{2 2} {7 3} {5 7}}} {
    2.8284 2.2361 2      2.1573 2.3534 2.5495 2.7456 2.9417 3.1623 3.6056 4.2426
    2.2361 1.4142 1      1.1767 1.3728 1.5689 1.7650 1.9612 2.2361 2.8284 3.6056
    2      1      0      0.1961 0.3922 0.5883 0.7845 0.9806 1.4142 2.2361 3.1623
    2.2361 1.4142 0.9806 0.7845 0.5883 0.3922 0.1961 0      1      2      3
    2.8284 2.2361 1.9612 1.7650 1.5689 1.3416 0.4472 0.4472 1.3416 2.2361 3.1623
    3.6056 3.1623 2.9417 2.6833 1.7889 0.8944 0      0.8944 1.7889 2.6833 3.5777
    4.4721 4.1231 3.1623 2.2361 1.3416 0.4472 0.4472 1.3416 2.2361 3.1305 4.0249







|

















|

















|















|















|















|
















|

















|















|







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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197

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

set base {width 11 height 11 x 0 y 0}

test aktive-image-sdf-box-2.0 "aktive image sdf box" -body {
    astclx 11 aktive image sdf box {*}$base ewidth 5 eheight 3 center {5 5}
} -match image -result [makei image::sdf::box 0 0 11 11 1 "$base ewidth 5.0 eheight 3.0 center {5.0 5.0}" {
    	2  2  2  2  2  2  2  2  2  2 2
	1  1  1  1  1  1  1  1  1  1 1
	0  0  0  0  0  0  0  0  0  0 0
	0 -1 -1 -1 -1 -1 -1 -1 -1 -1 0
	0 -1 -2 -2 -2 -2 -2 -2 -2 -1 0
	0 -1 -2 -3 -3 -3 -3 -3 -2 -1 0
	0 -1 -2 -2 -2 -2 -2 -2 -2 -1 0
	0 -1 -1 -1 -1 -1 -1 -1 -1 -1 0
	0  0  0  0  0  0  0  0  0  0 0
	1  1  1  1  1  1  1  1  1  1 1
    	2  2  2  2  2  2  2  2  2  2 2
}]

test aktive-image-sdf-box-rounded-2.0 "aktive image sdf box-rounded" -body {
    astclx 11 aktive image sdf box-rounded {*}$base \
	upleftradius 1 uprightradius 1 downleftradius 1 downrightradius 1 \
	ewidth 5 eheight 3 center {5 5}
} -match image -result [makei image::sdf::box-rounded 0 0 11 11 1 "$base upleftradius 1.0 uprightradius 1.0 downleftradius 1.0 downrightradius 1.0 ewidth 5.0 eheight 3.0 center {5.0 5.0}" {

    2.1623  2      2       2       2       2       2       2       2       2      2.1623
    1.2361  1      1       1       1       1       1       1       1       1      1.2361
    0.4142  0      0       0       0       0       0       0       0       0      0.4142
    0      -1     -1      -1      -1      -1      -1      -1      -1      -1      0
    0      -1     -2      -2      -2      -2      -2      -2      -2      -1      0
    0      -1     -2      -3      -3      -3      -3      -3      -2      -1      0
    0      -1     -2      -2      -2      -2      -2      -2      -2      -1      0
    0      -1     -1      -1      -1      -1      -1      -1      -1      -1      0
    0.4142  0      0       0       0       0       0       0       0       0      0.4142
    1.2361  1      1       1       1       1       1       1       1       1      1.2361
    2.1623  2      2       2       2       2       2       2       2       2      2.1623

}]

test aktive-image-sdf-circle-2.0 "aktive image sdf circle" -body {
    astclx 11 aktive image sdf circle {*}$base radius 3 center {5 5}
} -match image -result [makei image::sdf::circle 0 0 11 11 1 "$base radius 3.0 center {5.0 5.0}" {
    4.0711 3.4031 2.8310  2.3852  2.0990  2       2.0990  2.3852 2.8310 3.4031 4.0711
    3.4031 2.6569 2       1.4721  1.1231  1       1.1231  1.4721 2      2.6569 3.4031
    2.8310 2      1.2426  0.6056  0.1623  0       0.1623  0.6056 1.2426 2      2.8310
    2.3852 1.4721 0.6056 -0.1716 -0.7639 -1      -0.7639 -0.1716 0.6056 1.4721 2.3852
    2.0990 1.1231 0.1623 -0.7639 -1.5858 -2      -1.5858 -0.7639 0.1623 1.1231 2.0990
    2      1      0      -1      -2      -3      -2      -1      0      1      2
    2.0990 1.1231 0.1623 -0.7639 -1.5858 -2      -1.5858 -0.7639 0.1623 1.1231 2.0990
    2.3852 1.4721 0.6056 -0.1716 -0.7639 -1      -0.7639 -0.1716 0.6056 1.4721 2.3852
    2.8310 2      1.2426  0.6056  0.1623  0       0.1623  0.6056 1.2426 2      2.8310
    3.4031 2.6569 2       1.4721  1.1231  1       1.1231  1.4721 2      2.6569 3.4031
    4.0711 3.4031 2.8310  2.3852  2.0990  2       2.0990  2.3852 2.8310 3.4031 4.0711
}]

test aktive-image-sdf-parallelogram-2.0 "aktive image sdf parallelogram" -body {
    astclx 11 aktive image sdf parallelogram {*}$base ewidth 5 eheight 3 eskew 1 center {5 5}
} -match image -result [makei image::sdf::parallelogram 0 0 11 11 1 "$base ewidth 5.0 eheight 3.0 eskew 1.0 center {5.0 5.0}" {
    =  2       2       2       2       2       2       2       2       2       2       2.2361
    =  1       1       1       1       1       1       1       1       1       1       1.4142
    =  0       0       0       0       0       0       0       0       0       0       0.9487
    = -0.6325 -1      -1      -1      -1      -1      -1      -1      -1      -0.3162  0.6325
    = -0.3162 -1.2649 -2      -2      -2      -2      -2      -2      -1.5811 -0.6325  0.3162
    =  0      -0.9487 -1.8974 -2.8460 -3      -3      -3      -2.8460 -1.8974 -0.9487  0
    =  0.3162 -0.6325 -1.5811 -2      -2      -2      -2      -2      -2      -1.2649 -0.3162
    =  0.6325 -0.3162 -1      -1      -1      -1      -1      -1      -1      -1      -0.6325
    =  0.9487  0       0       0       0       0       0       0       0       0       0
    =  1.4142  1       1       1       1       1       1       1       1       1       1
    =  2.2361  2       2       2       2       2       2       2       2       2       2
}]

test aktive-image-sdf-rhombus-2.0 "aktive image sdf rhombus" -body {
    astclx 11 aktive image sdf rhombus {*}$base ewidth 5 eheight 3 center {5 5}
} -match image -result [makei image::sdf::rhombus 0 0 11 11 1 "$base ewidth 5.0 eheight 3.0 center {5.0 5.0}" {
    4.2875  3.7730  3.2585  2.7440  2.2361  2       2.2361  2.7440  3.2585  3.7730 4.2875
    3.4300  2.9155  2.4010  1.8865  1.3720  1       1.3720  1.8865  2.4010  2.9155 3.4300
    2.5725  2.0580  1.5435  1.0290  0.5145  0       0.5145  1.0290  1.5435  2.0580 2.5725
    1.7150  1.2005  0.6860  0.1715 -0.3430 -0.8575 -0.3430  0.1715  0.6860  1.2005 1.7150
    0.8575  0.3430 -0.1715 -0.6860 -1.2005 -1.7150 -1.2005 -0.6860 -0.1715  0.3430 0.8575
    0      -0.5145 -1.0290 -1.5435 -2.0580 -2.5725 -2.0580 -1.5435 -1.0290 -0.5145 0
    0.8575  0.3430 -0.1715 -0.6860 -1.2005 -1.7150 -1.2005 -0.6860 -0.1715  0.3430 0.8575
    1.7150  1.2005  0.6860  0.1715 -0.3430 -0.8575 -0.3430  0.1715  0.6860  1.2005 1.7150
    2.5725  2.0580  1.5435  1.0290  0.5145  0       0.5145  1.0290  1.5435  2.0580 2.5725
    3.4300  2.9155  2.4010  1.8865  1.3720  1       1.3720  1.8865  2.4010  2.9155 3.4300
    4.2875  3.7730  3.2585  2.7440  2.2361  2       2.2361  2.7440  3.2585  3.7730 4.2875
}]

test aktive-image-sdf-line-2.0 "aktive image sdf line" -body {
    astclx 11 aktive image sdf line {*}$base from {1 2} to {8 9}
} -match image -result [makei image::sdf::line 0 0 11 11 1 "$base from {1.0 2.0} to {8.0 9.0}" {

    2.2361 2      2.2361 2.8284 3.5355 4.2426 4.9497 5.6569 6.3640 7.0711 7.7782
    1.4142 1      1.4142 2.1213 2.8284 3.5355 4.2426 4.9497 5.6569 6.3640 7.0711
    1      0      0.7071 1.4142 2.1213 2.8284 3.5355 4.2426 4.9497 5.6569 6.3640
    1.4142 0.7071 0      0.7071 1.4142 2.1213 2.8284 3.5355 4.2426 4.9497 5.6569
    2.1213 1.4142 0.7071 0      0.7071 1.4142 2.1213 2.8284 3.5355 4.2426 4.9497
    2.8284 2.1213 1.4142 0.7071 0      0.7071 1.4142 2.1213 2.8284 3.5355 4.2426
    3.5355 2.8284 2.1213 1.4142 0.7071 0      0.7071 1.4142 2.1213 2.8284 3.5355
    4.2426 3.5355 2.8284 2.1213 1.4142 0.7071 0      0.7071 1.4142 2.1213 2.8284
    4.9497 4.2426 3.5355 2.8284 2.1213 1.4142 0.7071 0      0.7071 1.4142 2.2361
    5.6569 4.9497 4.2426 3.5355 2.8284 2.1213 1.4142 0.7071 0      1      2
    6.3640 5.6569 4.9497 4.2426 3.5355 2.8284 2.1213 1.4142 1      1.4142 2.2361
}]

test aktive-image-sdf-triangle-2.0 "aktive image sdf triangle" -body {
    astclx 11 aktive image sdf triangle {*}$base a {1 1} b {3 8} c {8 3}
} -match image -result [makei image::sdf::triangle 0 0 11 11 1 "$base a {1.0 1.0} b {3.0 8.0} c {8.0 3.0}" {
    1.4142  1       1.2362  1.5110  1.7857  2.0604  2.3351  2.6099  2.8846 3.1623 3.6056
    1      -0       0.2747  0.5494  0.8242  1.0989  1.3736  1.6483  1.9230 2.2361 2.8284
    1.2362  0.2747 -0.6868 -0.4121 -0.1374  0.1374  0.4121  0.6868  0.9615 1.4142 2.2361
    1.5110  0.5494 -0.4121 -1.3736 -1.0989 -0.8242 -0.5494 -0.2747 -0      1      2
    1.7857  0.8242 -0.1374 -1.0989 -2.0604 -1.4142 -0.7071 -0       0.7071 1.4142 2.2361
    2.0604  1.0989  0.1374 -0.8242 -1.4142 -0.7071 -0       0.7071  1.4142 2.1213 2.8284
    2.3351  1.3736  0.4121 -0.5494 -0.7071 -0       0.7071  1.4142  2.1213 2.8284 3.5355
    2.6099  1.6483  0.6868 -0.2747 -0       0.7071  1.4142  2.1213  2.8284 3.5355 4.2426
    2.8846  1.9230  0.9615 -0       0.7071  1.4142  2.1213  2.8284  3.5355 4.2426 4.9497
    3.1623  2.2361  1.4142  1       1.4142  2.1213  2.8284  3.5355  4.2426 4.9497 5.6569
    3.6056  2.8284  2.2361  2       2.2361  2.8284  3.5355  4.2426  4.9497 5.6569 6.3640
}]

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

test aktive-image-sdf-circles-2.0 "aktive image sdf circles" -body {
    astclx 11 aktive image sdf circles {*}$base radius 1 centers {2 2} {7 3} {5 7}
} -match image -result [makei image::sdf::circles 0 0 11 11 1 {width 11 height 11 x 0 y 0 radius 1.0 centers {{2.0 2.0} {7.0 3.0} {5.0 7.0}}} {
    1.8284 1.2361  1      1.2361 1.8284  2.6056 2.1623  2      2.1623 2.6056 3.2426
    1.2361 0.4142  0      0.4142 1.2361  1.8284 1.2361  1      1.2361 1.8284 2.6056
    1      0      -1      0      1       1.2361 0.4142  0      0.4142 1.2361 2.1623
    1.2361 0.4142  0      0.4142 1.2361  1      0      -1      0      1      2
    1.8284 1.2361  1      1.2361 1.8284  1.2361 0.4142  0      0.4142 1.2361 2.1623
    2.6056 2.1623  2      1.8284 1.2361  1      1.2361  1      1.2361 1.8284 2.6056
    3.4721 3.1231  2.1623 1.2361 0.4142  0      0.4142  1.2361 2.1623 2.6056 3.2426
    4      3       2      1      0      -1      0       1      2      3      4
    4.0990 3.1231  2.1623 1.2361 0.4142  0      0.4142  1.2361 2.1623 3.1231 4.0990
    4.3852 3.4721  2.6056 1.8284 1.2361  1      1.2361  1.8284 2.6056 3.4721 4.3852
    4.8310 4       3.2426 2.6056 2.1623  2      2.1623  2.6056 3.2426 4      4.8310
}]

test aktive-image-sdf-polyline-2.0 "aktive image sdf polyline" -body {
    astclx 11 aktive image sdf polyline {*}$base points {2 2} {7 3} {5 7}
} -match image -result [makei image::sdf::polyline 0 0 11 11 1 {width 11 height 11 x 0 y 0 points {{2.0 2.0} {7.0 3.0} {5.0 7.0}}} {
    2.8284 2.2361 2      2.1573 2.3534 2.5495 2.7456 2.9417 3.1623 3.6056 4.2426
    2.2361 1.4142 1      1.1767 1.3728 1.5689 1.7650 1.9612 2.2361 2.8284 3.6056
    2      1      0      0.1961 0.3922 0.5883 0.7845 0.9806 1.4142 2.2361 3.1623
    2.2361 1.4142 0.9806 0.7845 0.5883 0.3922 0.1961 0      1      2      3
    2.8284 2.2361 1.9612 1.7650 1.5689 1.3416 0.4472 0.4472 1.3416 2.2361 3.1623
    3.6056 3.1623 2.9417 2.6833 1.7889 0.8944 0      0.8944 1.7889 2.6833 3.5777
    4.4721 4.1231 3.1623 2.2361 1.3416 0.4472 0.4472 1.3416 2.2361 3.1305 4.0249