1 module vector_2i;
2 
3 import Math = math;
4 
5 import vector_2d;
6 
7 
8 /*
9  * The MIT License
10  *
11  * Copyright (c) 2015-2021 Richard Greenlees
12  @#$@#!$ Translated by jordan4ibanez
13  *
14  * Permission is hereby granted, free of charge, to any person obtaining a copy
15  * of this software and associated documentation files (the "Software"), to deal
16  * in the Software without restriction, including without limitation the rights
17  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
18  * copies of the Software, and to permit persons to whom the Software is
19  * furnished to do so, subject to the following conditions:
20  *
21  * The above copyright notice and this permission notice shall be included in
22  * all copies or substantial portions of the Software.
23  *
24  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
25  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
27  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
29  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
30  * THE SOFTWARE.
31  */
32 
33 /**
34  * Represents a 2D vector with single-precision.
35  *
36  * @author RGreenlees
37  * @author Kai Burjack
38  * @author Hans Uhlig
39  */
40 struct Vector2i {
41 
42     /**
43      * The x component of the vector.
44      */
45     public int x;
46     /**
47      * The y component of the vector.
48      */
49     public int y;
50 
51     /**
52      * Create a new {@link Vector2i} and initialize both of its components with
53      * the given value.
54      *
55      * @param s
56      *          the value of both components
57      */
58     this(int s) {
59         this.x = s;
60         this.y = s;
61     }
62 
63     /**
64      * Create a new {@link Vector2i} and initialize its components to the given values.
65      *
66      * @param x
67      *          the x component
68      * @param y
69      *          the y component
70      */
71     this(int x, int y) {
72         this.x = x;
73         this.y = y;
74     }
75 
76     /**
77      * Create a new {@link Vector2i} and initialize its component values and
78      * round using the given {@link RoundingMode}.
79      * @param x
80      *          the x component
81      * @param y
82      *          the y component
83      * @param mode
84      *          the {@link RoundingMode} to use
85      */
86     this(double x, double y, int mode) {
87         this.x = Math.roundUsing(x, mode);
88         this.y = Math.roundUsing(y, mode);
89     }
90 
91     /**
92      * Create a new {@link Vector2i} and initialize its components to the one of
93      * the given vector.
94      *
95      * @param v
96      *          the {@link Vector2i} to copy the values from
97      */
98     this(Vector2i v) {
99         x = v.x;
100         y = v.y;
101     }
102 
103     /**
104      * Create a new {@link Vector2i} and initialize its components to the rounded value of
105      * the given vector.
106      *
107      * @param v
108      *          the {@link Vector2d} to round and copy the values from
109      * @param mode
110      *          the {@link RoundingMode} to use
111      */
112     this(Vector2d v, int mode) {
113         x = Math.roundUsing(v.x, mode);
114         y = Math.roundUsing(v.y, mode);
115     }
116 
117     /**
118      * Create a new {@link Vector2i} and initialize its two components from the first
119      * two elements of the given array.
120      * 
121      * @param xy
122      *          the array containing at least three elements
123      */
124     this(int[] xy) {
125         this.x = xy[0];
126         this.y = xy[1];
127     }
128 
129     /**
130      * Set the x and y components to the supplied value.
131      *
132      * @param s
133      *          scalar value of both components
134      * @return this
135      */
136     ref public Vector2i set(int s) return {
137         this.x = s;
138         this.y = s;
139         return this;
140     }
141 
142     /**
143      * Set the x and y components to the supplied values.
144      *
145      * @param x
146      *          the x component
147      * @param y
148      *          the y component
149      * @return this
150      */
151     ref public Vector2i set(int x, int y) return {
152         this.x = x;
153         this.y = y;
154         return this;
155     }
156 
157     /**
158      * Set this {@link Vector2i} to the values of v.
159      *
160      * @param v
161      *          the vector to copy from
162      * @return this
163      */
164     ref public Vector2i set(Vector2i v) return {
165         this.x = v.x;
166         this.y = v.y;
167         return this;
168     }
169 
170     /**
171      * Set this {@link Vector2i} to the values of v using {@link RoundingMode#TRUNCATE} rounding.
172      * <p>
173      * Note that due to the given vector <code>v</code> storing the components
174      * in double-precision, there is the possibility to lose precision.
175      *
176      * @param v
177      *          the vector to copy from
178      * @return this
179      */
180     ref public Vector2i set(Vector2d v) return {
181         this.x = cast(int) v.x;
182         this.y = cast(int) v.y;
183         return this;
184     }
185 
186     /**
187      * Set this {@link Vector2i} to the values of v using the given {@link RoundingMode}.
188      * <p>
189      * Note that due to the given vector <code>v</code> storing the components
190      * in double-precision, there is the possibility to lose precision.
191      *
192      * @param v
193      *          the vector to copy from
194      * @param mode
195      *          the {@link RoundingMode} to use
196      * @return this
197      */
198     ref public Vector2i set(Vector2d v, int mode) return {
199         this.x = Math.roundUsing(v.x, mode);
200         this.y = Math.roundUsing(v.y, mode);
201         return this;
202     }
203 
204     /**
205      * Set the two components of this vector to the first two elements of the given array.
206      * 
207      * @param xy
208      *          the array containing at least two elements
209      * @return this
210      */
211     ref public Vector2i set(int[] xy) return {
212         this.x = xy[0];
213         this.y = xy[1];
214         return this;
215     }
216 
217     public int get(int component) {
218         switch (component) {
219         case 0:
220             return x;
221         case 1:
222             return y;
223         default:
224             return 0; // do nothing
225         }
226     }
227 
228     /**
229      * Set the value of the specified component of this vector.
230      *
231      * @param component
232      *          the component whose value to set, within <code>[0..1]</code>
233      * @param value
234      *          the value to set
235      * @return this
236      * @throws IllegalArgumentException if <code>component</code> is not within <code>[0..1]</code>
237      */
238     ref public Vector2i setComponent(int component, int value) return {
239         switch (component) {
240             case 0:
241                 x = value;
242                 break;
243             case 1:
244                 y = value;
245                 break;
246             default:{}
247         }
248         return this;
249     }
250 
251     /**
252      * Subtract the supplied vector from this one and store the result in
253      * <code>this</code>.
254      *
255      * @param v
256      *          the vector to subtract
257      * @return this
258      */
259     ref public Vector2i sub(Vector2i v) return {
260         this.x = x - v.x;
261         this.y = y - v.y;
262         return this;
263     }
264 
265     public Vector2i sub(Vector2i v, ref Vector2i dest) {
266         dest.x = x - v.x;
267         dest.y = y - v.y;
268         return dest;
269     }
270 
271     /**
272      * Decrement the components of this vector by the given values.
273      *
274      * @param x
275      *          the x component to subtract
276      * @param y
277      *          the y component to subtract
278      * @return this
279      */
280     ref public Vector2i sub(int x, int y) return {
281         this.x = this.x - x;
282         this.y = this.y - y;
283         return this;
284     }
285 
286     public Vector2i sub(int x, int y, ref Vector2i dest) {
287         dest.x = this.x - x;
288         dest.y = this.y - y;
289         return dest;
290     }
291 
292     public long lengthSquared() {
293         return x * x + y * y;
294     }
295 
296     /**
297      * Get the length squared of a 2-dimensional single-precision vector.
298      *
299      * @param x The vector's x component
300      * @param y The vector's y component
301      *
302      * @return the length squared of the given vector
303      */
304     public static long lengthSquared(int x, int y) {
305         return x * x + y * y;
306     }
307 
308     public double length() {
309         return Math.sqrt(x * x + y * y);
310     }
311 
312     /**
313      * Get the length of a 2-dimensional single-precision vector.
314      *
315      * @param x The vector's x component
316      * @param y The vector's y component
317      *
318      * @return the length squared of the given vector
319      */
320     public static double length(int x, int y) {
321         return Math.sqrt(x * x + y * y);
322     }
323 
324     public double distance(Vector2i v) {
325         int dx = this.x - v.x;
326         int dy = this.y - v.y;
327         return Math.sqrt(dx * dx + dy * dy);
328     }
329 
330     public double distance(int x, int y) {
331         int dx = this.x - x;
332         int dy = this.y - y;
333         return Math.sqrt(dx * dx + dy * dy);
334     }
335 
336     public long distanceSquared(Vector2i v) {
337         int dx = this.x - v.x;
338         int dy = this.y - v.y;
339         return dx * dx + dy * dy;
340     }
341 
342     public long distanceSquared(int x, int y) {
343         int dx = this.x - x;
344         int dy = this.y - y;
345         return dx * dx + dy * dy;
346     }
347 
348     public long gridDistance(Vector2i v) {
349         return Math.abs(v.x - x) + Math.abs(v.y - y);
350     }
351 
352     public long gridDistance(int x, int y) {
353         return Math.abs(x - this.x) + Math.abs(y - this.y);
354     }
355 
356     /**
357      * Return the distance between <code>(x1, y1)</code> and <code>(x2, y2)</code>.
358      *
359      * @param x1
360      *          the x component of the first vector
361      * @param y1
362      *          the y component of the first vector
363      * @param x2
364      *          the x component of the second vector
365      * @param y2
366      *          the y component of the second vector
367      * @return the euclidean distance
368      */
369     public static double distance(int x1, int y1, int x2, int y2) {
370         int dx = x1 - x2;
371         int dy = y1 - y2;
372         return Math.sqrt(dx * dx + dy * dy);
373     }
374 
375     /**
376      * Return the squared distance between <code>(x1, y1)</code> and <code>(x2, y2)</code>.
377      *
378      * @param x1
379      *          the x component of the first vector
380      * @param y1
381      *          the y component of the first vector
382      * @param x2
383      *          the x component of the second vector
384      * @param y2
385      *          the y component of the second vector
386      * @return the euclidean distance squared
387      */
388     public static long distanceSquared(int x1, int y1, int x2, int y2) {
389         int dx = x1 - x2;
390         int dy = y1 - y2;
391         return dx * dx + dy * dy;
392     }
393     
394     /**
395      * Add <code>v</code> to this vector.
396      *
397      * @param v
398      *          the vector to add
399      * @return this
400      */
401     ref public Vector2i add(Vector2i v) return {
402         this.x = x + v.x;
403         this.y = y + v.y;
404         return this;
405     }
406 
407     public Vector2i add(Vector2i v, ref Vector2i dest) {
408         dest.x = x + v.x;
409         dest.y = y + v.y;
410         return dest;
411     }
412 
413     /**
414      * Increment the components of this vector by the given values.
415      *
416      * @param x
417      *          the x component to add
418      * @param y
419      *          the y component to add
420      * @return this
421      */
422     ref public Vector2i add(int x, int y) return {
423         this.x = this.x + x;
424         this.y = this.y + y;
425         return this;
426     }
427 
428     public Vector2i add(int x, int y, ref Vector2i dest) {
429         dest.x = this.x + x;
430         dest.y = this.y + y;
431         return dest;
432     }
433 
434     /**
435      * Multiply all components of this {@link Vector2i} by the given scalar
436      * value.
437      * 
438      * @param scalar
439      *          the scalar to multiply this vector by
440      * @return this
441      */
442     ref public Vector2i mul(int scalar) return {
443         this.x = x * scalar;
444         this.y = y * scalar;
445         return this;
446     }
447 
448     public Vector2i mul(int scalar, ref Vector2i dest) {
449         dest.x = x * scalar;
450         dest.y = y * scalar;
451         return dest;
452     }
453 
454     /**
455      * Add the supplied vector by this one.
456      *
457      * @param v
458      *          the vector to multiply
459      * @return this
460      */
461     ref public Vector2i mul(Vector2i v) return {
462         this.x = x * v.x;
463         this.y = y * v.y;
464         return this;
465     }
466 
467     public Vector2i mul(Vector2i v, ref Vector2i dest) {
468         dest.x = x * v.x;
469         dest.y = y * v.y;
470         return dest;
471     }
472 
473     /**
474      * Multiply the components of this vector by the given values.
475      *
476      * @param x
477      *          the x component to multiply
478      * @param y
479      *          the y component to multiply
480      * @return this
481      */
482     ref public Vector2i mul(int x, int y) return {
483         this.x = this.x * x;
484         this.y = this.y * y;
485         return this;
486     }
487 
488     public Vector2i mul(int x, int y, ref Vector2i dest) {
489         dest.x = this.x * x;
490         dest.y = this.y * y;
491         return dest;
492     }
493 
494     /**
495      * Divide all components of this {@link Vector2i} by the given scalar value.
496      *
497      * @param scalar
498      *          the scalar to divide by
499      * @return a vector holding the result
500      */
501     public Vector2i div(float scalar) {
502         float invscalar = 1.0f / scalar;
503         this.x = cast(int) (x * invscalar);
504         this.y = cast(int) (y * invscalar);
505         return this;
506     }
507 
508     public Vector2i div(float scalar, ref Vector2i dest) {
509         float invscalar = 1.0f / scalar;
510         dest.x = cast(int) (x * invscalar);
511         dest.y = cast(int) (y * invscalar);
512         return dest;
513     }
514 
515     /**
516      * Divide all components of this {@link Vector2i} by the given scalar value.
517      *
518      * @param scalar
519      *          the scalar to divide by
520      * @return a vector holding the result
521      */
522     public Vector2i div(int scalar) {
523         this.x = x / scalar;
524         this.y = y / scalar;
525         return this;
526     }
527 
528     public Vector2i div(int scalar, ref Vector2i dest) {
529         dest.x = x / scalar;
530         dest.y = y / scalar;
531         return dest;
532     }
533     
534     /**
535      * Set all components to zero.
536      *
537      * @return this
538      */
539     ref public Vector2i zero() return {
540         this.x = 0;
541         this.y = 0;
542         return this;
543     }
544 
545 
546     /**
547      * Negate this vector.
548      *
549      * @return this
550      */
551     ref public Vector2i negate() return {
552         this.x = -x;
553         this.y = -y;
554         return this;
555     }
556 
557     public Vector2i negate(ref Vector2i dest) {
558         dest.x = -x;
559         dest.y = -y;
560         return dest;
561     }
562 
563     /**
564      * Set the components of this vector to be the component-wise minimum of this and the other vector.
565      *
566      * @param v
567      *          the other vector
568      * @return this
569      */
570     ref public Vector2i min(Vector2i v) return {
571         this.x = x < v.x ? x : v.x;
572         this.y = y < v.y ? y : v.y;
573         return this;
574     }
575 
576     public Vector2i min(Vector2i v, ref Vector2i dest) {
577         dest.x = x < v.x ? x : v.x;
578         dest.y = y < v.y ? y : v.y;
579         return dest;
580     }
581 
582     /**
583      * Set the components of this vector to be the component-wise maximum of this and the other vector.
584      *
585      * @param v
586      *          the other vector
587      * @return this
588      */
589     ref public Vector2i max(Vector2i v) return {
590         this.x = x > v.x ? x : v.x;
591         this.y = y > v.y ? y : v.y;
592         return this;
593     }
594 
595     public Vector2i max(Vector2i v, ref Vector2i dest) {
596         dest.x = x > v.x ? x : v.x;
597         dest.y = y > v.y ? y : v.y;
598         return dest;
599     }
600 
601     public int maxComponent() {
602         int absX = Math.abs(x);
603         int absY = Math.abs(y);
604         if (absX >= absY)
605             return 0;
606         return 1;
607     }
608 
609     public int minComponent() {
610         int absX = Math.abs(x);
611         int absY = Math.abs(y);
612         if (absX < absY)
613             return 0;
614         return 1;
615     }
616 
617     /**
618      * Set <code>this</code> vector's components to their respective absolute values.
619      * 
620      * @return this
621      */
622     ref public Vector2i absolute() return {
623         this.x = Math.abs(this.x);
624         this.y = Math.abs(this.y);
625         return this;
626     }
627 
628     public Vector2i absolute(ref Vector2i dest) {
629         dest.x = Math.abs(this.x);
630         dest.y = Math.abs(this.y);
631         return dest;
632     }
633 
634     public int hashCode() {
635         immutable int prime = 31;
636         int result = 1;
637         result = prime * result + x;
638         result = prime * result + y;
639         return result;
640     }
641 
642 
643     public bool equals(int x, int y) {
644         if (this.x != x)
645             return false;
646         if (this.y != y)
647             return false;
648         return true;
649     }
650 
651     public bool equals(Vector2i other) {
652         if (this.x != other.x)
653             return false;
654         if (this.y != other.y)
655             return false;
656         return true;
657     }
658 
659 }