test_triangle.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. #include <stdio.h>
  2. #define PAR_TRIANGLE_IMPLEMENTATION
  3. #include "par_triangle.h"
  4. static FILE* svg_begin(char const* path, float t, float s)
  5. {
  6. FILE* svgfile = fopen(path, "wt");
  7. fprintf(svgfile,
  8. "<svg viewBox='-1.1 -1.1 10.2 10.2' width='500px' height='500px' "
  9. "version='1.1' "
  10. "xmlns='http://www.w3.org/2000/svg'>\n"
  11. "<g transform='translate(%f %f) scale(%f %f)'>", t, t, s, s);
  12. return svgfile;
  13. }
  14. static void svg_end(FILE* svgfile)
  15. {
  16. fputs("</g>\n</svg>", svgfile);
  17. fclose(svgfile);
  18. }
  19. static void svg_write_path(FILE* svgfile, par_triangle_path const* polygon,
  20. uint32_t color, float fill, float stroke)
  21. {
  22. fprintf(svgfile, "<path\n"
  23. " fill='#%6.6x'\n"
  24. " stroke='#%6.6x'\n"
  25. " stroke-width='0.005'\n"
  26. " fill-opacity='%f'\n"
  27. " stroke-opacity='%f'\n"
  28. " d='", color, color, fill, stroke);
  29. for (int c = 0; c < polygon->nloops; c++) {
  30. float const* loop = polygon->loops[c];
  31. int length = (int) polygon->lengths[c];
  32. uint16_t first = 1;
  33. for (uint16_t s = 0; s < length; s++) {
  34. fprintf(svgfile, "%c%f,%f", first ? 'M' : 'L', loop[s * 2],
  35. loop[s * 2 + 1]);
  36. first = 0;
  37. }
  38. fputs("Z", svgfile);
  39. }
  40. fputs("'\n/>", svgfile);
  41. }
  42. static void svg_write_triangle(FILE* svgfile, par_triangle_mesh const* mesh,
  43. int triangle, uint32_t color, float fill, float stroke, float thickness)
  44. {
  45. fprintf(svgfile, "<path\n"
  46. " fill='#%6.6x'\n"
  47. " stroke='#000000'\n"
  48. " stroke-width='%f'\n"
  49. " fill-opacity='%f'\n"
  50. " stroke-opacity='%f'\n"
  51. " d='", color, thickness, fill, stroke);
  52. uint16_t const* tri = mesh->triangles + triangle * 3;
  53. float const* a = mesh->points + tri[0] * 2;
  54. float const* b = mesh->points + tri[1] * 2;
  55. float const* c = mesh->points + tri[2] * 2;
  56. fprintf(svgfile, "M%f,%fL%f,%fL%f,%fZ",
  57. a[0], a[1], b[0], b[1], c[0], c[1]);
  58. fputs("'\n/>", svgfile);
  59. }
  60. static void test_simple()
  61. {
  62. const uint16_t lengths[2] = {5, 3};
  63. const float points[] = {
  64. 0, 0, 6, 0, 6, 4, 3, 7, 0, 4, // CCW pentagon
  65. 3, 3, 4, 1, 2, 1, // CW triangle
  66. };
  67. par_triangle_path* path = par_triangle_path_create(lengths, 2, points, 0);
  68. FILE* svgfile = svg_begin("build/triangle_simple.svg", 1.5, 0.3);
  69. par_triangle_mesh* mesh = par_triangle_mesh_create_cdt(path);
  70. for (int t = 0; t < mesh->ntriangles; t++) {
  71. svg_write_triangle(svgfile, mesh, t, 0xa0a0a0, 0.5, 0.5, 0.1);
  72. }
  73. svg_write_path(svgfile, path, 0xff0000, 0.5, 0.5);
  74. par_triangle_path_free(path);
  75. par_triangle_mesh_free(mesh);
  76. svg_end(svgfile);
  77. }
  78. static void test_concave()
  79. {
  80. // Figure snarfed from:
  81. // https://github.com/prideout/polygon.js/blob/master/src/application.coffee
  82. const float points[] = {
  83. 440, 502, 414, 438, 404, 355, 394, 298, 442, 278, 470, 265, 480, 252,
  84. 489, 232, 508, 198, 467, 173, 437, 236, 395, 251, 361, 257, 324, 212,
  85. 317, 170, 327, 150, 349, 125, 367, 82, 353, 56, 308, 22, 244, 40, 233,
  86. 75, 258, 146, 278, 159, 299, 216, 282, 277, 228, 246, 168, 180, 159,
  87. 167, 117, 207, 194, 249, 223, 277, 263, 304, 277, 385, 259, 406, 225,
  88. 429, 217, 435, 159, 496, 293, 520, 284, 451, 315, 406, 323, 381, 351,
  89. 391, 354, 421, 370, 458, 344, 487, 335, 535,
  90. };
  91. const uint16_t lengths[1] = {sizeof(points) / (2 * sizeof(float))};
  92. par_triangle_path* path = par_triangle_path_create(lengths, 1, points, 0);
  93. FILE* svgfile = svg_begin("build/triangle_concave.svg", 0.0, 0.015);
  94. par_triangle_mesh* mesh = par_triangle_mesh_create_cdt(path);
  95. for (int t = 0; t < mesh->ntriangles; t++) {
  96. svg_write_triangle(svgfile, mesh, t, 0xa0a0a0, 0.5, 0.5, 1.0);
  97. }
  98. svg_write_path(svgfile, path, 0xff0000, 0.5, 0.5);
  99. par_triangle_path_free(path);
  100. par_triangle_mesh_free(mesh);
  101. svg_end(svgfile);
  102. }
  103. int main(int argc, char* argv[])
  104. {
  105. test_simple();
  106. test_concave();
  107. return 0;
  108. }