aboutsummaryrefslogtreecommitdiff
path: root/engines/sword25/math/polygon.h
blob: 68e2f4c05a04bc6594c431157894fe0c2c9d603c (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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
// -----------------------------------------------------------------------------
// This file is part of Broken Sword 2.5
// Copyright (c) Malte Thiesen, Daniel Queteschiner and Michael Elsd�rfer
//
// Broken Sword 2.5 is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// Broken Sword 2.5 is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Broken Sword 2.5; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
// -----------------------------------------------------------------------------

#ifndef BS_POLYGON_H
#define BS_POLYGON_H

// Includes
#include "kernel/common.h"
#include "kernel/persistable.h"
#include "vertex.h"

// -----------------------------------------------------------------------------
// Forward Declarations
// -----------------------------------------------------------------------------

class BS_Vertex;

/**
	@brief Eine Polygonklasse.
*/
class BS_Polygon : public BS_Persistable
{
public:
	/**
		@brief Erzeugt ein Objekt vom Typ #BS_Polygon, das 0 Vertecies enth�lt.

		Mit der Methode Init() k�nnen dem Polygon sp�ter Vertecies hinzugef�gt werden.
	*/
	BS_Polygon();

	/**
		@brief Copy-Constructor
	*/
	BS_Polygon(const BS_Polygon& Other);

	/**
		@brief Erstellt ein Polygon anhand persistierter Daten.
	*/
	BS_Polygon(BS_InputPersistenceBlock & Reader);

	/**
		@brief Erzeugt ein Objekt vom Typ #BS_Polygon und ordnet ihm Vertecies zu.
		@param VertexCount die Anzahl der Vertecies im Vertex Array.
		@param Vertecies ein Array, das Objekte vom Typ BS_Vertex enth�lt, die die Vertecies des Polygons darstellen.
		@remark Die Vertecies m�ssen ein nicht selbst�berschneidendes Polygon definieren.
				Falls das Polygon selbst�berschneidend sein sollte wird ein leeres BS_Polygon Objekt erzeugt.
	*/
	BS_Polygon(int VertexCount, const BS_Vertex* Vertecies);

	/**
		@brief L�scht das BS_Polygon Objekt.
	*/
	virtual ~BS_Polygon();

	/**
		@brief Initialisiert das BS_Polygon mit einer Liste von Vertecies.

		Die Vertecies m�ssen ein nicht selbst�berschneidendes Polygon definieren.
		Es kann auch einem Polygon, welches bereits Vertecies enth�lt, mit einer neue Vertexliste initialisiert werden, dabei gehen die
		alten Vertecies verloren.

		@param VertexCount die Anzahl der Vertecies im Vertecies Array.
		@param Vertecies ein Array, das Objekte vom Typ BS_Vertex enth�lt, die die Vertecies des Polygons darstellen.
		@return Gibt false zur�ck, falls die Vertecies ein selbst�berschneidendes Polygon definiert haben.
				In diesem Fall wird das Objekt nicht initialisiert.
	*/
	bool Init(int VertexCount, const BS_Vertex* Vertecies);

	//@{
	/** @name Sondierende Methoden */
	
	/**
		@brief �berpr�ft, ob die Vertecies des Polygons im Uhrzeigersinn angeordnet sind.
		@return Gibt true zur�ck, wenn die Vertecies des Polygons im Uhrzeigersinn angeordnet sind oder Koplanar sind.<br>
				Gibt false zur�ck, wenn die Vertecies des Polygons entgegen dem Uhrzeigersinn angeordnet sind.
		@remark Diese Methode gibt nur ein sinnvolles Ergebnis zur�ck, wenn das Polygon mindestens 3 Vertecies hat.
	*/
	bool IsCW() const;

	/**
		@brief �berpr�ft, ob die Vertecies des Polygons entgegen dem Uhrzeigersinn angeordnet sind.
		@return Gibt true zur�ck, wenn die Vertecies des Polygons entgegen dem Uhrzeigersinn angeordnet sind.<br>
				Gibt false zur�ck, wenn die Vertecies des Polygons im Uhrzeigersinn angeordnet sind oder Koplanar sind.
		@remark Diese Methode gibt nur ein sinnvolles Ergebnis zur�ck, wenn das Polygon mindestens 3 Vertecies hat.
				
	*/
	bool IsCCW() const;

	/**
		@brief �berpr�ft, ob das Polygon konvex ist.
		@return Gibt true zur�ck, wenn das Polygon konvex ist.<br>
				Gibt false zur�ck, wenn das Polygon konkav ist.
		@remark Diese Methode gibt nur ein sinnvolles Ergebnis zur�ck, wenn das Polygon mindestens 3 Vertecies hat.
	*/
	bool IsConvex() const;

	/** 
		@brief �berpr�ft, ob das Polygon konkav ist.
		@return Gibt true zur�ck, wenn das Polygon konkav ist.<br>
				Gibt false zur�ck, wenn das Polygon konvex ist.
		@remark Diese Methode gibt nur ein sinnvolles Ergebnis zur�ck, wenn das Polygon mindestens 3 Vertecies hat.
	*/
	bool IsConcave() const;

	/**
		@brief �berpr�ft, ob sich ein Punkt innerhalb des Polygons befindet.
		@param Vertex ein Vertex, mit den Koordinaten des zu testenden Punktes.
		@param BorderBelongsToPolygon gibt an, ob der Rand des Polygons als Teil des Polygons betrachtet werden soll.<br>
									  Der Standardwert ist true.
		@return Gibt true zur�ck, wenn sich der Punkt innerhalb des Polygons befindet.<br>
				Gibt false zur�ck, wenn sich der Punkt au�erhalb des Polygons befindet.
	*/
	bool IsPointInPolygon(const BS_Vertex& Vertex, bool BorderBelongsToPolygon = true) const;

	/**
		@brief �berpr�ft, ob sich ein Punkt innerhalb des Polygons befindet.
		@param X die Position des Punktes auf der X-Achse.
		@param Y die Position des Punktes auf der Y-Achse.
		@param BorderBelongsToPolygon gibt an, ob der Rand des Polygons als Teil des Polygons betrachtet werden soll.<br>
									  Der Standardwert ist true.
		@return Gibt true zur�ck, wenn sich der Punkt innerhalb des Polygons befindet.<br>
				Gibt false zur�ck, wenn sich der Punkt au�erhalb des Polygons befindet.
	*/
	bool IsPointInPolygon(int X, int Y, bool BorderBelongsToPolygon = true) const;

	/**
		@brief Gibt den Schwerpunkt des Polygons zur�ck.
	*/
	BS_Vertex GetCentroid() const;

	// Rand geh�rt zum Polygon
	// Polygon muss CW sein
	bool IsLineInterior(const BS_Vertex & a, const BS_Vertex & b) const;
	// Rand geh�rt nicht zum Polygon
	// Polygon muss CW sein
	bool IsLineExterior(const BS_Vertex & a, const BS_Vertex & b) const;

	//@}

	//@{
	/** @name Manipulierende Methoden */

	/**
		@brief Stellt sicher, dass die Vertecies des Polygons im Uhrzeigersinn angeordnet sind.
	*/
	void EnsureCWOrder();

	/**
		@brief Stellt sicher, dass die Vertecies des Polygons entgegen dem Uhrzeigersinn angeordnet sind.
	*/
	void EnsureCCWOrder();

	/**
		@brief Kehrt die Reihenfolge der Vertecies um.
	*/
	void ReverseVertexOrder();

	/**
		@brief Verschiebt das Polygon.
		@param Delta das Vertex um das das Polygon verschoben werden soll.
	*/
	void operator+=(const BS_Vertex& Delta);

	//@}

	/// Gibt die Anzahl an Vertecies im Vertecies-Array an.
	int VertexCount;
	/// Enth�lt die Vertecies des Polygons.
	BS_Vertex* Vertecies;

	virtual bool Persist(BS_OutputPersistenceBlock & Writer);
	virtual bool Unpersist(BS_InputPersistenceBlock & Reader);

private:
	bool m_IsCW;
	bool m_IsConvex;
	BS_Vertex m_Centroid;
	
	/**
		@brief Berechnet den Schwerpunkt des Polygons.
	*/
	BS_Vertex ComputeCentroid() const;

	/**
		@brief Bestimmt wie die Vertecies des Polygon angeordnet sind.
		@return Gibt true zur�ck, wenn die Vertecies im Uhrzeigersinn angeordnet sind, ansonsten false.
	*/
	bool ComputeIsCW() const;

	/**
		@brief Bestimmt ob das Polygon Konvex oder Konkav ist.
		@return Gibt true zur�ck, wenn das Polygon Konvex ist, ansonsten false.
	*/
	bool ComputeIsConvex() const;

	/**
		@brief Berechnet das Kreuzprodukt dreier Vertecies.
		@param V1 das erste Vertex
		@param V2 des zweite Vertex
		@param V3 das dritte Vertex
		@return Gibt das Kreuzprodukt der drei Vertecies zur�ck.
		@todo Diese Methode sollte an geeigneter Stelle in die BS_Vertex Klasse integriert werden.
	*/
	int CrossProduct(const BS_Vertex& V1, const BS_Vertex& V2, const BS_Vertex& V3) const;

	/**
		@brief Berechnet des Skalarprodukt der beiden von drei Vertecies aufgespannten Vektoren.

		Die Vektoren werden von V2 -> V1 und V2 -> V3 aufgespannt.
		
		@param V1 das erste Vertex
		@param V2 des zweite Vertex
		@param V3 das dritte Vertex
		@return Gibt das Skalarprodukt der drei Vertecies zur�ck.
		@todo Diese Methode sollte an geeigneter Stelle in die BS_Vertex Klasse integriert werden.
	*/
	int DotProduct(const BS_Vertex& V1, const BS_Vertex& V2, const BS_Vertex& V3) const;

	/**
		@brief �berpr�ft ob das Polygon selbst�berschneidend ist.
		@return Gibt true zur�ck, wenn das Polygon selbst�berschneidend ist.<br>
				Gibt false zur�ck, wenn das Polygon nicht selbst�berschneidend ist.
	*/
	bool CheckForSelfIntersection() const;

	/**
		@brief Findet das Vertex des Polygons das am weitesten rechts unten liegt und gibt dessen Index im Vertex-Array zur�ck.
		@return Gibt den Index des Vertex zur�ck das am weiteesten rechts unten liegt.<br>
				Gibt -1 zur�ck, wenn die Vertexliste leer ist.
	*/
	int FindLRVertexIndex() const;

	bool IsLineInCone(int StartVertexIndex, const BS_Vertex & EndVertex, bool IncludeEdges) const;
};

#endif