summaryrefslogtreecommitdiff
path: root/src/util/math.h
blob: 7bae12526fb4f8acc80de972b6ee915cf18a9daf (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
#pragma once

#include <math.h>
#include "vector.h"

inline F32 m_deg2rad( F32 deg ) { return deg * PIRAD; }
inline F32 m_rad2deg( F32 rad ) { return rad * RADPI; }

inline VEC2 m_radial_offset( F32 degrees, F32 distance ) {
  F32 rad = m_deg2rad( degrees );
  F32 x = cos( rad );
  F32 y = sin( rad );

  VEC2 ret = { x * distance, y * distance };
  return ret;
}

inline F32 m_dist_line_to_point( VEC2 p1, VEC2 p2, VEC2 p ) {
  if( vec_dist( p1, p2 ) < 0.001f )
    return vec_dist( p1, p );

  F32 a = p2.y - p1.y;
  F32 b = p1.x - p2.x;
  F32 c = p2.x * p1.y - p1.x * p2.y;

  F32 d = a * p.x + b * p.y + c;
  F32 n = sqrtf( a * a + b * b );

  F32 dot1 = (p.x - p1.x) * (p2.x - p1.x) + (p.y - p1.y) * (p2.y - p1.y);
  F32 dot2 = (p.x - p2.x) * (p1.x - p2.x) + (p.y - p2.y) * (p1.y - p2.y);

  if( dot1 < 0 ) return vec_dist( p, p1 );
  if( dot2 < 0 ) return vec_dist( p, p2 );

  return fabsf( d ) / n;
}

inline U8 m_point_in_polygon( VEC2 p, VEC2* points, U32 pointc, U32 point_stride = sizeof(VEC2) ) {
  U8 in = 0;
  for( U32 i = 0, j = pointc - 1; i < pointc; j = i++ ) {
    U8* pointarr = (U8*)points;

    VEC2* pi = (VEC2*)( pointarr + i * point_stride );
    VEC2* pj = (VEC2*)( pointarr + j * point_stride );

    if( ( pi->y > p.y ) != ( pj->y > p.y ) ) {
      if( ( p.x < ( pj->x - pi->x ) * ( p.y - pi->y ) / ( pj->y - pi->y ) + pi->x ) )
        in = !in;
    }
  }

  return in;
}

inline F32 m_snap_to_grid( F32 x, F32 grid ) {
  return x - copysignf( fmodf( fabsf( x ), grid ), x );
}

template <typename T>
T min( T a, T b ) {
  return a < b? a : b;
}

template <typename T>
T max( T a, T b ) {
  return a > b? a : b;
}

template <typename T>
inline T m_clamp( T x, T a, T b ) {
  return min( max( x, a ), b );
}

extern VEC2 m_screen_transform( const VEC3& world );