From 1fdd0f7b92b7d5f1b0e3c5cda96d1e46f6b3b790 Mon Sep 17 00:00:00 2001 From: David Vazgenovich Shakaryan Date: Tue, 5 Apr 2022 04:49:02 -0700 Subject: refactor c rewrite --- dartbot.c | 97 +++++++++++++++++++++++++++++++++++++++------------------------ 1 file changed, 61 insertions(+), 36 deletions(-) diff --git a/dartbot.c b/dartbot.c index 263bbc1..7367648 100644 --- a/dartbot.c +++ b/dartbot.c @@ -1,5 +1,6 @@ #include #include +#include #include #include #include @@ -7,6 +8,7 @@ #define HORIZONTAL_STDEV 50 #define VERTICAL_STDEV 50 +// board spec from WDF rules #define WIRE_WIDTH 1.56 #define INNER_DIAMETER_BULL 12.7 #define INNER_DIAMETER_25 31.8 @@ -15,14 +17,19 @@ #define DOUBLE_INSIDE_WIDTH 8.0 #define TREBLE_INSIDE_WIDTH 8.0 +#define SEGMENT_MAX_LEN 5 +// distance from centre to apex of outer wire +// must be ordered outwards from centre #define FOREACH_RING(M) \ - M(R_BULL, INNER_DIAMETER_BULL/2 + WIRE_WIDTH/2) \ - M(R_25, INNER_DIAMETER_25/2 + WIRE_WIDTH/2) \ - M(R_SMALL, TREBLE_OUTER_EDGE - WIRE_WIDTH - TREBLE_INSIDE_WIDTH - WIRE_WIDTH/2) \ - M(R_TREBLE, TREBLE_OUTER_EDGE - WIRE_WIDTH/2) \ - M(R_BIG, DOUBLE_OUTER_EDGE - WIRE_WIDTH - DOUBLE_INSIDE_WIDTH - WIRE_WIDTH/2) \ - M(R_DOUBLE, DOUBLE_OUTER_EDGE - WIRE_WIDTH/2) -#define GEN_RING_ENUM(X, D) X, + M(BULL, INNER_DIAMETER_BULL/2 + WIRE_WIDTH/2) \ + M(25, INNER_DIAMETER_25/2 + WIRE_WIDTH/2) \ + M(SMALL, TREBLE_OUTER_EDGE - WIRE_WIDTH - TREBLE_INSIDE_WIDTH - \ + WIRE_WIDTH/2) \ + M(TREBLE, TREBLE_OUTER_EDGE - WIRE_WIDTH/2) \ + M(BIG, DOUBLE_OUTER_EDGE - WIRE_WIDTH - DOUBLE_INSIDE_WIDTH - \ + WIRE_WIDTH/2) \ + M(DOUBLE, DOUBLE_OUTER_EDGE - WIRE_WIDTH/2) +#define GEN_RING_ENUM(X, D) R_ ## X, #define GEN_RING_STRING(X, D) #X, #define GEN_RING_OUTER_DIST(X, D) D, @@ -44,7 +51,8 @@ double OUTER_DISTS[] = { }; double CENTRE_DISTS[sizeof(OUTER_DISTS)/sizeof(*OUTER_DISTS)]; -void init_centre_dists() { +void init_centre_dists() +{ CENTRE_DISTS[0] = 0; for (int i = R_25; i < R_OUT; ++i) CENTRE_DISTS[i] = (OUTER_DISTS[i] - @@ -80,25 +88,43 @@ enum ring get_ring(double radius) return R_OUT; } -struct ccoords gauss() +double drand() { - double theta = 2 * M_PI * ((double)rand() / RAND_MAX); - double r = sqrt(-2 * log(1 - (double)rand() / RAND_MAX)); - return (struct ccoords){ .x = r * cos(theta), .y = r * sin(theta) }; + return (double)rand() / RAND_MAX; +} + +double gauss(double mean, double stdev) +{ + static bool have_next; + static double next; + + double curr; + + if (have_next) { + curr = next; + } else { + double theta = 2 * M_PI * drand(); + double r = sqrt(-2 * log(1 - drand())); + + curr = r * cos(theta); + next = r * sin(theta); + } + + have_next = !have_next; + return mean + (curr * stdev); } struct ccoords get_offset() { - struct ccoords g = gauss(); - return (struct ccoords){ .x = g.x * HORIZONTAL_STDEV, - .y = g.y * VERTICAL_STDEV }; + return (struct ccoords){ .x = gauss(0, HORIZONTAL_STDEV), + .y = gauss(0, VERTICAL_STDEV) }; } -struct ccoords pol_to_cart(struct pcoords a) +struct ccoords pol_to_cart(struct pcoords c) { - double t = a.a * (M_PI / 180); - double x = a.r * cos(t); - double y = a.r * sin(t); + double t = c.a * (M_PI / 180); + double x = c.r * cos(t); + double y = c.r * sin(t); return (struct ccoords){ .x = x, .y = y }; } @@ -120,28 +146,26 @@ struct pcoords throw_dart(struct pcoords target) .y = cc.y + offset.y }); } -struct segment get_segment(struct pcoords pos) +struct segment get_segment(struct pcoords c) { - return (struct segment){ .sector = get_sector(pos.a), - .ring = get_ring(pos.r) }; + return (struct segment){ .sector = get_sector(c.a), + .ring = get_ring(c.r) }; } char *segment_name(struct segment seg) { - char *str = malloc(5); - - if (seg.ring == R_BULL) - strncpy(str, "BULL", 5); - else if (seg.ring == R_25) - strncpy(str, "25", 5); - else if (seg.ring == R_OUT) - strncpy(str, "OUT", 5); - else if (seg.ring == R_TREBLE) - snprintf(str, 5, "T%d", seg.sector); - else if (seg.ring == R_DOUBLE) - snprintf(str, 5, "D%d", seg.sector); + char *str = malloc(SEGMENT_MAX_LEN); + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wstringop-truncation" + if (seg.ring == R_BULL || seg.ring == R_25 || seg.ring == R_OUT) + strncpy(str, RING_NAMES[seg.ring], SEGMENT_MAX_LEN); else - snprintf(str, 5, "%d", seg.sector); + snprintf(str, SEGMENT_MAX_LEN, + (seg.ring == R_TREBLE ? "T%d" : + (seg.ring == R_DOUBLE ? "D%d" : "%d")), + seg.sector); +#pragma GCC diagnostic pop return str; } @@ -167,7 +191,8 @@ int main() res = throw_dart(t); seg = get_segment(res); char *name = segment_name(seg); - printf("%d %f %f %d %s %s\n", seg.sector, res.a, res.r, seg.ring, RING_NAMES[seg.ring], name); + printf("%d %f %f %d %s %s\n", seg.sector, res.a, res.r, seg.ring, + RING_NAMES[seg.ring], name); free(name); } -- cgit v1.2.3-70-g09d2