diff --git a/prototype-2/index.html b/prototype-2/index.html
new file mode 100644
index 0000000..d3f499e
--- /dev/null
+++ b/prototype-2/index.html
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
+
+
+ Prototype Schutz und Rettung: Daten retten Leben
+
+
+
diff --git a/prototype-2/lib.js b/prototype-2/lib.js
new file mode 100644
index 0000000..bfed60e
--- /dev/null
+++ b/prototype-2/lib.js
@@ -0,0 +1,28 @@
+/**
+ *
+ * @param {[number, number]} origin
+ * @param {[number, number]} windVector
+ * @param {number} time
+ */
+export function createWindPolygon(origin, windVector, time) {
+ const vOrigin = new Vector(...origin);
+ const vWind = new Vector(...windVector).sub(vOrigin);
+ console.log(vOrigin, vWind);
+ const rotWind = vWind.rotateDegrees(90);
+ // WindShift
+ const windShift = rotWind.clone().rotateDegrees(180).mulScalarSelf(0.5);
+ // FIRST BASEPOINT
+ const basePoint1 = vOrigin.clone().addSelf(windShift);
+ // SECOND BASEPOINT
+ const basePoint2 = vOrigin.clone().addSelf(windShift).addSelf(rotWind);
+ const targetPoint1 = basePoint1.add(vWind.mulScalar(time));
+ const targetPoint2 = basePoint2.add(vWind.mulScalar(time));
+ const polygon = [
+ basePoint2.toArray(),
+ basePoint1.toArray(),
+ targetPoint1.toArray(),
+ targetPoint2.toArray(),
+ ];
+ console.log(polygon);
+ return polygon;
+}
diff --git a/prototype-2/lib/vector2js.js b/prototype-2/lib/vector2js.js
new file mode 100644
index 0000000..46f2dfa
--- /dev/null
+++ b/prototype-2/lib/vector2js.js
@@ -0,0 +1,754 @@
+/*
+* A simple 2d Vector class for node.js / javascript.
+*
+* Author: Ronen Ness, 2016.
+* License: MIT.
+*/
+
+
+(function(name, definition) {
+ if (typeof module != 'undefined') module.exports = definition();
+ else if (typeof define == 'function' && typeof define.amd == 'object') define(definition);
+ else this[name] = definition();
+}('Vector', function() {
+
+ "use strict";
+
+ // create the vector main object
+ var Vector = (function () {
+
+ "use strict";
+
+ // pi * 2
+ var PI2 = Math.PI * 2;
+
+ // convert radians to degrees
+ var radToDeg = (180 / Math.PI);
+
+ // convert degrees to radians
+ var degToRad = (Math.PI / 180);
+
+ // round numbers from 10'th digit
+ // this is useful for calculations that should return round or almost round numbers, but have a long tail of 0's and 1 due to floating points stuff
+ function smartRound(num)
+ {
+ return Math.round(num * 100000000.0) / 100000000.0;
+ }
+
+ // return distance between vectors
+ function vectorsDistance(p1, p2) {
+ var dx = p2.x - p1.x,
+ dy = p2.y - p1.y;
+ return Math.sqrt(dx * dx + dy * dy);
+ };
+
+ // return angle (in radians) between two vectors
+ function vectorsAngle(P1, P2, wrap) {
+ var deltaY = P2.y - P1.y,
+ deltaX = P2.x - P1.x;
+ var ret = Math.atan2(deltaY, deltaX);
+ if (wrap) {while (ret < 0) ret += PI2;}
+ return ret;
+ };
+
+ // create the vector
+ function Vector(x, y)
+ {
+ this.x = x !== undefined ? x : 0;
+ this.y = y !== undefined ? y : 0;
+ }
+
+ // create a vector with length 1 from a given radian.
+ // @param radian - angle in radians.
+ // @return new vector instance.
+ Vector.fromRadians = function (radian)
+ {
+ var x = Math.cos(radian);
+ var y = Math.sin(radian);
+ return new Vector(x, y);
+ };
+
+ // create a vector with length 1 from a given degree.
+ // @param degree - angle in degrees.
+ // @return new vector instance.
+ Vector.fromDegrees = function (degree)
+ {
+ var rad = degree * (Math.PI / 180.0);
+ return Vector.fromRadians(rad);
+ };
+
+ // create a vector from string ("x,y").
+ // @param str - string to create vector from.
+ // @return new vector instance.
+ Vector.fromString = function (str)
+ {
+ var parts = str.split(",");
+ return new Vector(parseFloat(parts[0]), parseFloat(parts[1]));
+ };
+
+ // create a vector from array ( [x, y] ).
+ // @param arr - array to create vector from.
+ // @return new vector instance.
+ Vector.fromArray = function (arr)
+ {
+ return new Vector(arr[0], arr[1]);
+ };
+
+ // vector prototype
+ Vector.prototype = {
+
+ // version
+ version: "2.0.1",
+
+ // [API]
+ // [chainable, clone]
+ // clone the vector and return the cloned instance.
+ // @return cloned vector.
+ clone: function()
+ {
+ return new Vector(this.x, this.y);
+ },
+
+ // [API]
+ // []
+ // Get if equal to another vector
+ // @param vector - other vector to compare with.
+ // @return if vectors are equal.
+ equals: function(vector)
+ {
+ return (this.prototype === vector.prototype) && (this.x === vector.x) && (this.y === vector.y);
+ },
+
+ // [API]
+ // [chainable, changeSelf]
+ // set values from another vector. this changes value of self.
+ // @param vector - other vector to get values from.
+ // @return self.
+ copy: function(vector)
+ {
+ this.x = vector.x;
+ this.y = vector.y;
+ return this;
+ },
+
+ // [API]
+ // [chainable, changeSelf]
+ // set only the x component from another vector.
+ // @return self.
+ copyX: function(vector)
+ {
+ this.x = vector.x;
+ return this;
+ },
+
+ // [API]
+ // [chainable, changeSelf]
+ // set only the y component from another vector.
+ // @return self.
+ copyY: function(vector)
+ {
+ this.y = vector.y;
+ return this;
+ },
+
+ // [API]
+ // []
+ // convert to a dictionary with {x, y}.
+ // @return a dictionary representation of the vector.
+ toDict: function()
+ {
+ return {x: this.x, y: this.y};
+ },
+
+ // [API]
+ // []
+ // convert to array with [x, y].
+ // @return an array representation of the vector.
+ toArray: function()
+ {
+ return [this.x, this.y];
+ },
+
+ // [API]
+ // [chainable, changeSelf]
+ // set values from x, y.
+ // @param x - optional x component to set.
+ // @param y - optional y component to set.
+ // @return self.
+ set: function(x, y)
+ {
+ if (x !== undefined) this.x = x;
+ if (y !== undefined) this.y = y;
+ return this;
+ },
+
+ // [API]
+ // [chainable, clone]
+ // clone and flip between x and y values.
+ // @return cloned vector with flipped x and y components.
+ flipXY: function()
+ {
+ return new Vector(this.y, this.x);
+ },
+
+ // [API]
+ // [chainable, changeSelf]
+ // flip between x and y values.
+ // @return self.
+ flipXYSelf: function()
+ {
+ this.y = [this.x, this.x = this.y][0];
+ return this;
+ },
+
+ // [API]
+ // [chainable, clone]
+ // clone and invert x and y values (like multiply with -1, eg x, y => -x, -y)
+ // @return cloned vector with inverted values.
+ invert: function()
+ {
+ return this.mulScalar(-1);
+ },
+
+ // [API]
+ // [chainable, changeSelf]
+ // invert x and y values (like multiply with -1, eg x, y => -x, -y)
+ // @return self.
+ invertSelf: function()
+ {
+ this.mulScalarSelf(-1);
+ return this;
+ },
+
+ // [API]
+ // []
+ // get the distance from another vector.
+ // @param other - vector to get distance from.
+ // @return distance between vectors.
+ distanceFrom: function (other)
+ {
+ return vectorsDistance(this, other);
+ },
+
+ // [API]
+ // []
+ // get angle from another vector in radians.
+ // @return angle in radians from this to other.
+ radiansTo: function (other)
+ {
+ return vectorsAngle(this, other, true);
+ },
+
+ // [API]
+ // []
+ // get degrees from another vector in degrees.
+ // @return angle in degrees from this to other.
+ degreesTo: function (other)
+ {
+ return vectorsAngle(this, other, true) * radToDeg;
+ },
+
+ // [API]
+ // []
+ // convert this vector to a radian angle.
+ // this is equivalent to doing Vector.zero.radiansTo(this).
+ // @return angle in radians.
+ toRadians: function (other)
+ {
+ return vectorsAngle(Vector.zero, this, true);
+ },
+
+ // [API]
+ // []
+ // convert this vector to degree.
+ // this is equivalent to doing Vector.zero.degreeTo(this).
+ // @return angle in degrees (0-360).
+ toDegrees: function (other)
+ {
+ return this.toRadians() * radToDeg;
+ },
+
+ // [API]
+ // [chainable, changeSelf]
+ // rotate this vector by a given degree.
+ // @param degrees - degrees to rotate this vector by (can be positive or negative).
+ // @return self.
+ rotateDegreesSelf: function(degrees)
+ {
+ return this.rotateRadiansSelf(degrees * degToRad);
+ },
+
+ // [API]
+ // [chainable]
+ // clone and rotate the vector by a given degree.
+ // @param degrees - degree to rotate this vector by (can be positive or negative).
+ // @return cloned rotated vector.
+ rotateDegrees: function(degrees)
+ {
+ return this.clone().rotateDegreesSelf(degrees);
+ },
+
+ // [API]
+ // [chainable, changeSelf]
+ // rotate this vector by a given radian.
+ // @param radians - radians to rotate this vector by (can be positive or negative).
+ // @return self.
+ rotateRadiansSelf: function(radians)
+ {
+ var ca = Math.cos(radians);
+ var sa = Math.sin(radians);
+ var x = (this.x * ca) - (this.y * sa);
+ var y = (this.x * sa) + (this.y * ca);
+ this.x = smartRound(x);
+ this.y = smartRound(y);
+ return this;
+ },
+
+ // [API]
+ // [chainable]
+ // clone and rotate the vector by a given degree.
+ // @param radians - radians to rotate this vector by (can be positive or negative).
+ // @return cloned rotated vector.
+ rotateRadians: function(radians)
+ {
+ return this.clone().rotateRadiansSelf(radians);
+ },
+
+ // [API]
+ // []
+ // calculate the length of this vector (aka magnitude).
+ // @return vector length.
+ length: function()
+ {
+ return Math.sqrt(this.x*this.x + this.y*this.y);
+ },
+
+ // [API]
+ // [chainable, changeSelf]
+ // normalize this vector, eg make length equal 1.
+ // @return self.
+ normalizeSelf: function()
+ {
+ var by = Math.sqrt(this.x * this.x + this.y * this.y);
+ if (by === 0) return this;
+ this.x /= by;
+ this.y /= by;
+ return this;
+ },
+
+ // [API]
+ // [chainable, clone]
+ // clone and normalize the vector.
+ // @return normalized vector.
+ normalize: function()
+ {
+ return this.clone().normalizeSelf();
+ },
+
+ // [API]
+ // [chainable, changeSelf]
+ // add other vector to self.
+ // for example, v(10, 11) + v(5, 6) = v(15, 17).
+ // @param other - vector to add components to self.
+ // @return self.
+ addSelf: function (other)
+ {
+ // if we got a number instead of vector, use the scalar function
+ if (typeof other === "number") {
+ return this.addScalarSelf(other);
+ }
+
+ // update and return
+ this.x += other.x;
+ this.y += other.y;
+ return this;
+ },
+
+ // [API]
+ // [chainable, changeSelf]
+ // subtract other vector from self.
+ // for example, v(10, 10) - v(2, 3) = v(8, 7).
+ // @param other - vector to subtract components from self.
+ // @return self.
+ subSelf: function (other)
+ {
+ // if we got a number instead of vector, use the scalar function
+ if (typeof other === "number") {
+ return this.subScalarSelf(other);
+ }
+
+ // update and return
+ this.x -= other.x;
+ this.y -= other.y;
+ return this;
+ },
+
+ // [API]
+ // [chainable, changeSelf]
+ // divide self by other vector.
+ // for example, v(10, 20) / v(2, 5) = v(5, 4).
+ // @param other - vector to divide components from self.
+ // @return self.
+ divSelf: function (other)
+ {
+ // if we got a number instead of vector, use the scalar function
+ if (typeof other === "number") {
+ return this.divScalarSelf(other);
+ }
+
+ // update and return
+ this.x /= other.x;
+ this.y /= other.y;
+ return this;
+ },
+
+ // [API]
+ // [chainable, changeSelf]
+ // multiply self vector by other vector.
+ // for example, v(2, 3) * v(3, 4) = v(6, 12).
+ // @param other - vector to multiply components with self.
+ // @return self.
+ mulSelf: function (other)
+ {
+ // if we got a number instead of vector, use the scalar function
+ if (typeof other === "number") {
+ return this.mulScalarSelf(other);
+ }
+
+ // update and return
+ this.x *= other.x;
+ this.y *= other.y;
+ return this;
+ },
+
+ // [API]
+ // [chainable, changeSelf]
+ // add scalar value to self.
+ // for example, v(2, 3) + 5 = v(7, 8).
+ // @param val - value to add to components.
+ // @return self.
+ addScalarSelf: function (val)
+ {
+ this.x += val;
+ this.y += val;
+ return this;
+ },
+
+ // [API]
+ // [chainable, changeSelf]
+ // subtract scalar from self.
+ // for example, v(7, 9) - 5 = v(3, 4).
+ // @param val - value to subtract from components.
+ // @return self.
+ subScalarSelf: function (val)
+ {
+ this.x -= val;
+ this.y -= val;
+ return this;
+ },
+
+ // [API]
+ // [chainable, changeSelf]
+ // divide self by scalar.
+ // for example, v(6, 8) / 5 = v(3, 4).
+ // @param val - value to divide components by.
+ // @return self.
+ divScalarSelf: function (val)
+ {
+ this.x /= val;
+ this.y /= val;
+ return this;
+ },
+
+ // [API]
+ // [chainable, changeSelf]
+ // multiply self by scalar.
+ // for example, v(2, 3) * 2 = v(4, 6).
+ // @param val - value to multiply components with.
+ // @return self.
+ mulScalarSelf: function (val)
+ {
+ this.x *= val;
+ this.y *= val;
+ return this;
+ },
+
+ // [API]
+ // [chainable, clone]
+ // clone self and add other vector to it.
+ // @param other - vector to add with.
+ // @return cloned vector.
+ add: function (other)
+ {
+ return this.clone().addSelf(other);
+ },
+
+ // [API]
+ // [chainable, clone]
+ // clone self and subtract other vector from it.
+ // @param other - vector to subtract with.
+ // @return cloned vector.
+ sub: function (other)
+ {
+ return this.clone().subSelf(other);
+ },
+
+ // [API]
+ // [chainable, clone]
+ // clone self and multiply by other vector.
+ // @param other - vector to multiply with.
+ // @return cloned vector.
+ mul: function (other)
+ {
+ return this.clone().mulSelf(other);
+ },
+
+ // [API]
+ // [chainable, clone]
+ // clone self and divide by other vector.
+ // @param other - vector to divide with.
+ // @param scalar - value to divide by.
+ // @return cloned vector.
+ div: function (other)
+ {
+ return this.clone().divSelf(other);
+ },
+
+ // [API]
+ // [chainable, clone]
+ // clone self and add scalar to it.
+ // @param scalar - value to add.
+ // @return cloned vector.
+ addScalar: function (scalar)
+ {
+ return this.clone().addScalarSelf(scalar);
+ },
+
+ // [API]
+ // [chainable, clone]
+ // clone self and substract scalar from it.
+ // @param scalar - value to subtract.
+ // @return cloned vector.
+ subScalar: function (scalar)
+ {
+ return this.clone().subScalarSelf(scalar);
+ },
+
+ // [API]
+ // [chainable, clone]
+ // clone self and multiply by scalar.
+ // @param scalar - value to multiply with.
+ // @return cloned vector.
+ mulScalar: function (scalar)
+ {
+ return this.clone().mulScalarSelf(scalar);
+ },
+
+ // [API]
+ // [chainable, clone]
+ // clone self and divide by scalar.
+ // @param scalar - value to divide by.
+ // @return cloned vector.
+ divScalar: function (scalar)
+ {
+ return this.clone().divScalarSelf(scalar);
+ },
+
+ // [API]
+ // [chainable, changeSelf]
+ // clamp vector values into range.
+ // note: this function does not validate that min < max.
+ // @param min - min value for x, y components.
+ // @param max - max value for x, y components.
+ // @return self.
+ clampSelf: function (min, max)
+ {
+ if (this.x < min.x) this.x = min.x;
+ if (this.y < min.y) this.y = min.y;
+ if (this.x > max.x) this.x = max.x;
+ if (this.y > max.y) this.y = max.y;
+ return this;
+ },
+
+ // [API]
+ // [chainable, clone]
+ // clone vector and clamp its values.
+ // note: this function does not validate that min < max.
+ // @param min - min value for x, y components.
+ // @param max - max value for x, y components.
+ // @return cloned vector in range.
+ clamp: function (min, max)
+ {
+ return this.clone().clampSelf(min, max);
+ },
+
+ // [API]
+ // [chainable, changeSelf]
+ // apply a function on x and y components of the vector.
+ // for example, you can use Math.round to round the vector x, y values.
+ // @param func - function to apply on components.
+ // @return self.
+ applySelf: function (func)
+ {
+ this.x = func(this.x);
+ this.y = func(this.y);
+ return this;
+ },
+
+ // [API]
+ // [chainable, clone]
+ // clone self and apply a function on x and y components of the clone vector.
+ // for example, you can use Math.round to round the vector x, y values.
+ // @param func - function to apply on components.
+ // @return cloned vector.
+ apply: function (func)
+ {
+ return this.clone().applySelf(func);
+ },
+
+ // [API]
+ // [chainable, changeSelf]
+ // turn self to absolute values (eg turn x, y positive).
+ // @return self.
+ absSelf: function()
+ {
+ return this.applySelf(Math.abs);
+ },
+
+ // [API]
+ // [chainable, clone]
+ // clone and turn to absolute values (eg turn x, y positive).
+ // @return cloned vector.
+ abs: function()
+ {
+ return this.clone().absSelf();
+ },
+
+ // [API]
+ // [chainable, changeSelf]
+ // turn self to round values (eg turn x, y positive).
+ // @return self.
+ roundSelf: function()
+ {
+ return this.applySelf(Math.round);
+ },
+
+ // [API]
+ // [chainable, clone]
+ // clone and turn to round values (eg turn x, y positive).
+ // @return cloned vector.
+ round: function()
+ {
+ return this.clone().roundSelf();
+ },
+
+ // [API]
+ // []
+ // calculate dot-product of this vector with another vector.
+ // @param other - other vector to calculate dot-product with.
+ // @return dot product.
+ dot: function (other)
+ {
+ return (this.x * other.x) + (this.y * other.y);
+ },
+
+ // [API]
+ // []
+ // calculate cross-product of this vector with another vector.
+ // @param other - other vector to calculate cross-product with.
+ // @return dot product.
+ cross: function (other)
+ {
+ return (this.x * other.y) - (this.y * other.x);
+ },
+
+ // [API]
+ // [chainable, changeSelf]
+ // if any of the components of this vector are NaN, null, undefined, etc. set them to defaults.
+ // note: 0's are considered to be a valid number and will not be replaced with a default value.
+ // @param x - default value for x if undefined (0 if not defined).
+ // @param y - default value for y if undefined (0 if not defined).
+ // @return self.
+ repairSelf: function(x, y)
+ {
+ // checking if number but also trying a simple math equasion and check if NaN (because typeof NaN == number..)
+ if (typeof this.x !== "number" || isNaN(this.x + 1)) {this.x = x || 0;}
+ if (typeof this.y !== "number" || isNaN(this.y + 1)) {this.y = y || 0;}
+ return this;
+ },
+
+ // [API]
+ // [chainable, clone]
+ // create a clone and if any of the components of the vector are NaN, null, undefined, etc. set them to default.
+ // note: 0's are considered to be a valid number and will not be replaced with a default value.
+ // @param x - default value for x if undefined (0 if not defined).
+ // @param y - default value for y if undefined (0 if not defined).
+ // @return repaired clone.
+ repair: function(x, y)
+ {
+ return this.clone().repairSelf(x, y);
+ },
+
+ // [API]
+ // []
+ // convert to string in the form of "x,y".
+ // @return string representation of the vector.
+ toString: function ()
+ {
+ // default format
+ return this.x + "," + this.y;
+ },
+
+ // [API]
+ // []
+ // convert to a string with a given format.
+ // @param format - a string in which %x and %y will be replaced with the vector values.
+ // @return formatted string representing the vector.
+ format: function (format)
+ {
+ // default format
+ format = format || "%x,%y";
+ format = format.replace(new RegExp("%x", 'g'), this.x);
+ format = format.replace(new RegExp("%y", 'g'), this.y);
+ return format;
+ },
+ };
+
+ // return the vector class
+ return Vector;
+
+ })();
+
+ // some default consts
+ Vector.zero = new Vector(0, 0);
+ Vector.one = new Vector(1, 1);
+ Vector.up = new Vector(0, -1);
+ Vector.down = new Vector(0, 1);
+ Vector.left = new Vector(-1, 0);
+ Vector.right = new Vector(1, 0);
+ Vector.upLeft = new Vector(-1, -1);
+ Vector.downLeft = new Vector(-1, 1);
+ Vector.upRight = new Vector(1, -1);
+ Vector.downRight = new Vector(1, 1);
+
+ // alias for magnitude
+ Vector.prototype.magnitude = Vector.prototype.length;
+
+ // if freeze is supported make those consts freeze
+ if (Object.freeze)
+ {
+ Object.freeze(Vector.zero);
+ Object.freeze(Vector.one);
+ Object.freeze(Vector.up);
+ Object.freeze(Vector.down);
+ Object.freeze(Vector.left);
+ Object.freeze(Vector.right);
+ Object.freeze(Vector.upLeft);
+ Object.freeze(Vector.downLeft);
+ Object.freeze(Vector.upRight);
+ Object.freeze(Vector.downRight);
+ }
+
+ // return the vector class
+ return Vector;
+}));
\ No newline at end of file
diff --git a/prototype-2/lib/vector2js.min.js b/prototype-2/lib/vector2js.min.js
new file mode 100644
index 0000000..e1c5f00
--- /dev/null
+++ b/prototype-2/lib/vector2js.min.js
@@ -0,0 +1 @@
+!function(t,e){"undefined"!=typeof module?module.exports=e():"function"==typeof define&&"object"==typeof define.amd?define(e):this.Vector=e()}(0,function(){"use strict";var t=function(){function t(t){return Math.round(1e8*t)/1e8}function e(t,e){var n=e.x-t.x,i=e.y-t.y;return Math.sqrt(n*n+i*i)}function n(t,e,n){var i=e.y-t.y,s=e.x-t.x,u=Math.atan2(i,s);if(n)for(;u<0;)u+=r;return u}function i(t,e){this.x=void 0!==t?t:0,this.y=void 0!==e?e:0}var r=2*Math.PI,s=180/Math.PI,u=Math.PI/180;return i.fromRadians=function(t){return new i(Math.cos(t),Math.sin(t))},i.fromDegrees=function(t){var e=t*(Math.PI/180);return i.fromRadians(e)},i.fromString=function(t){var e=t.split(",");return new i(parseFloat(e[0]),parseFloat(e[1]))},i.fromArray=function(t){return new i(t[0],t[1])},i.prototype={version:"2.0.1",clone:function(){return new i(this.x,this.y)},equals:function(t){return this.prototype===t.prototype&&this.x===t.x&&this.y===t.y},copy:function(t){return this.x=t.x,this.y=t.y,this},copyX:function(t){return this.x=t.x,this},copyY:function(t){return this.y=t.y,this},toDict:function(){return{x:this.x,y:this.y}},toArray:function(){return[this.x,this.y]},set:function(t,e){return void 0!==t&&(this.x=t),void 0!==e&&(this.y=e),this},flipXY:function(){return new i(this.y,this.x)},flipXYSelf:function(){return this.y=[this.x,this.x=this.y][0],this},invert:function(){return this.mulScalar(-1)},invertSelf:function(){return this.mulScalarSelf(-1),this},distanceFrom:function(t){return e(this,t)},radiansTo:function(t){return n(this,t,!0)},degreesTo:function(t){return n(this,t,!0)*s},toRadians:function(t){return n(i.zero,this,!0)},toDegrees:function(t){return this.toRadians()*s},rotateDegreesSelf:function(t){return this.rotateRadiansSelf(t*u)},rotateDegrees:function(t){return this.clone().rotateDegreesSelf(t)},rotateRadiansSelf:function(e){var n=Math.cos(e),i=Math.sin(e),r=this.x*n-this.y*i,s=this.x*i+this.y*n;return this.x=t(r),this.y=t(s),this},rotateRadians:function(t){return this.clone().rotateRadiansSelf(t)},length:function(){return Math.sqrt(this.x*this.x+this.y*this.y)},normalizeSelf:function(){var t=Math.sqrt(this.x*this.x+this.y*this.y);return 0===t?this:(this.x/=t,this.y/=t,this)},normalize:function(){return this.clone().normalizeSelf()},addSelf:function(t){return"number"==typeof t?this.addScalarSelf(t):(this.x+=t.x,this.y+=t.y,this)},subSelf:function(t){return"number"==typeof t?this.subScalarSelf(t):(this.x-=t.x,this.y-=t.y,this)},divSelf:function(t){return"number"==typeof t?this.divScalarSelf(t):(this.x/=t.x,this.y/=t.y,this)},mulSelf:function(t){return"number"==typeof t?this.mulScalarSelf(t):(this.x*=t.x,this.y*=t.y,this)},addScalarSelf:function(t){return this.x+=t,this.y+=t,this},subScalarSelf:function(t){return this.x-=t,this.y-=t,this},divScalarSelf:function(t){return this.x/=t,this.y/=t,this},mulScalarSelf:function(t){return this.x*=t,this.y*=t,this},add:function(t){return this.clone().addSelf(t)},sub:function(t){return this.clone().subSelf(t)},mul:function(t){return this.clone().mulSelf(t)},div:function(t){return this.clone().divSelf(t)},addScalar:function(t){return this.clone().addScalarSelf(t)},subScalar:function(t){return this.clone().subScalarSelf(t)},mulScalar:function(t){return this.clone().mulScalarSelf(t)},divScalar:function(t){return this.clone().divScalarSelf(t)},clampSelf:function(t,e){return this.xe.x&&(this.x=e.x),this.y>e.y&&(this.y=e.y),this},clamp:function(t,e){return this.clone().clampSelf(t,e)},applySelf:function(t){return this.x=t(this.x),this.y=t(this.y),this},apply:function(t){return this.clone().applySelf(t)},absSelf:function(){return this.applySelf(Math.abs)},abs:function(){return this.clone().absSelf()},roundSelf:function(){return this.applySelf(Math.round)},round:function(){return this.clone().roundSelf()},dot:function(t){return this.x*t.x+this.y*t.y},cross:function(t){return this.x*t.y-this.y*t.x},repairSelf:function(t,e){return("number"!=typeof this.x||isNaN(this.x+1))&&(this.x=t||0),("number"!=typeof this.y||isNaN(this.y+1))&&(this.y=e||0),this},repair:function(t,e){return this.clone().repairSelf(t,e)},toString:function(){return this.x+","+this.y},format:function(t){return t=t||"%x,%y",t=t.replace(new RegExp("%x","g"),this.x),t=t.replace(new RegExp("%y","g"),this.y)}},i}();return t.zero=new t(0,0),t.one=new t(1,1),t.up=new t(0,-1),t.down=new t(0,1),t.left=new t(-1,0),t.right=new t(1,0),t.upLeft=new t(-1,-1),t.downLeft=new t(-1,1),t.upRight=new t(1,-1),t.downRight=new t(1,1),t.prototype.magnitude=t.prototype.length,Object.freeze&&(Object.freeze(t.zero),Object.freeze(t.one),Object.freeze(t.up),Object.freeze(t.down),Object.freeze(t.left),Object.freeze(t.right),Object.freeze(t.upLeft),Object.freeze(t.downLeft),Object.freeze(t.upRight),Object.freeze(t.downRight)),t});
\ No newline at end of file
diff --git a/prototype-2/main.js b/prototype-2/main.js
new file mode 100644
index 0000000..9af6477
--- /dev/null
+++ b/prototype-2/main.js
@@ -0,0 +1,132 @@
+import { createWindPolygon } from "./lib.js";
+var map = L.map("map").setView([46.94863, 7.45164], 16);
+const rathaus = [46.94866, 7.45144];
+const wind = [46.94806, 7.45004];
+L.tileLayer("https://tile.openstreetmap.org/{z}/{x}/{y}.png", {
+ maxZoom: 19,
+ attribution:
+ '© OpenStreetMap',
+}).addTo(map);
+L.marker(rathaus).addTo(map);
+L.polyline([rathaus, wind], { color: "red" }).addTo(map);
+L.marker(wind).addTo(map);
+L.polygon(createWindPolygon(rathaus, wind, 3), { color: "yellow" }).addTo(map);
+const windVector = substractVectors(rathaus, wind);
+const turnedWind = rotateVector(windVector, Math.PI);
+//L.marker(addVectors(wind, windVector)).addTo(map);
+L.polyline([wind, addVectors(wind, turnedWind)], { color: "blue" }).addTo(map);
+/** Wind Origin */
+const muenster = [46.94739, 7.45137];
+const vMuenster = new Vector(...muenster);
+// Wind Destination
+const bundesHaus = [46.94653, 7.44688];
+const vBund = new Vector(...bundesHaus);
+// Resulting Wind Vector
+const vWind = vBund.clone().subSelf(vMuenster);
+// Rotated Wind
+const rotWind = vWind.rotateDegrees(90);
+// WindShift
+const windShift = rotWind.clone().rotateDegrees(180).mulScalarSelf(0.5);
+// FIRST BASEPOINT
+const basePoint1 = vMuenster.clone().addSelf(windShift);
+// SECOND BASEPOINT
+const basePoint2 = vMuenster.clone().addSelf(windShift).addSelf(rotWind);
+// BASELINE
+const baseLine = [basePoint1.toArray(), basePoint2.toArray()];
+// FIRSTPOLYGON
+const polygon1 = [
+ basePoint2.toArray(),
+ basePoint1.toArray(),
+ basePoint1.add(vWind).toArray(),
+ basePoint2.add(vWind).toArray(),
+];
+// SecondPolygon
+const polygon2 = [
+ polygon1[2],
+ polygon1[3],
+ new Vector(...polygon1[3]).add(vWind).toArray(),
+ new Vector(...polygon1[2]).add(vWind).toArray(),
+];
+/**
+ *
+ * @param {[number, number]} origin
+ * @param {[number, number]} windVector
+ * @param {number} time
+ */
+// function createWindPolygon(origin, windVector, time) {
+// const vOrigin = new Vector(...origin);
+// const vWind = new Vector(...windVector).sub(vOrigin);
+// console.log(vOrigin, vWind);
+// const rotWind = vWind.rotateDegrees(90);
+// // WindShift
+// const windShift = rotWind.clone().rotateDegrees(180).mulScalarSelf(0.5);
+// // FIRST BASEPOINT
+// const basePoint1 = vOrigin.clone().addSelf(windShift);
+// // SECOND BASEPOINT
+// const basePoint2 = vOrigin.clone().addSelf(windShift).addSelf(rotWind);
+// const targetPoint1 = basePoint1.add(vWind.mulScalar(time));
+// const targetPoint2 = basePoint2.add(vWind.mulScalar(time));
+// const polygon = [
+// basePoint2.toArray(),
+// basePoint1.toArray(),
+// targetPoint1.toArray(),
+// targetPoint2.toArray(),
+// ];
+// console.log(polygon);
+// return polygon;
+// }
+console.log(vMuenster.toArray(), vBund.toArray(), vWind.toArray());
+L.polyline([vMuenster.toArray(), vBund.toArray()], { color: "green" }).addTo(
+ map
+);
+/**
+L.polyline(
+ [vMuenster.toArray(), vMuenster.clone().addSelf(rotWind).toArray()],
+ {
+ color: "red",
+ }
+).addTo(map);
+ */
+L.polyline(baseLine, {
+ color: "yellow",
+}).addTo(map);
+L.polygon(polygon1).addTo(map);
+L.polygon(polygon2, { color: "green" }).addTo(map);
+/**
+ * Returns the vector from origin to destination
+ * @param {[number, number]} origin
+ * @param {[number, number]} destination
+ * @returns {[number, number]}
+ */
+function substractVectors(origin, destination) {
+ const x = destination[0] - origin[0];
+ const y = destination[1] - origin[1];
+ return [x, y];
+}
+/**
+ *
+ * @param {[number, number]} v1
+ * @param {[number, number]} v2
+ * @returns {[number, number]}
+ */
+function addVectors(v1, v2) {
+ return [v1[0] + v2[0], v1[1] + v2[1]];
+}
+/**
+ * @param {[number, number]} v1
+ * @param {number} degrees
+ * @returns
+ */
+function rotateVector(v1, degrees) {
+ const angle = getAngle(v1);
+ return [Math.cos(degrees + angle) * v1[0], Math.sin(degrees + angle) * v1[1]];
+}
+/**
+ *
+ * @param {[number, number]} v
+ * @returns {number}
+ */
+function getAngle(v) {
+ return Math.atan2(v[0], v[1]);
+}
+function translateVector(v, factor) {}
diff --git a/prototype-2/styles.css b/prototype-2/styles.css
new file mode 100644
index 0000000..d0a17f0
--- /dev/null
+++ b/prototype-2/styles.css
@@ -0,0 +1,6 @@
+#container {
+ border: 1px solid black;
+}
+#map {
+ height: 1080px;
+}