initial commit
[b2ld.git] / b2dlite / mathutils.d
blob336c44266bf11536adc93b46d380535915dd4fcd
1 /*
2 * Copyright (c) 2006-2007 Erin Catto http://www.gphysics.com
4 * Permission to use, copy, modify, distribute and sell this software
5 * and its documentation for any purpose is hereby granted without fee,
6 * provided that the above copyright notice appear in all copies.
7 * Erin Catto makes no representations about the suitability
8 * of this software for any purpose.
9 * It is provided "as is" without express or implied warranty.
11 module b2dlite.mathutils;
13 enum k_pi = 3.14159265358979323846264f;
16 struct Vec2 {
17 pure nothrow @safe @nogc:
18 public:
19 float x = 0, y = 0;
21 public:
22 this (float ax, float ay) { pragma(inline, true); x = ax; y = ay; }
24 void Set (float ax, float ay) { pragma(inline, true); x = ax; y = ay; }
26 Vec2 opUnary (string op:"-") () const { pragma(inline, true); return Vec2(-x, -y); }
28 void opOpAssign (string op) (in auto ref Vec2 v) if (op == "+" || op == "-") {
29 pragma(inline, true);
30 mixin("x"~op~"=v.x;");
31 mixin("y"~op~"=v.y;");
34 void opOpAssign (string op:"*") (in float a) { pragma(inline, true); x *= a; y *= a; }
36 Vec2 opBinary (string op) (in auto ref Vec2 v) const if (op == "+" || op == "-") {
37 pragma(inline, true);
38 mixin("return Vec2(x"~op~"v.x, y"~op~"v.y);");
41 Vec2 opBinary (string op:"*") (in float a) const { pragma(inline, true); return Vec2(x*a, y*a); }
42 Vec2 opBinaryRight (string op:"*") (in float a) const { pragma(inline, true); return Vec2(x*a, y*a); }
44 float Length () const { pragma(inline, true); import std.math : sqrt; return sqrt(x*x+y*y); }
48 struct Mat22 {
49 pure nothrow @safe @nogc:
50 public:
51 Vec2 col1, col2;
53 public:
54 this (float angle) {
55 pragma(inline, true);
56 import std.math : cos, sin;
57 immutable float c = cos(angle), s = sin(angle);
58 col1.x = c; col1.y = s;
59 col2.x = -s; col2.y = c;
62 this() (in auto ref Vec2 acol1, in auto ref Vec2 acol2) { pragma(inline, true); col1 = acol1; col2 = acol2; }
64 Mat22 Transpose () const { pragma(inline, true); return Mat22(Vec2(col1.x, col2.x), Vec2(col1.y, col2.y)); }
66 Mat22 Invert () const {
67 pragma(inline, true);
68 immutable float a = col1.x, b = col2.x, c = col1.y, d = col2.y;
69 Mat22 B;
70 float det = a*d-b*c;
71 assert(det != 0.0f);
72 det = 1.0f/det;
73 B.col1.x = det*d;
74 B.col2.x = -det*b;
75 B.col1.y = -det*c;
76 B.col2.y = det*a;
77 return B;
80 Vec2 opBinary(string op:"*") (in auto ref Vec2 v) const { pragma(inline, true); return Vec2(col1.x*v.x+col2.x*v.y, col1.y*v.x+col2.y*v.y); }
82 Mat22 opBinary(string op:"+") (in auto ref Mat22 B) const { pragma(inline, true); return Mat22(col1+B.col1, col2+B.col2); }
83 Mat22 opBinary(string op:"*") (in auto ref Mat22 B) const { pragma(inline, true); return Mat22(this*B.col1, this*B.col2); }
87 float Dot() (in auto ref Vec2 a, in auto ref Vec2 b) { pragma(inline, true); return a.x*b.x+a.y*b.y; }
88 float Cross() (in auto ref Vec2 a, in auto ref Vec2 b) { pragma(inline, true); return a.x*b.y-a.y*b.x; }
89 Vec2 Cross() (in auto ref Vec2 a, float s) { pragma(inline, true); return Vec2(s*a.y, -s*a.x); }
90 Vec2 Cross() (float s, in auto ref Vec2 a) { pragma(inline, true); return Vec2(-s*a.y, s*a.x); }
92 float Abs() (float a) { import std.math : abs; pragma(inline, true); return /*(a > 0.0f ? a : -a)*/abs(a); }
93 Vec2 Abs() (in auto ref Vec2 a) { import std.math : abs; pragma(inline, true); return Vec2(abs(a.x), abs(a.y)); }
94 Mat22 Abs() (in auto ref Mat22 A) { pragma(inline, true); return Mat22(Abs(A.col1), Abs(A.col2)); }
96 float Sign (float x) { pragma(inline, true); return (x < 0.0f ? -1.0f : 1.0f); }
98 float Min (float a, float b) { pragma(inline, true); return (a < b ? a : b); }
99 float Max (float a, float b) { pragma(inline, true); return (a > b ? a : b); }
101 float Clamp (float a, float low, float high) { pragma(inline, true); return Max(low, Min(a, high)); }
103 void Swap(T) (ref T a, ref T b) {
104 T tmp = a;
105 a = b;
106 b = tmp;
109 // Random number in range [-1,1]
110 float Random (void) {
111 pragma(inline, true);
112 import std.random : uniform;
113 return cast(float)uniform!"[]"(-1.0f, 1.0f);
116 float Random (float lo, float hi) {
117 pragma(inline, true);
118 import std.random : uniform;
119 return cast(float)uniform!"[]"(lo, hi);