Skip to content

Commit dd1807d

Browse files
committed
FEAT: native for human perception weighted Euclidean distance between two RGB colors
1 parent dbdb4d3 commit dd1807d

File tree

2 files changed

+39
-0
lines changed

2 files changed

+39
-0
lines changed

src/core/n-image.c

+30
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,36 @@ typedef struct REBCLR {
184184
}
185185

186186

187+
/***********************************************************************
188+
**
189+
*/ REBNATIVE(color_distance)
190+
/*
191+
** It's by design providing only the weighted version! The simple distance
192+
** could be provided in more generic `distance` function.
193+
**
194+
** https://www.compuphase.com/cmetric.htm
195+
** https://observablehq.com/@luciyer/euclidian-distance-in-rgb-color-space
196+
**
197+
// color-distance: native [
198+
// "Human perception weighted Euclidean distance between two RGB colors"
199+
// a [tuple!]
200+
// b [tuple!]
201+
// ]
202+
***********************************************************************/
203+
{
204+
REBCLR *val1 = (REBCLR*)VAL_TUPLE(D_ARG(1));
205+
REBCLR *val2 = (REBCLR*)VAL_TUPLE(D_ARG(2));
206+
207+
long r = (long)val1->r - (long)val2->r;
208+
long g = (long)val1->g - (long)val2->g;
209+
long b = (long)val1->b - (long)val2->b;
210+
211+
long rmean = ((long)val1->r + (long)val2->r ) / 2;
212+
SET_DECIMAL(D_RET, sqrt((((512+rmean)*r*r)>>8) + 4*g*g + (((767-rmean)*b*b)>>8)));
213+
return R_RET;
214+
}
215+
216+
187217
/***********************************************************************
188218
**
189219
*/ REBNATIVE(tint)

src/tests/units/image-test.r3

+9
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,15 @@ FFFFFFDC1616212121212121
363363

364364
===end-group===
365365

366+
===start-group=== "RGB color distance"
367+
--test-- "color-distance"
368+
--assert 764.83 = round/to color-distance 0.0.0 255.255.255 0.01
369+
--assert 569.97 = round/to color-distance 0.0.255 255.0.0 0.01
370+
--assert 42.04 = round/to color-distance 200.105.200 225.105.200 0.01
371+
--assert 41.3 = round/to color-distance 175.200.100 200.200.100 0.01
372+
--assert 0.0 = round/to color-distance 200.200.100 200.200.100 0.01
373+
===end-group===
374+
366375

367376
===start-group=== "Tint color"
368377

0 commit comments

Comments
 (0)