Skip to content

Commit

Permalink
factor out pbio_color_hsv_fix16_t
Browse files Browse the repository at this point in the history
  • Loading branch information
Novakasa committed Mar 2, 2022
1 parent fd1d344 commit f43ad8e
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 26 deletions.
14 changes: 14 additions & 0 deletions lib/pbio/include/pbio/color.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@

#include <stdint.h>

#include <fixmath.h>

/** @cond INTERNAL */

/**
Expand Down Expand Up @@ -106,12 +108,24 @@ typedef struct __attribute__((__packed__)) {
uint8_t v;
} pbio_color_compressed_hsv_t;

/** HSV color with fix16 components */
typedef struct {
/** The hue component. radians. */
fix16_t h;
/** The saturation component. 0 to 1. */
fix16_t s;
/** The value component. 0 to 1. */
fix16_t v;
} pbio_color_hsv_fix16_t;

void pbio_color_rgb_to_hsv(const pbio_color_rgb_t *rgb, pbio_color_hsv_t *hsv);
void pbio_color_hsv_to_rgb(const pbio_color_hsv_t *hsv, pbio_color_rgb_t *rgb);
void pbio_color_to_hsv(pbio_color_t color, pbio_color_hsv_t *hsv);
void pbio_color_to_rgb(pbio_color_t color, pbio_color_rgb_t *rgb);
void pbio_color_hsv_compress(const pbio_color_hsv_t *hsv, pbio_color_compressed_hsv_t *compressed);
void pbio_color_hsv_expand(const pbio_color_compressed_hsv_t *compressed, pbio_color_hsv_t *hsv);
void pbio_color_hsv_to_fix16(const pbio_color_hsv_t *hsv, pbio_color_hsv_fix16_t *hsv_fix16);

int32_t pbio_get_hsv_cost(const pbio_color_hsv_t *x, const pbio_color_hsv_t *c);
int32_t pbio_get_cone_cost(const pbio_color_hsv_t *a, const pbio_color_hsv_t *b);

Expand Down
17 changes: 17 additions & 0 deletions lib/pbio/src/color/conversion.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
// Copyright (c) 2020 The Pybricks Authors
// Copyright (c) 2013 FastLED

#include <fixmath.h>

#include <pbio/color.h>

/**
Expand Down Expand Up @@ -233,3 +235,18 @@ void pbio_color_hsv_expand(const pbio_color_compressed_hsv_t *compressed, pbio_c
hsv->s = compressed->s;
hsv->v = compressed->v;
}

/**
* Converts HSV to normalized HSV for fixed point operations.
*
* @param [in] hsv The source HSV color value.
* @param [out] hsv The destination HSV_fix16 color value.
*/
void pbio_color_hsv_to_fix16(const pbio_color_hsv_t *hsv, pbio_color_hsv_fix16_t *hsv_fix16) {
const fix16_t by100 = F16C(0,0100);

// normalize h to radians, s/v to (0,1)
hsv_fix16->h = fix16_deg_to_rad(fix16_from_int(hsv->h));
hsv_fix16->s = fix16_mul(fix16_from_int(hsv->s), by100);
hsv_fix16->v = fix16_mul(fix16_from_int(hsv->v), by100);
}
43 changes: 18 additions & 25 deletions lib/pbio/src/color/util.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: MIT
// Copyright (c) 2018-2020 The Pybricks Authors
// Copyright (c) 2018-2022 The Pybricks Authors

#include <fixmath.h>

Expand Down Expand Up @@ -32,47 +32,40 @@ int32_t pbio_get_hsv_cost(const pbio_color_hsv_t *x, const pbio_color_hsv_t *c)
return hue_error * hue_error + 5 * saturation_error * saturation_error + 2 * value_error * value_error;
}

int32_t pbio_get_cone_cost(const pbio_color_hsv_t *a, const pbio_color_hsv_t *b) {
int32_t pbio_get_cone_cost(const pbio_color_hsv_t *hsv_a, const pbio_color_hsv_t *hsv_b) {

fix16_t by100 = fix16_div(fix16_one, fix16_from_int(100));

// normalize h to radians, s/v to (0,1)
fix16_t a_h = fix16_deg_to_rad(fix16_from_int(a->h));
fix16_t a_s = fix16_mul(fix16_from_int(a->s), by100);
fix16_t a_v = fix16_mul(fix16_from_int(a->v), by100);

fix16_t b_h = fix16_deg_to_rad(fix16_from_int(b->h));
fix16_t b_s = fix16_mul(fix16_from_int(b->s), by100);
fix16_t b_v = fix16_mul(fix16_from_int(b->v), by100);
pbio_color_hsv_fix16_t a, b;
pbio_color_hsv_to_fix16(hsv_a, &a);
pbio_color_hsv_to_fix16(hsv_b, &b);

// x, y and z deltas between cartesian coordinates of a and b in HSV cone
// delx = b_s*b_v*cos(b_h) - a_s*a_v*cos(a_h)
fix16_t delx = fix16_sub(
fix16_mul(
fix16_mul(
fix16_cos(b_h),
b_v),
b_s),
fix16_cos(b.h),
b.v),
b.s),
fix16_mul(
fix16_mul(
fix16_cos(a_h),
a_v),
a_s));
fix16_cos(a.h),
a.v),
a.s));

// dely = b_s*b_v*sin(b_h) - a_s*a_v*sin(a_h)
fix16_t dely = fix16_sub(
fix16_mul(
fix16_mul(
fix16_sin(b_h),
b_v),
b_s),
fix16_sin(b.h),
b.v),
b.s),
fix16_mul(
fix16_mul(
fix16_sin(a_h),
a_v),
a_s));
fix16_sin(a.h),
a.v),
a.s));
// delz = b_v - a_v
fix16_t delz = fix16_sub(b_v, a_v);
fix16_t delz = fix16_sub(b.v, a.v);

// cdist = delx*delx + dely*dely + delz*delz
fix16_t cdist = fix16_add(
Expand Down
1 change: 0 additions & 1 deletion lib/pbio/test/src/color.c
Original file line number Diff line number Diff line change
Expand Up @@ -399,7 +399,6 @@ static void test_color_hsv_cost(void *env) {
color_b.v = 70;

dist = pbio_get_cone_cost(&color_a, &color_b);
printf("\n\nhello world %d\n", dist);

color_a.h = 30;
color_a.s = 40;
Expand Down

0 comments on commit f43ad8e

Please sign in to comment.