reservation plugin - unbound request (unclean
[unfold.git] / portal / static / unbound_reservation_static / lib / jsplumb-geom-0.1.js
1 /**
2  * jsPlumbGeom v0.1
3  *
4  * Various geometry functions written as part of jsPlumb and perhaps useful for others.
5  *
6  * Copyright (c) 2013 Simon Porritt
7  *
8  * Permission is hereby granted, free of charge, to any person
9  * obtaining a copy of this software and associated documentation
10  * files (the "Software"), to deal in the Software without
11  * restriction, including without limitation the rights to use,
12  * copy, modify, merge, publish, distribute, sublicense, and/or sell
13  * copies of the Software, and to permit persons to whom the
14  * Software is furnished to do so, subject to the following
15  * conditions:
16  *
17  * The above copyright notice and this permission notice shall be
18  * included in all copies or substantial portions of the Software.
19  *
20  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
22  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
24  * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
25  * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
27  * OTHER DEALINGS IN THE SOFTWARE.
28  */
29 ;(function() {
30
31         
32         "use strict";
33
34         // Establish the root object, `window` in the browser, or `global` on the server.
35         var root = this;
36         var jsPlumbGeom;
37         if (typeof exports !== 'undefined') {
38                 jsPlumbGeom = exports;
39         } else {
40                 jsPlumbGeom = root.jsPlumbGeom = {};
41         }
42
43         var _isa = function(a) { return Object.prototype.toString.call(a) === "[object Array]"; },
44                 _pointHelper = function(p1, p2, fn) {
45                     p1 = _isa(p1) ? p1 : [p1.x, p1.y];
46                     p2 = _isa(p2) ? p2 : [p2.x, p2.y];    
47                     return fn(p1, p2);
48                 },
49                 /**
50                 * @name jsPlumbGeom.gradient
51                 * @function
52                 * @desc Calculates the gradient of a line between the two points.
53                 * @param {Point} p1 First point, either as a 2 entry array or object with `left` and `top` properties.
54                 * @param {Point} p2 Second point, either as a 2 entry array or object with `left` and `top` properties.
55                 * @return {Float} The gradient of a line between the two points.
56                 */
57                 _gradient = jsPlumbGeom.gradient = function(p1, p2) {
58                     return _pointHelper(p1, p2, function(_p1, _p2) { 
59                         if (_p2[0] == _p1[0])
60                             return _p2[1] > _p1[1] ? Infinity : -Infinity;
61                         else if (_p2[1] == _p1[1]) 
62                             return _p2[0] > _p1[0] ? 0 : -0;
63                         else 
64                             return (_p2[1] - _p1[1]) / (_p2[0] - _p1[0]); 
65                     });         
66                 },
67                 /**
68                 * @name jsPlumbGeom.normal
69                 * @function
70                 * @desc Calculates the gradient of a normal to a line between the two points.
71                 * @param {Point} p1 First point, either as a 2 entry array or object with `left` and `top` properties.
72                 * @param {Point} p2 Second point, either as a 2 entry array or object with `left` and `top` properties.
73                 * @return {Float} The gradient of a normal to a line between the two points.
74                 */
75                 _normal = jsPlumbGeom.normal = function(p1, p2) {
76                     return -1 / _gradient(p1, p2);
77                 },
78                 /**
79                 * @name jsPlumbGeom.lineLength
80                 * @function
81                 * @desc Calculates the length of a line between the two points.
82                 * @param {Point} p1 First point, either as a 2 entry array or object with `left` and `top` properties.
83                 * @param {Point} p2 Second point, either as a 2 entry array or object with `left` and `top` properties.
84                 * @return {Float} The length of a line between the two points.
85                 */
86                 _lineLength = jsPlumbGeom.lineLength = function(p1, p2) {
87                     return _pointHelper(p1, p2, function(_p1, _p2) {
88                         return Math.sqrt(Math.pow(_p2[1] - _p1[1], 2) + Math.pow(_p2[0] - _p1[0], 2));                  
89                     });
90                 },
91                 /**
92                 * @name jsPlumbGeom.quadrant
93                 * @function
94                 * @desc Calculates the quadrant in which the angle between the two points lies. 
95                 * @param {Point} p1 First point, either as a 2 entry array or object with `left` and `top` properties.
96                 * @param {Point} p2 Second point, either as a 2 entry array or object with `left` and `top` properties.
97                 * @return {Integer} The quadrant - 1 for upper right, 2 for lower right, 3 for lower left, 4 for upper left.
98                 */
99                 _quadrant = jsPlumbGeom.quadrant = function(p1, p2) {
100                     return _pointHelper(p1, p2, function(_p1, _p2) {
101                         if (_p2[0] > _p1[0]) {
102                             return (_p2[1] > _p1[1]) ? 2 : 1;
103                         }
104                         else if (_p2[0] == _p1[0]) {
105                             return _p2[1] > _p1[1] ? 2 : 1;    
106                         }
107                         else {
108                             return (_p2[1] > _p1[1]) ? 3 : 4;
109                         }
110                     });
111                 },
112                 /**
113                 * @name jsPlumbGeom.theta
114                 * @function
115                 * @desc Calculates the angle between the two points. 
116                 * @param {Point} p1 First point, either as a 2 entry array or object with `left` and `top` properties.
117                 * @param {Point} p2 Second point, either as a 2 entry array or object with `left` and `top` properties.
118                 * @return {Float} The angle between the two points.
119                 */
120                 _theta = jsPlumbGeom.theta = function(p1, p2) {
121                     return _pointHelper(p1, p2, function(_p1, _p2) {
122                         var m = _gradient(_p1, _p2),
123                             t = Math.atan(m),
124                             s = _quadrant(_p1, _p2);
125                         if ((s == 4 || s== 3)) t += Math.PI;
126                         if (t < 0) t += (2 * Math.PI);
127                     
128                         return t;
129                     });
130                 },
131                 /**
132                 * @name jsPlumbGeom.intersects
133                 * @function
134                 * @desc Calculates whether or not the two rectangles intersect.
135                 * @param {Rectangle} r1 First rectangle, as a js object in the form `{x:.., y:.., w:.., h:..}`
136                 * @param {Rectangle} r2 Second rectangle, as a js object in the form `{x:.., y:.., w:.., h:..}`
137                 * @return {Boolean} True if the rectangles intersect, false otherwise.
138                 */
139                 _intersects = jsPlumbGeom.intersects = function(r1, r2) {
140                     var x1 = r1.x, x2 = r1.x + r1.w, y1 = r1.y, y2 = r1.y + r1.h,
141                         a1 = r2.x, a2 = r2.x + r2.w, b1 = r2.y, b2 = r2.y + r2.h;
142                 
143                         return  ( (x1 <= a1 && a1 <= x2) && (y1 <= b1 && b1 <= y2) ) ||
144                                 ( (x1 <= a2 && a2 <= x2) && (y1 <= b1 && b1 <= y2) ) ||
145                                 ( (x1 <= a1 && a1 <= x2) && (y1 <= b2 && b2 <= y2) ) ||
146                                 ( (x1 <= a2 && a1 <= x2) && (y1 <= b2 && b2 <= y2) ) || 
147                                 ( (a1 <= x1 && x1 <= a2) && (b1 <= y1 && y1 <= b2) ) ||
148                                 ( (a1 <= x2 && x2 <= a2) && (b1 <= y1 && y1 <= b2) ) ||
149                                 ( (a1 <= x1 && x1 <= a2) && (b1 <= y2 && y2 <= b2) ) ||
150                                 ( (a1 <= x2 && x1 <= a2) && (b1 <= y2 && y2 <= b2) );
151                 },
152                 _segmentMultipliers = [null, [1, -1], [1, 1], [-1, 1], [-1, -1] ],
153                 _inverseSegmentMultipliers = [null, [-1, -1], [-1, 1], [1, 1], [1, -1] ],
154                 /**
155                 * @name jsPlumbGeom.pointOnLine
156                 * @function
157                 * @desc Calculates a point on the line from `fromPoint` to `toPoint` that is `distance` units along the length of the line.
158                 * @param {Point} p1 First point, either as a 2 entry array or object with `left` and `top` properties.
159                 * @param {Point} p2 Second point, either as a 2 entry array or object with `left` and `top` properties.
160                 * @return {Point} Point on the line, in the form `{ x:..., y:... }`.
161                 */
162                 _pointOnLine = jsPlumbGeom.pointOnLine = function(fromPoint, toPoint, distance) {
163                     var m = _gradient(fromPoint, toPoint),
164                         s = _quadrant(fromPoint, toPoint),
165                         segmentMultiplier = distance > 0 ? _segmentMultipliers[s] : _inverseSegmentMultipliers[s],
166                         theta = Math.atan(m),
167                         y = Math.abs(distance * Math.sin(theta)) * segmentMultiplier[1],
168                         x =  Math.abs(distance * Math.cos(theta)) * segmentMultiplier[0];
169                     return { x:fromPoint.x + x, y:fromPoint.y + y };
170                 },
171                 /**
172                 * @name jsPlumbGeom.perpendicularLineTo
173                 * @function
174                 * @desc Calculates a line of length `length` that is perpendicular to the line from `fromPoint` to `toPoint` and passes through `toPoint`.
175                 * @param {Point} p1 First point, either as a 2 entry array or object with `left` and `top` properties.
176                 * @param {Point} p2 Second point, either as a 2 entry array or object with `left` and `top` properties.
177                 * @return {Line} Perpendicular line, in the form `[ { x:..., y:... }, { x:..., y:... } ]`.
178                 */        
179                 _perpendicularLineTo = jsPlumbGeom.perpendicularLineTo = function(fromPoint, toPoint, length) {
180                     var m = _gradient(fromPoint, toPoint),
181                         theta2 = Math.atan(-1 / m),
182                         y =  length / 2 * Math.sin(theta2),
183                         x =  length / 2 * Math.cos(theta2);
184                     return [{x:toPoint.x + x, y:toPoint.y + y}, {x:toPoint.x - x, y:toPoint.y - y}];
185                 };      
186 }).call(this);