1 | namespace MIConvexHull
|
---|
2 | {
|
---|
3 | using System;
|
---|
4 | using System.Collections.Generic;
|
---|
5 |
|
---|
6 | /// <summary>
|
---|
7 | /// Used to effectively store vertices beyond.
|
---|
8 | /// </summary>
|
---|
9 | /// <typeparam name="T"></typeparam>
|
---|
10 | sealed class VertexBuffer
|
---|
11 | {
|
---|
12 | VertexWrap[] items;
|
---|
13 | int count;
|
---|
14 | int capacity;
|
---|
15 |
|
---|
16 | /// <summary>
|
---|
17 | /// Number of elements present in the buffer.
|
---|
18 | /// </summary>
|
---|
19 | public int Count { get { return count; } }
|
---|
20 |
|
---|
21 | /// <summary>
|
---|
22 | /// Get the i-th element.
|
---|
23 | /// </summary>
|
---|
24 | /// <param name="i"></param>
|
---|
25 | /// <returns></returns>
|
---|
26 | public VertexWrap this[int i]
|
---|
27 | {
|
---|
28 | get { return items[i]; }
|
---|
29 | }
|
---|
30 |
|
---|
31 | /// <summary>
|
---|
32 | /// Size matters.
|
---|
33 | /// </summary>
|
---|
34 | void EnsureCapacity()
|
---|
35 | {
|
---|
36 | if (count + 1 > capacity)
|
---|
37 | {
|
---|
38 | if (capacity == 0) capacity = 4;
|
---|
39 | else capacity = 2 * capacity;
|
---|
40 | Array.Resize(ref items, capacity);
|
---|
41 | }
|
---|
42 | }
|
---|
43 |
|
---|
44 | /// <summary>
|
---|
45 | /// Adds a vertex to the buffer.
|
---|
46 | /// </summary>
|
---|
47 | /// <param name="item"></param>
|
---|
48 | public void Add(VertexWrap item)
|
---|
49 | {
|
---|
50 | EnsureCapacity();
|
---|
51 | items[count++] = item;
|
---|
52 | }
|
---|
53 |
|
---|
54 | /// <summary>
|
---|
55 | /// Sets the Count to 0, otherwise does nothing.
|
---|
56 | /// </summary>
|
---|
57 | public void Clear()
|
---|
58 | {
|
---|
59 | count = 0;
|
---|
60 | }
|
---|
61 | }
|
---|
62 |
|
---|
63 | /// <summary>
|
---|
64 | /// A priority based linked list.
|
---|
65 | /// </summary>
|
---|
66 | sealed class FaceList
|
---|
67 | {
|
---|
68 | ConvexFaceInternal first, last;
|
---|
69 |
|
---|
70 | /// <summary>
|
---|
71 | /// Get the first element.
|
---|
72 | /// </summary>
|
---|
73 | public ConvexFaceInternal First { get { return first; } }
|
---|
74 |
|
---|
75 | /// <summary>
|
---|
76 | /// Adds the element to the beginning.
|
---|
77 | /// </summary>
|
---|
78 | /// <param name="face"></param>
|
---|
79 | void AddFirst(ConvexFaceInternal face)
|
---|
80 | {
|
---|
81 | face.InList = true;
|
---|
82 | this.first.Previous = face;
|
---|
83 | face.Next = this.first;
|
---|
84 | this.first = face;
|
---|
85 | }
|
---|
86 |
|
---|
87 | /// <summary>
|
---|
88 | /// Adds a face to the list.
|
---|
89 | /// </summary>
|
---|
90 | /// <param name="face"></param>
|
---|
91 | public void Add(ConvexFaceInternal face)
|
---|
92 | {
|
---|
93 | if (face.InList)
|
---|
94 | {
|
---|
95 | //if (this.first.FurthestDistance < face.FurthestDistance)
|
---|
96 | if (this.first.VerticesBeyond.Count < face.VerticesBeyond.Count)
|
---|
97 | {
|
---|
98 | Remove(face);
|
---|
99 | AddFirst(face);
|
---|
100 | }
|
---|
101 | return;
|
---|
102 | }
|
---|
103 |
|
---|
104 | face.InList = true;
|
---|
105 |
|
---|
106 | //if (first != null && first.FurthestDistance < face.FurthestDistance)
|
---|
107 | if (first != null && first.VerticesBeyond.Count < face.VerticesBeyond.Count)
|
---|
108 | {
|
---|
109 | this.first.Previous = face;
|
---|
110 | face.Next = this.first;
|
---|
111 | this.first = face;
|
---|
112 | }
|
---|
113 | else
|
---|
114 | {
|
---|
115 | if (this.last != null)
|
---|
116 | {
|
---|
117 | this.last.Next = face;
|
---|
118 | }
|
---|
119 | face.Previous = this.last;
|
---|
120 | this.last = face;
|
---|
121 | if (this.first == null)
|
---|
122 | {
|
---|
123 | this.first = face;
|
---|
124 | }
|
---|
125 | }
|
---|
126 | }
|
---|
127 |
|
---|
128 | /// <summary>
|
---|
129 | /// Removes the element from the list.
|
---|
130 | /// </summary>
|
---|
131 | /// <param name="face"></param>
|
---|
132 | public void Remove(ConvexFaceInternal face)
|
---|
133 | {
|
---|
134 | if (!face.InList) return;
|
---|
135 |
|
---|
136 | face.InList = false;
|
---|
137 |
|
---|
138 | if (face.Previous != null)
|
---|
139 | {
|
---|
140 | face.Previous.Next = face.Next;
|
---|
141 | }
|
---|
142 | else if (/*first == face*/ face.Previous == null)
|
---|
143 | {
|
---|
144 | this.first = face.Next;
|
---|
145 | }
|
---|
146 |
|
---|
147 | if (face.Next != null)
|
---|
148 | {
|
---|
149 | face.Next.Previous = face.Previous;
|
---|
150 | }
|
---|
151 | else if (/*last == face*/ face.Next == null)
|
---|
152 | {
|
---|
153 | this.last = face.Previous;
|
---|
154 | }
|
---|
155 |
|
---|
156 | face.Next = null;
|
---|
157 | face.Previous = null;
|
---|
158 | }
|
---|
159 | }
|
---|
160 |
|
---|
161 | /// <summary>
|
---|
162 | /// Connector list.
|
---|
163 | /// </summary>
|
---|
164 | sealed class ConnectorList
|
---|
165 | {
|
---|
166 | FaceConnector first, last;
|
---|
167 |
|
---|
168 | /// <summary>
|
---|
169 | /// Get the first element.
|
---|
170 | /// </summary>
|
---|
171 | public FaceConnector First { get { return first; } }
|
---|
172 |
|
---|
173 | /// <summary>
|
---|
174 | /// Adds the element to the beginning.
|
---|
175 | /// </summary>
|
---|
176 | /// <param name="connector"></param>
|
---|
177 | void AddFirst(FaceConnector connector)
|
---|
178 | {
|
---|
179 | this.first.Previous = connector;
|
---|
180 | connector.Next = this.first;
|
---|
181 | this.first = connector;
|
---|
182 | }
|
---|
183 |
|
---|
184 | /// <summary>
|
---|
185 | /// Adds a face to the list.
|
---|
186 | /// </summary>
|
---|
187 | /// <param name="element"></param>
|
---|
188 | public void Add(FaceConnector element)
|
---|
189 | {
|
---|
190 | if (this.last != null)
|
---|
191 | {
|
---|
192 | this.last.Next = element;
|
---|
193 | }
|
---|
194 | element.Previous = this.last;
|
---|
195 | this.last = element;
|
---|
196 | if (this.first == null)
|
---|
197 | {
|
---|
198 | this.first = element;
|
---|
199 | }
|
---|
200 | }
|
---|
201 |
|
---|
202 | /// <summary>
|
---|
203 | /// Removes the element from the list.
|
---|
204 | /// </summary>
|
---|
205 | /// <param name="connector"></param>
|
---|
206 | public void Remove(FaceConnector connector)
|
---|
207 | {
|
---|
208 | if (connector.Previous != null)
|
---|
209 | {
|
---|
210 | connector.Previous.Next = connector.Next;
|
---|
211 | }
|
---|
212 | else if (/*first == face*/ connector.Previous == null)
|
---|
213 | {
|
---|
214 | this.first = connector.Next;
|
---|
215 | }
|
---|
216 |
|
---|
217 | if (connector.Next != null)
|
---|
218 | {
|
---|
219 | connector.Next.Previous = connector.Previous;
|
---|
220 | }
|
---|
221 | else if (/*last == face*/ connector.Next == null)
|
---|
222 | {
|
---|
223 | this.last = connector.Previous;
|
---|
224 | }
|
---|
225 |
|
---|
226 | connector.Next = null;
|
---|
227 | connector.Previous = null;
|
---|
228 | }
|
---|
229 | }
|
---|
230 | }
|
---|