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