[9730] | 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 | }
|
---|