@@ -47,8 +47,10 @@ computing the normals:
47
47
on our 3D curve.
48
48
* Leverage the cross product to find our normals.
49
49
50
- The last one is the easiest, in my opinion. The first paragraph of [ the
51
- Wikipedia article for the cross
50
+ If we were to try central differences, we end up getting issues near the peak of a step curve.
51
+
52
+ The last one is not only the most accurate, but also the easiest, in my
53
+ opinion. The first paragraph of [ the Wikipedia article for the cross
52
54
product] ( https://en.wikipedia.org/wiki/Cross_product ) mentions using them to
53
55
calculate normal vectors.
54
56
@@ -144,8 +146,9 @@ var surface_pos = center.y
144
146
This works extremely well for how simple it is, but we can take it further.
145
147
Waves usually move things, right? How can we capture the force created by a
146
148
wave? The amplitude of the wave should affect the strength of the push we give.
147
- It sounds like we need to look at the slope... otherwise known as the gradient
148
- which we can find using the partial derivatives of the wave.
149
+ It sounds like we need to look at the slope. This means we need the derivative
150
+ of our wave's function.
151
+
149
152
The current wave is defined by:
150
153
151
154
{{<katex >}}$$ w\left(x,y\right)=H\cdot e^{\sin\left(\sqrt{x^{2}+y^{2}}\right)+\sin\left(y\right)} $$
@@ -216,6 +219,36 @@ wave changing slope at a given point over time, the object can eventually end
216
219
up changing direction. Instead of getting stuck at some local minimum after
217
220
encountering one wave, our object looks like it's swaying back and forth.
218
221
222
+ ### Central Differences
223
+
224
+ While this is very precise, doing the calculus to get that gradient takes an
225
+ extra step of manual work. Each time the structure of our ` _wave ` function
226
+ changes, that new function must be differentiated. Central differences is
227
+ actually viable here, making analytic differentiation unneccessary at the cost
228
+ of a few extra samples. It's viable here because we take a very small step
229
+ rather than reaching to the far corners of the rectangle.
230
+
231
+ ``` gdscript
232
+ var step = .1
233
+ var r = _wave(center + Vector3.RIGHT * step)
234
+ var l = _wave(center + Vector3.LEFT * step)
235
+ var u = _wave(center + Vector3.BACK * step)
236
+ var d = _wave(center + Vector3.FORWARD * step)
237
+ var grad = Vector3(r - l, 0.0, u - d) / (2.0 * step)
238
+ ```
239
+
240
+ Measuring the difference between this method and the last method for step sizes
241
+ ` .01 ` , ` .1 ` and ` 1 ` were all oscillating between ` 0.01 and .1 ` using the
242
+ following measurement:
243
+
244
+ ```
245
+ (grad.normalized() - _wave_gradient(center).normalized()).length()
246
+ ```
247
+
248
+ The magnitudes were massively different, with the difference in maginitude
249
+ oscillating as well. This can be partially mitigated by using a higher
250
+ ` strength ` or an extra division by ` step ` .
251
+
219
252
220
253
## Swimming
221
254
0 commit comments