Make JetStream 2
[WebKit-https.git] / PerformanceTests / JetStream2 / cdjs / motion.js
1 // Copyright (c) 2001-2010, Purdue University. All rights reserved.
2 // Copyright (C) 2015 Apple Inc. All rights reserved.
3 // 
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are met:
6 //  * Redistributions of source code must retain the above copyright
7 //    notice, this list of conditions and the following disclaimer.
8 //  * Redistributions in binary form must reproduce the above copyright
9 //    notice, this list of conditions and the following disclaimer in the
10 //    documentation and/or other materials provided with the distribution.
11 //  * Neither the name of the Purdue University nor the
12 //    names of its contributors may be used to endorse or promote products
13 //    derived from this software without specific prior written permission.
14 // 
15 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
16 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18 // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
19 // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20 // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21 // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22 // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25
26 function Motion(callsign, posOne, posTwo) {
27     this.callsign = callsign;
28     this.posOne = posOne;
29     this.posTwo = posTwo;
30 }
31
32 Motion.prototype.toString = function() {
33     return "Motion(" + this.callsign + " from " + this.posOne + " to " + this.posTwo + ")";
34 };
35
36 Motion.prototype.delta = function() {
37     return this.posTwo.minus(this.posOne);
38 };
39
40 Motion.prototype.findIntersection = function(other) {
41     var init1 = this.posOne;
42     var init2 = other.posOne;
43     var vec1 = this.delta();
44     var vec2 = other.delta();
45     var radius = Constants.PROXIMITY_RADIUS;
46     
47     // this test is not geometrical 3-d intersection test, it takes the fact that the aircraft move
48     // into account ; so it is more like a 4d test
49     // (it assumes that both of the aircraft have a constant speed over the tested interval)
50     
51     // we thus have two points, each of them moving on its line segment at constant speed ; we are looking
52     // for times when the distance between these two points is smaller than r 
53     
54     // vec1 is vector of aircraft 1
55     // vec2 is vector of aircraft 2
56     
57     // a = (V2 - V1)^T * (V2 - V1)
58     var a = vec2.minus(vec1).squaredMagnitude();
59     
60     if (a != 0) {
61         // we are first looking for instances of time when the planes are exactly r from each other
62         // at least one plane is moving ; if the planes are moving in parallel, they do not have constant speed
63
64         // if the planes are moving in parallel, then
65         //   if the faster starts behind the slower, we can have 2, 1, or 0 solutions
66         //   if the faster plane starts in front of the slower, we can have 0 or 1 solutions
67
68         // if the planes are not moving in parallel, then
69
70
71         // point P1 = I1 + vV1
72         // point P2 = I2 + vV2
73         //   - looking for v, such that dist(P1,P2) = || P1 - P2 || = r
74
75         // it follows that || P1 - P2 || = sqrt( < P1-P2, P1-P2 > )
76         //   0 = -r^2 + < P1 - P2, P1 - P2 >
77         //  from properties of dot product
78         //   0 = -r^2 + <I1-I2,I1-I2> + v * 2<I1-I2, V1-V2> + v^2 *<V1-V2,V1-V2>
79         //   so we calculate a, b, c - and solve the quadratic equation
80         //   0 = c + bv + av^2
81
82         // b = 2 * <I1-I2, V1-V2>
83
84         var b = 2 * init1.minus(init2).dot(vec1.minus(vec2));
85
86         // c = -r^2 + (I2 - I1)^T * (I2 - I1)
87         var c = -radius * radius + init2.minus(init1).squaredMagnitude();
88
89         var discr = b * b - 4 * a * c;
90         if (discr < 0)
91             return null;
92
93         var v1 = (-b - Math.sqrt(discr)) / (2 * a);
94         var v2 = (-b + Math.sqrt(discr)) / (2 * a);
95
96         if (v1 <= v2 && ((v1 <= 1 && 1 <= v2) ||
97                          (v1 <= 0 && 0 <= v2) ||
98                          (0 <= v1 && v2 <= 1))) {
99             // Pick a good "time" at which to report the collision.
100             var v;
101             if (v1 <= 0) {
102                 // The collision started before this frame. Report it at the start of the frame.
103                 v = 0;
104             } else {
105                 // The collision started during this frame. Report it at that moment.
106                 v = v1;
107             }
108             
109             var result1 = init1.plus(vec1.times(v));
110             var result2 = init2.plus(vec2.times(v));
111             
112             var result = result1.plus(result2).times(0.5);
113             if (result.x >= Constants.MIN_X &&
114                 result.x <= Constants.MAX_X &&
115                 result.y >= Constants.MIN_Y &&
116                 result.y <= Constants.MAX_Y &&
117                 result.z >= Constants.MIN_Z &&
118                 result.z <= Constants.MAX_Z)
119                 return result;
120         }
121
122         return null;
123     }
124     
125     // the planes have the same speeds and are moving in parallel (or they are not moving at all)
126     // they  thus have the same distance all the time ; we calculate it from the initial point
127     
128     // dist = || i2 - i1 || = sqrt(  ( i2 - i1 )^T * ( i2 - i1 ) )
129     
130     var dist = init2.minus(init1).magnitude();
131     if (dist <= radius)
132         return init1.plus(init2).times(0.5);
133     
134     return null;
135 };
136