palette sorter

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



In a fit of boredom today, I wrote a palette sorter for my gradient
generator.  This seems to work pretty well, so I thought I'd share.

Really bad C code follows.  

Kelly

~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~

#include <stdio.h>

#define MAXV 1024
#define MAXE (MAXV*MAXV/2)

struct _Vert {
  double r, g, b;
  short component;
  short incount;
} vert[MAXV];

struct _Edge {
  short v1, v2;
  double dist;
} edge[MAXE];

int selected[MAXV];

int newpalette[MAXV];

int nvert, nedge;

int
edge_compare (struct _Edge *e1, struct _Edge *e2)
{
  if      (e1->dist < e2->dist) return -1;
  else if (e1->dist > e2->dist) return 1;
  else                          return 0;
}

double
colordist (struct _Vert *v1, struct _Vert *v2)
{
  double r = v1->r - v2->r;
  double g = v1->g - v2->g;
  double b = v1->b - v2->b;

  return (r*r)+(g*g)+(b*b);
}

int
main (int argc, char **argv)
{
  double r, g, b;
  int edgecursor;
  int i;
  int start, next;
  int count;

  nvert = 0;
  nedge = 0;

  while (scanf("%lf %lf %lf", &r, &g, &b) != EOF) {
    int i = nvert;
    int j;

    vert[i].r = r;
    vert[i].g = g;
    vert[i].b = b;
    vert[i].component = nvert;
    vert[i].incount = 0;
    nvert++;
    for (j=0; j<i; j++) {
      int k = nedge;
      edge[k].v1 = i; edge[k].v2 = j;
      edge[k].dist = colordist(&(vert[i]), &(vert[j]));
      nedge++;
    }
  }

  qsort(edge, nedge, sizeof(edge[0]), &edge_compare);

  count = nvert-1;
  edgecursor = 0;

  while (count) {
    int delcomp, keepcomp;
    int e = edgecursor++;
    int a = edge[e].v1;
    int b = edge[e].v2;
    if (vert[a].component == vert[b].component ||
	vert[a].incount > 1 ||
	vert[b].incount > 1) continue;
    vert[a].incount++;
    vert[b].incount++;

    selected[--count] = e;

    keepcomp = vert[a].component;
    delcomp  = vert[b].component;

    for (i=0; i<nvert; i++) {
      if (vert[i].component == delcomp) vert[i].component = keepcomp;
    }
  }

  for (i=0; i<nvert; i++) {
    if (vert[i].incount < 2) {
      start = i; break;
    }
  }

  for (count = nvert-1; count; count--) {
    next = -1;
    for (i = 0; i<nvert; i++) {
      if (selected[i] == -1) {
	continue;
      } else if (edge[selected[i]].v1 == start) {
	next = edge[selected[i]].v2; break;
      } else if (edge[selected[i]].v2 == start) {
	next = edge[selected[i]].v1; break;
      }
    }
    if (next == -1) abort();
    selected[i] = -1;
    newpalette[count] = start;
    start = next;
  }

  newpalette[0] = start;

  for (i = nvert-1; i; i--) {
    printf("%d %lg %lg %lg\n", 
	   newpalette[i],
	   vert[newpalette[i]].r,
	   vert[newpalette[i]].g,
	   vert[newpalette[i]].b);
  }

}



[Index of Archives]     [Video For Linux]     [Photo]     [Yosemite News]     [gtk]     [GIMP for Windows]     [KDE]     [GEGL]     [Gimp's Home]     [Gimp on GUI]     [Gimp on Windows]     [Steve's Art]

  Powered by Linux