builtin-programs/draw/arc.folk
Wish the GPU compiles pipeline "arc" [list \
{vec2 viewport mat3 surfaceToClip
vec2 center float radius float thickness float start float arclen vec4 color} {
float r = radius + thickness;
vec2 vertices[6] = vec2[6](
center - r,
vec2(center.x + r, center.y - r),
vec2(center.x - r, center.y + r),
vec2(center.x + r, center.y - r),
center + r,
vec2(center.x - r, center.y + r)
);
vec3 v = surfaceToClip * vec3(vertices[gl_VertexIndex], 1.0);
return vec4(v.xy / v.z, 0.0, 1.0);
} [subst {
vec2 clipXy = (gl_FragCoord.xy / viewport) * 2.0 - 1.0;
vec3 surfaceXy = inverse(surfaceToClip) * vec3(clipXy, 1.0);
surfaceXy /= surfaceXy.z;
const float TAU = $::TAU;
float c_start = clamp(start, 0.0, TAU);
float c_arclen = clamp(arclen, 0.0, TAU);
float dist = length(surfaceXy.xy - center) - radius;
float angle = atan(-(surfaceXy.y - center.y), surfaceXy.x - center.x);
angle = (angle < 0.0) ? (angle + TAU) : angle;
float end = c_start + c_arclen;
if (dist < thickness && dist > 0.0) {
if ((end < TAU && angle > c_start && angle < end) ||
(end >= TAU && (angle > c_start || angle < end - TAU))) {
return color;
}
}
return vec4(0.0);
}]]
When the color map is /colorMap/ &\
/p/ has canvas /id/ with /...wiOptions/ &\
/p/ has canvas projection /surfaceToClip/ &\
/someone/ wishes to draw an arc onto /p/ with /...options/ {
set center [dict getdef $options center ""]
if {$center eq ""} { set center [list [dict get $options x] [dict get $options y]] }
set radius [dict get $options radius]
set thickness [dict get $options thickness]
set start [dict get $options start]
set arclen [dict get $options arclen]
set color [dict get $options color]
set color [dict getdef $colorMap $color $color]
set layer [dict getdef $options layer 0]
set wiResolution [list [dict get $wiOptions width] [dict get $wiOptions height]]
Wish the GPU draws pipeline "arc" onto canvas $id with arguments \
[list $wiResolution $surfaceToClip \
$center $radius $thickness $start $arclen $color] \
layer $layer
}