@@ -4,28 +4,85 @@ export class DataPacket {
4
4
/**
5
5
* Interpolate between two data packets
6
6
* @param alpha Value 0-1, determines how close to this packet(0)
7
- * or the other packet(1) the output should be
8
- * @param other The packet to interpolate between
7
+ * or the after packet(1) the output should be
8
+ * @param before The packet before "this" packet, used to get the derivative for smoothing. Can be undefined.
9
+ * @param after The packet to interpolate to. Can be undefined.
10
+ * @param twoAfter The packet after "after", used to get the derivative for smoothing. Can be undefined.
9
11
*/
10
- interpolate ( alpha : number , other : DataPacket ) : DataPacket {
11
- if ( other === undefined ) {
12
+ interpolate ( alpha : number , before : DataPacket , after : DataPacket , twoAfter : DataPacket ) : DataPacket {
13
+ if ( after === undefined ) {
12
14
return this ;
13
15
}
14
- let old_ra = this . ra ;
15
- let new_ra = other . ra ;
16
- if ( Math . abs ( this . ra - other . ra ) > Math . PI ) {
17
- if ( this . ra < other . ra ) {
18
- old_ra += 2 * Math . PI ;
16
+
17
+ let before_ra = undefined ;
18
+ let cur_ra = this . ra ;
19
+ let after_ra = after . ra ;
20
+ let two_after_ra = undefined ;
21
+
22
+ after_ra = this . loopAngleToBeCloseTo ( after_ra , cur_ra ) ;
23
+
24
+ if ( before )
25
+ before_ra = this . loopAngleToBeCloseTo ( before . ra , cur_ra ) ;
26
+ if ( twoAfter )
27
+ two_after_ra = this . loopAngleToBeCloseTo ( twoAfter . ra , after_ra ) ;
28
+
29
+ let before_dist = undefined ;
30
+ let two_after_dist = undefined ;
31
+ if ( before )
32
+ before_dist = before . distance ;
33
+ if ( twoAfter )
34
+ two_after_dist = twoAfter . distance ;
35
+
36
+ return new DataPacket (
37
+ this . interpolateValue ( alpha , before_ra , cur_ra , after_ra , two_after_ra ) ,
38
+ this . interpolateValue ( alpha , before_dist , this . distance , after . distance , two_after_dist )
39
+ ) ;
40
+ }
41
+
42
+ private loopAngleToBeCloseTo ( to_be_looped : number , to_be_close_to : number ) : number {
43
+ if ( Math . abs ( to_be_close_to - to_be_looped ) > Math . PI ) {
44
+ if ( to_be_close_to < to_be_looped ) {
45
+ to_be_looped -= 2 * Math . PI ;
19
46
}
20
47
else {
21
- new_ra += 2 * Math . PI ;
48
+ to_be_looped += 2 * Math . PI ;
22
49
}
23
50
}
51
+ return to_be_looped ;
52
+ }
24
53
25
- return new DataPacket (
26
- ( alpha * new_ra + ( 1 - alpha ) * old_ra ) ,
27
- ( alpha * other . distance + ( 1 - alpha ) * this . distance )
28
- ) ;
54
+ /**
55
+ * Interpolates beteween "curVal" and "afterVal", using beforeVal and twoAfterVal to get the derivatives in order to smooth.
56
+ * @param alpha Value 0-1, determines how close to this packet(0)
57
+ * or the after packet(1) the output should be
58
+ * @param beforeVal The value before curVal, used to get the derivative for smoothing. Can be undefined.
59
+ * @param curVal The value to start interpolating from
60
+ * @param afterVal The value to interpolate to.
61
+ * @param twoAfterVal The value after afterVal, used to get the derivative for smoothing. Can be undefined.
62
+ */
63
+ private interpolateValue ( alpha : number , beforeVal : number , curVal : number , afterVal : number , twoAfterVal : number ) : number {
64
+ // linear => (alpha * afterVal + (1 - alpha) * curVal)
65
+
66
+ let y1 = curVal ;
67
+ let y2 = afterVal ;
68
+
69
+ let middleDeriv = afterVal - curVal ;
70
+
71
+ let m1 = middleDeriv ;
72
+ let m2 = middleDeriv ;
73
+
74
+ if ( beforeVal )
75
+ m1 = ( ( curVal - beforeVal ) + middleDeriv ) / 2 ;
76
+
77
+ if ( twoAfterVal )
78
+ m2 = ( ( twoAfterVal - afterVal ) + middleDeriv ) / 2 ;
79
+
80
+ let a = m2 + m1 - 2 * y2 + 2 * y1 ;
81
+ let b = - m2 - 2 * m1 + 3 * y2 - 3 * y1 ;
82
+ let c = m1 ;
83
+ let d = y1 ;
84
+
85
+ return a * Math . pow ( alpha , 3 ) + b * Math . pow ( alpha , 2 ) + c * alpha + d ;
29
86
}
30
87
}
31
88
0 commit comments