add support to SDLBackend for rendering 24bit data
[openc2e.git] / physics.h
bloba019b7c5d3ea77d3f1877ebeddc4ab52802a0a1c
1 /*
2 * physics.h
3 * openc2e
5 * Created by Alyssa Milburn on Tue 08 Feb 2005.
6 * Copyright (c) 2005 Alyssa Milburn. All rights reserved.
7 * Copyright (c) 2005 Bryan Donlan. All rights reserved.
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
20 #ifndef PHYSICS_H
21 #define PHYSICS_H 1
23 #include <iostream> // XXX debug
24 #include <cmath> // sqrt
25 #include <algorithm> // swap
26 #include "openc2e.h" // FRIEND_SERIALIZE
28 struct Point {
29 float x, y;
30 Point() { x = y = 0; }
31 Point(float _x, float _y) : x(_x), y(_y) {}
32 Point(const Point &p) : x(p.x), y(p.y) { }
34 bool operator==(const Point &p) { return x == p.x && y == p.y; }
35 bool operator!=(const Point &p) { return !(*this == p); }
36 Point &operator=(const Point &r) {
37 x = r.x;
38 y = r.y;
39 return *this;
43 enum linetype { NORMAL, HORIZONTAL, VERTICAL };
45 class Line {
46 protected:
47 FRIEND_SERIALIZE(Line);
48 Point start, end;
49 double x_icept, y_icept, slope;
50 linetype type;
51 public:
53 void dump() const;
55 Line() {
56 start = Point(0,0);
57 end = Point(1,1);
58 x_icept = y_icept = 0;
59 slope = 1;
60 type = NORMAL;
63 Line(const Line &l) {
64 start = l.start;
65 end = l.end;
66 x_icept = l.x_icept;
67 y_icept = l.y_icept;
68 slope = l.slope;
69 type = l.type;
72 Line(Point s, Point e);
74 Line &operator=(const Line &l) {
75 start = l.start;
76 end = l.end;
77 x_icept = l.x_icept;
78 y_icept = l.y_icept;
79 slope = l.slope;
80 type = l.type;
81 return *this;
84 bool intersect(const Line &l, Point &where) const;
86 linetype getType() const { return type; }
87 double xIntercept() const { return x_icept; }
88 double yIntercept() const { return y_icept; }
89 double getSlope() const { return slope; }
90 const Point &getStart() const { return start; }
91 const Point &getEnd() const { return end; }
93 // TODO: this code hasn't really been tested - fuzzie
94 bool containsPoint(Point p) const {
95 if (type == VERTICAL) {
96 bool is_x = fabs(start.x - p.x) < 1;
97 bool is_y = containsY(p.y);
98 // TODO
99 //bool is_v = (start.x > (p.x + 0.5)) && (start.x < (p.x - 0.5));
100 //bool is_h = (start.y > (p.y + 0.5)) && (start.y < (p.y - 0.5));
101 return (is_x && is_y);
102 } else if (type == HORIZONTAL) {
103 bool is_y = fabs(start.y - p.y) < 1;
104 bool is_x = containsX(p.x);
106 return is_x && is_y;
107 } else {
108 Point point_on_line = pointAtX(p.x);
109 return containsX(p.x) && fabs(point_on_line.y - p.y) < 1;
113 Point pointAtX(double x) const
115 assert(type != VERTICAL);
116 if (type == NORMAL)
117 return Point(x, (x - start.x) * slope + start.y);
118 else
119 return Point(x, start.y);
122 Point pointAtY(double y) const
124 assert(type != HORIZONTAL);
125 if (type == NORMAL)
126 return Point((y - start.y) / slope + start.x, y);
127 else
128 return Point(start.x, y);
131 bool containsX(double x) const {
132 return x >= start.x && x <= end.x;
135 bool containsY(double y) const {
136 if (start.y > end.y)
137 return y <= start.y && y >= end.y;
138 else
139 return y >= start.y && y <= end.y;
142 void sanity_check() const;
145 template <class T = double>
146 class Vector {
147 public:
148 T x, y;
149 Vector() {
150 x = y = 0;
153 Vector(T _x, T _y) {
154 x = _x;
155 y = _y;
158 Vector(const Point &s, const Point &e) {
159 x = e.x - s.x;
160 y = e.y - s.y;
163 T getMagnitude() const { return sqrt(x*x+y*y); }
165 Line extendFrom(const Point &p) const {
166 return Line(p, Point(p.x + x, p.y + y));
169 Vector scaleToMagnitude(T m) const {
170 return Vector(x/getMagnitude()*m, y/getMagnitude()*m);
173 Vector scale(T multiplier) const {
174 return Vector(x * multiplier, y * multiplier);
177 bool extendIntersect(const Point &start, Line barrier,
178 Vector &residual) const {
179 Line l = extendFrom(start);
180 Point i;
181 if (!l.intersect(barrier, i))
182 return false;
183 residual = Vector(i, Point(start.x + x, start.y + y));
184 return true;
187 T getX() const { return x; }
188 T getY() const { return y; }
190 Vector operator*(T m) const {
191 return scale(m);
194 Vector operator+(const Vector &v) const {
195 return Vector(x + v.x, y + v.y);
198 Vector operator-(const Vector &v) const {
199 return Vector(x - v.x, y - v.y);
202 bool operator==(const Vector &v) const {
203 return (x == v.x) && (y == v.y);
206 static Vector unitVector(T angle) {
207 return Vector(cos(angle), sin(angle));
211 template <class T>
212 Point operator+(const Vector<T> &v, const Point &p) {
213 return Point(v.x + p.x, v.y + p.y);
216 template <class T>
217 Point operator+(const Point &p, const Vector<T> &v) {
218 return v + p;
221 #endif
222 /* vim: set noet: */