-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathParabolicMotion.cs
147 lines (119 loc) · 2.56 KB
/
ParabolicMotion.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ParabolicMotion
{
enum Mode
{
DistanceTime,
SpeedAngle
}
Mode mode;
float gravity;
float startY;
float startAngle;
float distance;
float time;
Vector2 startVelocity;
float Sec(float x)
{
return 1f / Mathf.Cos(x);
}
public ParabolicMotion(float distance, float time, float startY, float gravity = 9.81f)
{
mode = Mode.DistanceTime;
this.gravity = gravity;
this.startY = startY;
this.distance = distance;
this.time = time;
startVelocity = new Vector2(
distance / time,
(0.5f * gravity * Mathf.Pow(time, 2f) - startY) / time
);
}
public ParabolicMotion(Vector2 startVelocity, float startY, float gravity = 9.81f)
{
mode = Mode.SpeedAngle;
this.startVelocity = startVelocity;
this.gravity = gravity;
this.startY = startY;
Vector2 startDir = startVelocity.normalized;
startAngle = Mathf.Atan2(startDir.y, startDir.x);
}
float GetA()
{
switch (mode)
{
case Mode.DistanceTime:
return -0.5f * gravity;
case Mode.SpeedAngle:
return -(gravity / (2f * Mathf.Pow(startVelocity.magnitude, 2f) * Mathf.Pow(Mathf.Cos(startAngle), 2f)));
}
return 0;
}
float GetB()
{
switch (mode)
{
case Mode.DistanceTime:
return startVelocity.y;
case Mode.SpeedAngle:
return Mathf.Tan(startAngle);
}
return 0;
}
float GetC()
{
switch (mode)
{
case Mode.DistanceTime:
return startY;
case Mode.SpeedAngle:
return startY;
}
return 0;
}
float GetDelta()
{
return Mathf.Pow(GetB(), 2f) - 4f * GetA() * GetC();
}
public float Evaluate(float x)
{
switch(mode)
{
case Mode.DistanceTime:
float ti = x / startVelocity.x;
return GetA() * Mathf.Pow(ti, 2f) + GetB() * ti + GetC();
case Mode.SpeedAngle:
return GetA() * Mathf.Pow(x, 2f) + GetB() * x + GetC();
}
return 0;
}
public float GetDistance()
{
switch(mode)
{
case Mode.DistanceTime:
return distance;
case Mode.SpeedAngle:
float tmp = (2f * gravity * startY * Mathf.Pow(Sec(startAngle), 2f)) / Mathf.Pow(startVelocity.magnitude, 2f) + Mathf.Pow(Mathf.Tan(startAngle), 2f);
return -(Mathf.Pow(startVelocity.magnitude, 2f) * Mathf.Pow(Mathf.Cos(startAngle) ,2f) * ( -Mathf.Tan(startAngle) - Mathf.Sqrt(tmp) ))/ gravity;
}
return 0;
}
public float GetTime()
{
switch(mode)
{
case Mode.DistanceTime:
return time;
case Mode.SpeedAngle:
return GetDistance() / startVelocity.x;
}
return 0;
}
public float GetMaxHeight()
{
return -GetDelta() / (4f * GetA());
}
}