Created
April 18, 2013 20:22
-
-
Save rgov/5415912 to your computer and use it in GitHub Desktop.
Building a curve for @mdznr
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Let's widen the circle to have a radius of 1. | |
Solve x^2 + (y - 1)^2 = 1, you get | |
y = 1 +/- Sqrt[1 - x^2] | |
Focus on the bottom-right part of the circle first, from x = 0 to 1: | |
y = 1 - Sqrt[1 - x^2] | |
Let's make the right half of this curve repeat. Instead of using x, we'll use | |
a sawtooth curve with period 1, which looks like: | |
y = x - Floor[x] | |
Then we get | |
y = 1 - Sqrt[1 - (x - Floor[x])^2] | |
which is the buttom-right of the circle repeating horizontally. Let's make it | |
step up a little bit each time, according to | |
y = Floor[x] | |
then we get | |
y = (1 - Sqrt[1 - (x - Floor[x])^2]) + Floor[x] | |
Now switch to the top-left of the circle. | |
y = 1 + Sqrt[1 - x^2] | |
Lets slide this over so it's in the same position as the bottom-right was: | |
y = Sqrt[1 - (x - 1)^2] | |
So that gives us these two for our quarter-circles. | |
y = Sqrt[1 - (x - 1)^2] | |
y = 1 - Sqrt[1 - x^2] | |
We want one equation which we can toggle between based on f[x]. For instance, | |
to toggle between | |
y = 0 + x | |
y = 1 - x | |
we can use | |
y = (-1)^f[x] * x + ((-1)^f[x] - 1) / -2 | |
which evaluates to the first if f[x] is 0, and the second if f[x] is 1. | |
We do the same trick to toggle between | |
y = x - 1 | |
y = x - 0 | |
yielding | |
y = x - ((-1)^f[x] + 1) / 2 | |
Then we can put these two together to combine our two quarter-circles: | |
y = (-1)^f[x] * Sqrt[1 - (x - ((-1)^f[x] + 1) / 2)^2] + ((-1)^f[x] - 1) / -2 | |
Now we get the top-left when f[x] is 0, and the bottom-right when f[x] is 1. | |
Actually, this is dependent on whether f[x] is even or odd. | |
Let's also combine this with our two earlier findings. Our first was to use the | |
sawtooth curve for x (we don't care about where it appears in f[x]). | |
y = (-1)^f[x] * Sqrt[1 - ((x - Floor[x]) - ((-1)^f[x] + 1) / 2)^2] + ((-1)^f[x] - 1) / -2 | |
And add our step-up: | |
y = (-1)^f[x] * Sqrt[1 - ((x - Floor[x]) - ((-1)^f[x] + 1) / 2)^2] + ((-1)^f[x] - 1) / -2 + Floor[x] | |
All that remains is picking f[x] so that it switches appropriately. We need a | |
stepwise function that switches between even and odd, at an interval of 1. We | |
have this already: | |
f[x] = Floor[x] | |
y = (-1)^Floor[x] * Sqrt[1 - ((x - Floor[x]) - ((-1)^Floor[x] + 1) / 2)^2] + ((-1)^Floor[x] - 1) / -2 + Floor[x] | |
which is the desired curve. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I think I swapped the ordering of the two curves when I was building up the f[x] toggle. I also might be missing some coefficients to change the phase from 2 to 1.
This could probably be done much better using an S-shaped trigonometric function. If you find a suitable one, F[x], then you can re-use the sawtooth and step up tricks: F[x] becomes F[x - Floor[x]] + Floor[x].
For instance, y = 1/2 (tanh[4x - 2] + 1) is pretty close, and gets pretty close. Compare:
http://www.wolframalpha.com/input/?i=y+%3D+tanh%5B2x+-+2%5D+%2B+1%2C+%28-1%29%5EFloor%5Bx+-+1%5D+*+Sqrt%5B1+-+%28%28x+-+1+-+Floor%5Bx+-+1%5D%29+-+%28%28-1%29%5EFloor%5Bx+-+1%5D+%2B+1%29+%2F+2%29%5E2%5D+%2B+%28%28-1%29%5EFloor%5Bx+-+1%5D+-+1%29+%2F+-2+%2B+Floor%5Bx%5D+from+x+%3D+0+to+2
@hortont424 points out you could use the sigmoid function instead of tanh for an easier-to-compute approximation.