shapes_lines_splines.c 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. /*******************************************************************************************
  2. *
  3. * raylib [shapes] example - splines drawing
  4. *
  5. * Example originally created with raylib 4.6-dev, last time updated with raylib 4.6-dev
  6. *
  7. * Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
  8. * BSD-like license that allows static linking with closed source software
  9. *
  10. * Copyright (c) 2023 Ramon Santamaria (@raysan5)
  11. *
  12. ********************************************************************************************/
  13. #include "raylib.h"
  14. #define MAX_CONTROL_POINTS 32
  15. typedef struct {
  16. Vector2 start;
  17. Vector2 end;
  18. } ControlPoint;
  19. //------------------------------------------------------------------------------------
  20. // Program main entry point
  21. //------------------------------------------------------------------------------------
  22. int main(void)
  23. {
  24. // Initialization
  25. //--------------------------------------------------------------------------------------
  26. const int screenWidth = 800;
  27. const int screenHeight = 450;
  28. SetConfigFlags(FLAG_MSAA_4X_HINT);
  29. InitWindow(screenWidth, screenHeight, "raylib [shapes] example - splines drawing");
  30. Vector2 points[MAX_CONTROL_POINTS] = {
  31. { 100.0f, 200.0f },
  32. { 300.0f, 400.0f },
  33. { 500.0f, 300.0f },
  34. { 700.0f, 100.0f },
  35. { 200.0f, 100.0f },
  36. };
  37. int pointCount = 5;
  38. int selectedPoint = -1;
  39. int splineType = 0; // 0-Linear, 1-BSpline, 2-CatmullRom, 3-Bezier
  40. // Cubic Bezier control points
  41. ControlPoint control[MAX_CONTROL_POINTS] = { 0 };
  42. for (int i = 0; i < pointCount - 1; i++)
  43. {
  44. control[i].start = points[i];
  45. control[i].end = points[i + 1];
  46. }
  47. SetTargetFPS(60); // Set our game to run at 60 frames-per-second
  48. //--------------------------------------------------------------------------------------
  49. // Main game loop
  50. while (!WindowShouldClose()) // Detect window close button or ESC key
  51. {
  52. // Update
  53. //----------------------------------------------------------------------------------
  54. // Points movement logic
  55. if (IsMouseButtonPressed(MOUSE_RIGHT_BUTTON) && (pointCount < MAX_CONTROL_POINTS))
  56. {
  57. points[pointCount] = GetMousePosition();
  58. pointCount++;
  59. }
  60. for (int i = 0; i < pointCount; i++)
  61. {
  62. if (IsMouseButtonDown(MOUSE_LEFT_BUTTON) && CheckCollisionPointCircle(GetMousePosition(), points[i], 6.0f))
  63. {
  64. selectedPoint = i;
  65. break;
  66. }
  67. }
  68. if (selectedPoint >= 0)
  69. {
  70. points[selectedPoint] = GetMousePosition();
  71. if (IsMouseButtonReleased(MOUSE_LEFT_BUTTON)) selectedPoint = -1;
  72. }
  73. // TODO: Cubic Bezier spline control points logic
  74. // Spline selection logic
  75. if (IsKeyPressed(KEY_ONE)) splineType = 0;
  76. else if (IsKeyPressed(KEY_TWO)) splineType = 1;
  77. else if (IsKeyPressed(KEY_THREE)) splineType = 2;
  78. else if (IsKeyPressed(KEY_FOUR)) splineType = 3;
  79. //----------------------------------------------------------------------------------
  80. // Draw
  81. //----------------------------------------------------------------------------------
  82. BeginDrawing();
  83. ClearBackground(RAYWHITE);
  84. if (splineType == 0) // Linear
  85. {
  86. // Draw linear spline
  87. for (int i = 0; i < pointCount - 1; i++)
  88. {
  89. DrawLineEx(points[i], points[i + 1], 2.0f, RED);
  90. }
  91. }
  92. else if (splineType == 1) // B-Spline
  93. {
  94. // Draw b-spline
  95. DrawLineBSpline(points, pointCount, 2.0f, RED);
  96. //for (int i = 0; i < (pointCount - 3); i++) DrawLineBSplineSegment(points[i], points[i + 1], points[i + 2], points[i + 3], 24.0f, BLUE);
  97. }
  98. else if (splineType == 2) // CatmullRom Spline
  99. {
  100. // Draw spline: catmull-rom
  101. DrawLineCatmullRom(points, pointCount, 2.0f, RED);
  102. //for (int i = 0; i < (pointCount - 3); i++) DrawLineCatmullRomSegment(points[i], points[i + 1], points[i + 2], points[i + 3], 24.0f, Fade(BLUE, 0.4f));
  103. }
  104. else if (splineType == 3) // Cubic Bezier
  105. {
  106. // Draw line bezier cubic (with control points)
  107. for (int i = 0; i < pointCount - 1; i++)
  108. {
  109. DrawLineBezierCubic(points[i], points[i + 1], control[i].start, control[i + 1].end, 2.0f, RED);
  110. // TODO: Every cubic bezier point should have two control points
  111. DrawCircleV(control[i].start, 4, GOLD);
  112. DrawCircleV(control[i].end, 4, GOLD);
  113. DrawLineEx(points[i], control[i].start, 1.0, LIGHTGRAY);
  114. DrawLineEx(points[i + 1], control[i].end, 1.0, LIGHTGRAY);
  115. }
  116. }
  117. // Draw control points
  118. for (int i = 0; i < pointCount; i++)
  119. {
  120. DrawCircleV(points[i], 6.0f, RED);
  121. if ((splineType != 0) && (i < pointCount - 1)) DrawLineV(points[i], points[i + 1], GRAY);
  122. }
  123. EndDrawing();
  124. //----------------------------------------------------------------------------------
  125. }
  126. // De-Initialization
  127. //--------------------------------------------------------------------------------------
  128. CloseWindow(); // Close window and OpenGL context
  129. //--------------------------------------------------------------------------------------
  130. return 0;
  131. }