math.h 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. #ifndef MATH_H
  2. #define MATH_H
  3. #include "stdint.h"
  4. typedef struct {
  5. int x;
  6. int y;
  7. } RI_vector_2;
  8. typedef struct {
  9. double x;
  10. double y;
  11. } RI_vector_2f;
  12. typedef struct {
  13. double x;
  14. double y;
  15. double z;
  16. } RI_vector_3f;
  17. typedef struct {
  18. double w;
  19. double x;
  20. double y;
  21. double z;
  22. } RI_vector_4f;
  23. // value-wise multiplacation.
  24. // multiply the whole vector by 1 value
  25. void vector_2f_times(RI_vector_2f *vector, double value){
  26. vector->x *= value;
  27. vector->y *= value;
  28. }
  29. // value-wise multiplacation.
  30. // multiply the whole vector by 1 value
  31. void vector_3f_times(RI_vector_3f *vector, double value){
  32. vector->x *= value;
  33. vector->y *= value;
  34. vector->z *= value;
  35. }
  36. // hadamard multiplacation.
  37. // multiply each value of one vector with the matching one on the other vector
  38. void vector_3f_hadamard(RI_vector_3f *multiplicand, RI_vector_3f multiplicator){
  39. multiplicand->x *= multiplicator.x;
  40. multiplicand->y *= multiplicator.y;
  41. multiplicand->z *= multiplicator.z;
  42. }
  43. // "hadamard" addition.
  44. // add each value of one vector with the matching one on the other vector
  45. void vector_2f_element_wise_add(RI_vector_2f *addend_a, RI_vector_2f addend_b){
  46. addend_a->x += addend_b.x;
  47. addend_a->y += addend_b.y;
  48. }
  49. // "hadamard" addition.
  50. // add each value of one vector with the matching one on the other vector
  51. void vector_3f_element_wise_add(RI_vector_3f *addend_a, RI_vector_3f addend_b){
  52. addend_a->x += addend_b.x;
  53. addend_a->y += addend_b.y;
  54. addend_a->z += addend_b.z;
  55. }
  56. // "hadamard" subtraction.
  57. // subtraction each value of one vector with the matching one on the other vector
  58. void vector_3f_element_wise_subtract(RI_vector_3f *minuend, RI_vector_3f subtrahend){
  59. minuend->x -= subtrahend.x;
  60. minuend->y -= subtrahend.y;
  61. minuend->z -= subtrahend.z;
  62. }
  63. // "hadamard" division.
  64. // divide each value of one vector with the matching one on the other vector
  65. void vector_3f_divide(RI_vector_3f *dividend, double divisor){
  66. dividend->x /= divisor;
  67. dividend->y /= divisor;
  68. dividend->z /= divisor;
  69. }
  70. // conjugate a quaterion.
  71. // (flip the sign of the x, y, z values)
  72. void quaternion_conjugate(RI_vector_4f* quaternion){
  73. quaternion->x *= -1.0;
  74. quaternion->y *= -1.0;
  75. quaternion->z *= -1.0;
  76. }
  77. // quaternion multiplacation
  78. void quaternion_multiply(RI_vector_4f* a, RI_vector_4f b){
  79. double w1 = a->w; double x1 = a->x; double y1 = a->y; double z1 = a->z;
  80. double w2 = b.w; double x2 = b.x; double y2 = b.y; double z2 = b.z;
  81. double w = w1*w2 - x1*x2 - y1*y2 - z1*z2;
  82. double x = w1*x2 + x1*w2 + y1*z2 - z1*y2;
  83. double y = w1*y2 - x1*z2 + y1*w2 + z1*x2;
  84. double z = w1*z2 + x1*y2 - y1*x2 + z1*w2;
  85. *a = (RI_vector_4f){w, x, y, z};
  86. }
  87. // linear interpolate between 2 vectors
  88. void vector_2f_lerp(RI_vector_2f vector_a, RI_vector_2f vector_b, RI_vector_2f *result, double w1){
  89. double w0 = 1.0 - w1;
  90. vector_2f_times(result, 0);
  91. vector_2f_times(&vector_a, w0);
  92. vector_2f_times(&vector_b, w1);
  93. vector_2f_element_wise_add(result, vector_a);
  94. vector_2f_element_wise_add(result, vector_b);
  95. }
  96. // beziate between 2 vectors
  97. void vector_2f_bezier_interpolate(RI_vector_2f vector_a, RI_vector_2f vector_b, RI_vector_2f vector_c, RI_vector_2f *result, double w1){
  98. double w0 = 1.0 - w1;
  99. vector_2f_lerp(vector_a, vector_b, &vector_b, w1); // this works because the first vector b is a copy and the second is a reference
  100. vector_2f_lerp(vector_b, vector_c, &vector_c, w1);
  101. vector_2f_lerp(vector_b, vector_c, result, w1);
  102. }
  103. // linear interpolate between 2 vectors
  104. void vector_3f_lerp(RI_vector_3f vector_a, RI_vector_3f vector_b, RI_vector_3f *result, double w1){
  105. double w0 = 1.0 - w1;
  106. vector_3f_times(result, 0);
  107. vector_3f_times(&vector_a, w0);
  108. vector_3f_times(&vector_b, w1);
  109. vector_3f_element_wise_add(result, vector_a);
  110. vector_3f_element_wise_add(result, vector_b);
  111. }
  112. #endif