summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVito Caputo <vcaputo@pengaru.com>2023-12-03 21:58:34 -0800
committerVito Caputo <vcaputo@pengaru.com>2023-12-03 21:58:34 -0800
commit531657799d853dc727d834c7f180dacdbfa76380 (patch)
treeccd221686a16b23825fdabbb2e063fd6f3a32567
parent9c6575344bbba510836de9a3222d779434cb67f7 (diff)
modules/spokes: make spokes count configurable
This switches the perimeter and stride math to use floating point, done in a kind of fast and nasty naive substitution manner. That's necessary for getting away from the even stride calculation / spokes calculation in favor of supporting arbitrary spoke counts, without introducing discontinuities at the boundaries of the mirrored sides The new setting is count= with a handful of reasonable presets. It's a little awkward since this is expressed as half the actual count, naming could probably be improved.
-rw-r--r--src/modules/spokes/spokes.c63
1 files changed, 46 insertions, 17 deletions
diff --git a/src/modules/spokes/spokes.c b/src/modules/spokes/spokes.c
index 16e8900..6bc3b2b 100644
--- a/src/modules/spokes/spokes.c
+++ b/src/modules/spokes/spokes.c
@@ -15,12 +15,14 @@
#define SPOKES_DEFAULT_ITERATIONS 3
#define SPOKES_DEFAULT_TWIST 0.0625
#define SPOKES_DEFAULT_THICKNESS 3
+#define SPOKES_DEFAULT_COUNT 4
typedef struct spokes_setup_t {
til_setup_t til_setup;
unsigned iterations;
float twist;
unsigned thickness;
+ unsigned count;
} spokes_setup_t;
static void spokes_draw_line(til_fb_fragment_t *fragment, int x1, int y1, int x2, int y2, uint32_t color, int thickness)
@@ -123,8 +125,8 @@ static void spokes_render_fragment(til_module_context_t *context, til_stream_t *
til_fb_fragment_t *fragment = *fragment_ptr;
int width = fragment->width, height = fragment->height;
- int stride;
- int offset;
+ float stride;
+ float offset;
uint32_t color;
int display_R, display_origin_x, display_origin_y;
@@ -153,7 +155,7 @@ static void spokes_render_fragment(til_module_context_t *context, til_stream_t *
origin_y=display_origin_y+sin((float)ticks*0.001)*display_R*0.7f;
/* calculate an offset for outer line endpoints based on ticks */
- offset=(int)round((float)ticks*0.1); /* use the ticks. */
+ offset=(float)ticks*0.1f; /* use the ticks. */
/* rotate through RGB color space slowly based on ticks */
color=makergb(
@@ -162,33 +164,28 @@ static void spokes_render_fragment(til_module_context_t *context, til_stream_t *
(int)round(255.0*sinf((float)ticks*0.00001+1.3333*M_PI)),
1);
- /* find the largest even stride for the fragments dimensions */
- stride=1;
- for(int i=2; i<(width+height)/2; i++) {
- if((width+height)%i==0) {
- stride=i;
- }
- }
+ stride = ((float)(width+height))/(float)s->count;
/* we're setup now to draw some shit */
til_fb_fragment_clear(fragment);
- for(int i=0; i<=width+height-stride; i+=stride){ /* iterate over half the perimiter at a time... */
- int perimiter_x=-1, perimiter_y=-1;
- if(i+offset%stride<width) {
- perimiter_x=i+offset%stride;
+ for(float i=0; i<=width+height-stride; i+=stride){ /* iterate over half the perimiter at a time... */
+ float perimiter_x, perimiter_y;
+
+ if(i+fmodf(offset, stride) < width) {
+ perimiter_x=i+fmodf(offset, stride);
perimiter_y=0;
} else {
perimiter_x=width-1;
- perimiter_y=(i-width)+offset%stride;
+ perimiter_y=(i-((float)width))+fmodf(offset, stride);
}
- spokes_draw_segmented_line(fragment, s->iterations, theta, origin_x, origin_y, perimiter_x, perimiter_y, color, s->thickness);
+ spokes_draw_segmented_line(fragment, s->iterations, theta, origin_x, origin_y, rintf(perimiter_x), rintf(perimiter_y), color, s->thickness);
/* Calculate and draw the mirror line... */
perimiter_x=abs(perimiter_x-width);
perimiter_y=abs(perimiter_y-height);
- spokes_draw_segmented_line(fragment, s->iterations, theta, origin_x, origin_y, perimiter_x, perimiter_y, color, s->thickness);
+ spokes_draw_segmented_line(fragment, s->iterations, theta, origin_x, origin_y, rintf(perimiter_x), rintf(perimiter_y), color, s->thickness);
}
}
@@ -246,6 +243,20 @@ int spokes_setup(const til_settings_t *settings, til_setting_t **res_setting, co
"5",
NULL
};
+ til_setting_t *count;
+ const char *count_values[] = {
+ "2",
+ "3",
+ "4",
+ "8",
+ "10",
+ "15",
+ "20",
+ "25",
+ "30",
+ "40",
+ NULL
+ };
int r;
r = til_settings_get_and_describe_setting(settings,
@@ -265,6 +276,21 @@ int spokes_setup(const til_settings_t *settings, til_setting_t **res_setting, co
r = til_settings_get_and_describe_setting(settings,
&(til_setting_spec_t){
+ .name = "Number of spokes (gets doubled)",
+ .key = "count",
+ .regex = "[0-9]+",
+ .preferred = TIL_SETTINGS_STR(SPOKES_DEFAULT_COUNT),
+ .values = count_values,
+ .annotations = NULL
+ },
+ &count,
+ res_setting,
+ res_desc);
+ if (r)
+ return r;
+
+ r = til_settings_get_and_describe_setting(settings,
+ &(til_setting_spec_t){
.name = "Twist",
.key = "twist",
.regex = "[0-9]+\\.[0-9]+",
@@ -303,6 +329,9 @@ int spokes_setup(const til_settings_t *settings, til_setting_t **res_setting, co
if (sscanf(iterations->value, "%u", &setup->iterations) != 1)
return til_setup_free_with_failed_setting_ret_err(&setup->til_setup, iterations, res_setting, -EINVAL);
+ if (sscanf(count->value, "%u", &setup->count) != 1)
+ return til_setup_free_with_failed_setting_ret_err(&setup->til_setup, count, res_setting, -EINVAL);
+
if (sscanf(twist->value, "%f", &setup->twist) != 1)
return til_setup_free_with_failed_setting_ret_err(&setup->til_setup, twist, res_setting, -EINVAL);
© All Rights Reserved