您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

img2rubik.c 4.1 KiB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. #include "config.h"
  2. #include "common.h"
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #include <math.h>
  7. #include <pipi.h>
  8. #define Y(x) (0.299*(x)[0] + 0.587*(x)[1] + 0.114*(x)[2])
  9. #define STEPS 16
  10. #define EPSILON (0.000001)
  11. int main(int argc, char *argv[])
  12. {
  13. double palette[][3] =
  14. {
  15. { 1.0, 0.0, 0.0 }, /* red */
  16. { 0.0, 1.0, 0.0 }, /* green */
  17. { 0.0, 0.0, 1.0 }, /* blue */
  18. { 1.0, 1.0, 1.0 }, /* white */
  19. { 1.0, 1.0, 0.0 }, /* yellow */
  20. { 1.0, 0.5, 0.0 }, /* orange */
  21. };
  22. #define NCOLORS ((int)(sizeof(palette)/sizeof(*palette)))
  23. double tmp;
  24. int i, j;
  25. /*
  26. * 1. Find the darkest and lightest colours
  27. */
  28. double *dark = NULL, *light = NULL;
  29. double min = 1.0, max = 0.0;
  30. for(i = 0; i < NCOLORS; i++)
  31. {
  32. double p = Y(palette[i]);
  33. if(p < min)
  34. {
  35. dark = palette[i];
  36. min = p;
  37. }
  38. if(p > max)
  39. {
  40. light = palette[i];
  41. max = p;
  42. }
  43. }
  44. printf("lightest (%g,%g,%g)\n", light[0], light[1], light[2]);
  45. printf("darkest (%g,%g,%g)\n", dark[0], dark[1], dark[2]);
  46. /*
  47. * 2. Find two base vectors for the chrominance planes
  48. * FIXME: this doesn't work in all cases because u can be null
  49. */
  50. double y[3], u[3], v[3];
  51. double ylen;
  52. y[0] = light[0] - dark[0];
  53. y[1] = light[1] - dark[1];
  54. y[2] = light[2] - dark[2];
  55. ylen = sqrt(y[0] * y[0] + y[1] * y[1] + y[2] * y[2]);
  56. u[0] = y[1];
  57. u[1] = -y[0];
  58. u[2] = 0;
  59. tmp = sqrt(u[0] * u[0] + u[1] * u[1] + u[2] * u[2]);
  60. u[0] /= tmp; u[1] /= tmp; u[2] /= tmp;
  61. v[0] = y[1] * u[2] - y[2] * u[1];
  62. v[1] = y[2] * u[0] - y[0] * u[2];
  63. v[2] = y[0] * u[1] - y[1] * u[0];
  64. tmp = sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
  65. v[0] /= tmp; v[1] /= tmp; v[2] /= tmp;
  66. printf("gray axis (%g,%g,%g) - length %g\n", y[0], y[1], y[2], ylen);
  67. printf("u (%g,%g,%g)\n", u[0], u[1], u[2]);
  68. printf("v (%g,%g,%g)\n", v[0], v[1], v[2]);
  69. /*
  70. * 3. Browse the grey axis and do stuff
  71. */
  72. double t;
  73. for(t = 0.; t <= 1.0; t += 1. / STEPS)
  74. {
  75. double pts[NCOLORS*NCOLORS/2][3];
  76. double p0[3];
  77. int npts = 0;
  78. p0[0] = dark[0] + t * y[0];
  79. p0[1] = dark[1] + t * y[1];
  80. p0[2] = dark[2] + t * y[2];
  81. printf("%g,%g,%g\n", p0[0], p0[1], p0[2]);
  82. /*
  83. * 3.1. Find all edges that intersect the t.y + (u,v) plane
  84. */
  85. for(i = 0; i < NCOLORS; i++)
  86. {
  87. double k1[3];
  88. k1[0] = palette[i][0] - dark[0];
  89. k1[1] = palette[i][1] - dark[1];
  90. k1[2] = palette[i][2] - dark[2];
  91. tmp = sqrt(k1[0] * k1[0] + k1[1] * k1[1] + k1[2] * k1[2]);
  92. /* If k1.y > t.y.y, we don't want this point */
  93. double yk1 = y[0] * k1[0] + y[1] * k1[1] + y[2] * k1[2];
  94. if(yk1 > t * ylen * ylen + EPSILON)
  95. continue;
  96. for(j = 0; j < NCOLORS; j++)
  97. {
  98. if(i == j)
  99. continue;
  100. double k2[3];
  101. k2[0] = palette[j][0] - dark[0];
  102. k2[1] = palette[j][1] - dark[1];
  103. k2[2] = palette[j][2] - dark[2];
  104. tmp = sqrt(k2[0] * k2[0] + k2[1] * k2[1] + k2[2] * k2[2]);
  105. /* If k2.y < t.y.y, we don't want this point */
  106. double yk2 = y[0] * k2[0] + y[1] * k2[1] + y[2] * k2[2];
  107. if(yk2 < t * ylen * ylen - EPSILON)
  108. continue;
  109. if(yk2 < yk1)
  110. continue;
  111. double s = yk1 == yk2 ?
  112. 0.5 : (t * ylen * ylen - yk1) / (yk2 - yk1);
  113. pts[npts][0] = dark[0] + k1[0] + s * (k2[0] - k1[0]);
  114. pts[npts][1] = dark[1] + k1[1] + s * (k2[1] - k1[1]);
  115. pts[npts][2] = dark[2] + k1[2] + s * (k2[2] - k1[2]);
  116. printf(" %i,%i: s = (%g,%g,%g)\n", i, j, pts[npts][0], pts[npts][1], pts[npts][2]);
  117. npts++;
  118. }
  119. }
  120. /*
  121. * 3.2. Find the barycentre of these points' convex hull. (TODO)
  122. */
  123. }
  124. return 0;
  125. }