1 /*skeleton.d by Ruby The Roobster*/
2 /*Version 1.0.1 Release*/
3 /*Module for representing skeletons in the D Programming Language 2.0*/
4 /*This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
8 
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 GNU General Public License for more details.
13 
14 You should have received a copy of the GNU General Public License
15 along with this program.  If not, see <http://www.gnu.org/licenses/>.*/
16 /** Copyright: 2022, Ruby The Roobster*/
17 /**Author: Ruby The Roobster, michaeleverestc79@gmail.com*/
18 /**Date: January 19, 20222*/
19 /** License:  GPL-3.0*/
20 module dutils.skeleton;
21 ///This code sucks.  It's going bye-bye soon.
22 version(DLL)
23 {
24     export struct Point ///Structure for representing a point.
25     {		
26 	    export:
27 			///The x coordinate of the point.
28 			real x;
29 			///The y coordinate of the point.
30 			real y;
31 			///The z coordinate of the point.
32 			real z;
33 			this(real x, real y, real z)	{
34 				this.x = x;
35 				this.y = y;
36 				this.z = z;
37 			}
38 			void opAssign(Point rhs)	{
39 				this.x = rhs.x;
40 				this.y = rhs.y;
41 				this.z = rhs.z;
42 			}
43 			void opAssign(shared Point rhs) shared	{
44 				this.x = rhs.x;
45 				this.y = rhs.y;
46 				this.z = rhs.z;
47 			}
48 			void opOpAssign(string op)(Point rhs)	{
49 				this = this.opBinary!op(rhs);
50 			}
51 			void opOpAssign(string op)(Point rhs) shared	{
52 				this = this.opBinary!op(rhs);
53 			}
54 			void opOpAssign(string op)(real rhs)
55 			{
56 				this = this.opBinary!op(rhs); 
57 			}
58 			void opOpAssign(string op)(real rhs) shared
59 			{
60 				this = this.opBinary!op(rhs);
61 			}
62 			Point opBinary(string op)(Point rhs)
63 			{
64 				mixin("return Point(this.x " ~ op ~ " rhs.x, this.y " ~ op ~ " rhs.y, this.z " ~ op ~ " rhs.z);");
65 			}
66 			Point opBinary(string op)(shared Point rhs) shared
67 			{
68 				mixin("return cast(shared(Point))Point(this.x " ~ op ~ " rhs.x, this.y " ~ op ~ " rhs.y, this.z " ~ op ~ " rhs.z);");
69 			}
70 			Point opBinary(string op)(real rhs)
71 			{
72 				mixin("return Point(this.x " ~ op ~ "rhs, this.y " ~ op ~ "rhs, this.z " ~ op ~ "rhs);");
73 			}
74 			Point opBinary(string op)(real rhs) shared
75 			{
76 				mixin("return cast(shared(Point))Point(this.x " ~ op ~ "rhs, this.y " ~ op ~ "rhs, this.z " ~ op ~ "rhs);");
77 			}
78 	}
79 		
80 	/**Struct for representing a face of a skeleton that is made out of lines.*/
81 	export struct Face	{ //Face(of a 3D shape) structure...
82 		///Array of all the lines in a face.
83 		Line[] lines;
84 		///The center of the face.
85 		Point center;
86 		void opAssign(Face rhs)	{
87 			this.lines.length = rhs.lines.length;
88 			foreach(i;0 .. this.lines.length)	{
89 				this.lines[i] = rhs.lines[i];
90 			}
91 		}
92 		void opAssign(shared Face rhs)	shared {
93 			this.lines.length = rhs.lines.length;
94 			foreach(i;0 .. this.lines.length)	{
95 				this.lines[i] = rhs.lines[i];
96 			}
97 		}
98 		this(Line[] lines)
99 		{
100 		   this.lines = lines.dup;
101 		   this.center = find(Skeleton([this]));
102 		}
103 		this(Line[] lines) shared
104 		{
105 			this.lines = cast(shared(Line[]))(cast(Line[])lines).dup;
106 			this.center = cast(shared(Point))find(cast(Skeleton)Skeleton(cast(Face[])[this]));
107 		}
108 	}
109 		
110 	/**Struct for representing a 3D skeleton.*/
111 	export struct Skeleton	{ //Skeleton of a 3D structure...
112 	    export:
113 			///Array of the faces that make up the skeleton.
114 			Face[] faces;
115 			///The centroid of the skeleton.
116 			Point center;
117 			void opAssign(Skeleton rhs)	{
118 				this.faces.length = rhs.faces.length;
119 				foreach(i;0 .. this.faces.length)	{
120 					this.faces[i] = rhs.faces[i];
121 				}
122 				this.center = rhs.center;
123 			}
124 			void opAssign(shared Skeleton rhs) shared	{
125 				this.faces.length = rhs.faces.length;
126 				foreach(i;0 .. this.faces.length)	{
127 					this.faces[i] = rhs.faces[i];
128 				}
129 				this.center = rhs.center;
130 			}
131 			this(Face[] faces)
132 			{
133 				this.faces = faces.dup;
134 				this.center = find(this);
135 			}
136 			this(shared(Face)[] faces) shared
137 			{
138 				this.faces = faces.dup;
139 				this.center = cast(shared(Point))find(cast(Skeleton)this);
140 		}	
141 	}
142 
143 	package Point find(Skeleton skele)
144 	{
145 		Point x = Point(0,0,0);
146 		ulong count = 0;
147 		foreach(i; skele.faces)
148 		{
149 			foreach(j; i.lines)
150 			{
151 				foreach(k; j.mid_points)
152 				{
153 					++count;
154 					x += k;
155 				}
156 				count += 2;
157 				x += j.start;
158 				x += j.stop;
159 			}
160 		}
161 		x /= count;
162 		return x;
163 	}		
164 
165 	/**Struct for representing a line composed of at least a starting point and an end point.
166 	*/
167 	export struct Line	{ //Line struct...
168 	    export:
169 			///Array of all points that are not the start or end points.
170 			Point[] mid_points;
171 			///The start point of the line..
172 			Point start;
173 			///The end point of the line.
174 			Point stop;
175 			void opAssign(Line rhs)	{
176 				this.start = rhs.start;
177 				this.stop = rhs.stop;
178 				this.mid_points.length = rhs.mid_points.length;
179 				foreach(i;0 .. this.mid_points.length)	{
180 					this.mid_points[i] = rhs.mid_points[i];
181 				}
182 			}
183 			void opAssign(shared Line rhs) shared	{
184 				this.start = rhs.start;
185 				this.stop = rhs.stop;
186 				this.mid_points.length = rhs.mid_points.length;
187 				foreach(i;0 .. this.mid_points.length)	{
188 					this.mid_points[i] = rhs.mid_points[i];
189 				}
190 			}
191 	}
192 }
193 else
194 {
195 	public struct Point	{ ///Structure for representing a point.
196 		///The x coordinate of the point.
197 		real x;
198 		///The y coordinate of the point.
199 		real y;
200 		///The z coordinate of the point.
201 		real z;
202 		this(real x, real y, real z)	{
203 			this.x = x;
204 			this.y = y;
205 			this.z = z;
206 		}
207 		void opAssign(Point rhs)	{
208 			this.x = rhs.x;
209 			this.y = rhs.y;
210 			this.z = rhs.z;
211 		}
212 		void opAssign(shared Point rhs) shared	{
213 			this.x = rhs.x;
214 			this.y = rhs.y;
215 			this.z = rhs.z;
216 		}
217 		void opOpAssign(string op)(Point rhs)	{
218 			this = this.opBinary!op(rhs);
219 		}
220 		void opOpAssign(string op)(Point rhs) shared	{
221 			this = this.opBinary!op(rhs);
222 		}
223 		void opOpAssign(string op)(real rhs)
224 		{
225 			this = this.opBinary!op(rhs); 
226 		}
227 		void opOpAssign(string op)(real rhs) shared
228 		{
229 			this = this.opBinary!op(rhs);
230 		}
231 		Point opBinary(string op)(Point rhs)
232 		{
233 			mixin("return Point(this.x " ~ op ~ " rhs.x, this.y " ~ op ~ " rhs.y, this.z " ~ op ~ " rhs.z);");
234 		}
235 		Point opBinary(string op)(shared Point rhs) shared
236 		{
237 			mixin("return cast(shared(Point))Point(this.x " ~ op ~ " rhs.x, this.y " ~ op ~ " rhs.y, this.z " ~ op ~ " rhs.z);");
238 		}
239 		Point opBinary(string op)(real rhs)
240 		{
241 			mixin("return Point(this.x " ~ op ~ "rhs, this.y " ~ op ~ "rhs, this.z " ~ op ~ "rhs);");
242 		}
243 		Point opBinary(string op)(real rhs) shared
244 		{
245 			mixin("return cast(shared(Point))Point(this.x " ~ op ~ "rhs, this.y " ~ op ~ "rhs, this.z " ~ op ~ "rhs);");
246 		}
247 	}
248 		
249 	/**Struct for representing a face of a skeleton that is made out of lines.*/
250 	public struct Face	{ //Face(of a 3D shape) structure...
251 		///Array of all the lines in a face.
252 		Line[] lines;
253 		///The center of the face.
254 		Point center;
255 		void opAssign(Face rhs)	{
256 			this.lines.length = rhs.lines.length;
257 			foreach(i;0 .. this.lines.length)	{
258 				this.lines[i] = rhs.lines[i];
259 			}
260 		}
261 		void opAssign(shared Face rhs)	shared {
262 			this.lines.length = rhs.lines.length;
263 			foreach(i;0 .. this.lines.length)	{
264 				this.lines[i] = rhs.lines[i];
265 			}
266 		}
267 		this(Line[] lines)
268 		{
269 		   this.lines = lines.dup;
270 		   this.center = find(Skeleton([this]));
271 		}
272 		this(Line[] lines) shared
273 		{
274 			this.lines = cast(shared(Line[]))(cast(Line[])lines).dup;
275 			this.center = cast(shared(Point))find(cast(Skeleton)Skeleton(cast(Face[])[this]));
276 		}
277 	}
278 		
279 	/**Struct for representing a 3D skeleton.*/
280 	public struct Skeleton	{ //Skeleton of a 3D structure...
281 		///Array of the faces that make up the skeleton.
282 		Face[] faces;
283 		///The centroid of the skeleton.
284 		Point center;
285 		void opAssign(Skeleton rhs)	{
286 			this.faces.length = rhs.faces.length;
287 			foreach(i;0 .. this.faces.length)	{
288 				this.faces[i] = rhs.faces[i];
289 			}
290 			this.center = rhs.center;
291 		}
292 		void opAssign(shared Skeleton rhs) shared	{
293 			this.faces.length = rhs.faces.length;
294 			foreach(i;0 .. this.faces.length)	{
295 				this.faces[i] = rhs.faces[i];
296 			}
297 			this.center = rhs.center;
298 		}
299 		this(Face[] faces)
300 		{
301 			this.faces = faces.dup;
302 			this.center = find(this);
303 		}
304 		this(shared(Face)[] faces) shared
305 		{
306 			this.faces = faces.dup;
307 			this.center = cast(shared(Point))find(cast(Skeleton)this);
308 		}
309 				
310 	}
311 
312 	package Point find(Skeleton skele)
313 	{
314 		Point x = Point(0,0,0);
315 		ulong count = 0;
316 		foreach(i; skele.faces)
317 		{
318 			foreach(j; i.lines)
319 			{
320 				foreach(k; j.mid_points)
321 				{
322 					++count;
323 					x += k;
324 				}
325 				count += 2;
326 				x += j.start;
327 				x += j.stop;
328 			}
329 		}
330 		x /= count;
331 		return x;
332 	}		
333 
334 	/**Struct for representing a line composed of at least a starting point and an end point.
335 	*/
336 	public struct Line	{ //Line struct...
337 		///Array of all points that are not the start or end points.
338 		Point[] mid_points;
339 		///The start point of the line..
340 		Point start;
341 		///The end point of the line.
342 		Point stop;
343 		void opAssign(Line rhs)	{
344 			this.start = rhs.start;
345 			this.stop = rhs.stop;
346 			this.mid_points.length = rhs.mid_points.length;
347 			foreach(i;0 .. this.mid_points.length)	{
348 				this.mid_points[i] = rhs.mid_points[i];
349 			}
350 		}
351 		void opAssign(shared Line rhs) shared	{
352 			this.start = rhs.start;
353 			this.stop = rhs.stop;
354 			this.mid_points.length = rhs.mid_points.length;
355 			foreach(i;0 .. this.mid_points.length)	{
356 				this.mid_points[i] = rhs.mid_points[i];
357 			}
358 		}
359 	}
360 }
361