We return to our fabled circle, which can be drawn as such: X = 100 + 50 * Cos(0.1 * T) Y = 100 + 50 * Sin(0.1 * T) This goes clockwise starting from the rightmost end of the circle (3:00) Upon experimentation, you may find that we also get a circle even if we do this: X = X + 50 * Cos(0.1 * T) Y = Y + 50 * Sin(0.1 * T) By accidentally placing X and Y instead of our 100, we get a humongous circle. Now, each point of the circle is defined with respect to the previous circle. The circle now has its center where X is 0 and Y is at some value. It obviously starts at (0,0), which is now the topmost end of the circle (12:00), but continues counterclockwise. Why does this make a circle? (This is closely based more with calculus than with trigonometry, and I will avoid using calculus for now.) This is because, when we add our previous value to the next value, we are using our functions (Cos() and Sin()) as an antiderivative of another function. (The antiderivative of a function is another function, FYI.) So, the antiderivative of +Cos() is +Sin(). The plus sign means that we are adding the result (50 * Cos()) to the previous coordinate. This is not all when taking the antiderivative, you also have to divide the 'radius' by the angular frequency to get the actual radius. This number that appears in the additive version as the radius, is not really a radius. It's what I like to call a 'radispeed'. I'll bet there's some word that already exists for this term. So, our first part of the circle: X = X + 50 * Cos(0.1 * T) is equivalent to X = 500 * Sin(0.1 * T) 50 divided by 0.1 gives us 500, the actual radius. X = X + radispeedX * Cos(afreq * T) is equal to X = radispeedX / afreq * Sin(afreq * T), where radispeedX / afreq = radiusX The antiderivative of +Sin is -Cos. This means that the plus will change to a minus. And our second part of the circle: Y = Y + 50 * Sin(0.1 * T) is equivalent to Y = -500 * Cos(0.1 * T) X = 500 * Sin(0.1 * T) Y = -500 * Cos(0.1 * T) That is fine so far, but we did not accomodate for the original placement of the circle. The old circle's centerpoint is at (0, ???) This circle has the centerpoint at (0,0). How do we find the centerpoint? This is surprisingly algebra. The problem is that X = X + 50 * Cos(0.1 * T) Y = Y + 50 * Sin(0.1 * T) does not actually define where it started, so you can specify an initial value for this to work, and it will start the circle at that point (Xi,Yi as our initial point). In our new modified version, we actually have to solve for it. Xi = origX + 500 * Sin(0.1 * T) Notice that our result point is assumed to be Xi, the initial point, and we now solve for the origX. Our time variable T will be replaced by 0, and Sin(0) = 0, leaving us with Xi = origX The initial point Xi is 0, so the origin is 0. It's correct so far. We did find the old circle's centerpoint to be (0, ???) The Y point will be found the same way, using our recently developed expression with the minus sign in it. Yi = origY - 500 * Cos(0.1 * T) Cos(0) is 1, so the - 500 survives the first round. 500 * 1 = 500 Yi = origY - 500 origY must be = Yi + 500, and since Yi = 0, origY must be 500. Our new expressions: X = 500 * Sin(0.1 * T) Y = 500 - 500 * Cos(0.1 * T) (Looks funny, but that's it) Then why does your white circle (additive version) look bigger than the red circle (our newly calculated result)? That is because the original version is not making its calculations often enough to move as fast as the real circle. You can get the circles closer together by decreasing the angular frequency to slow both circles down (this will change the radii, so the radispeeds may need to be changed as well. The smaller the angular frequency, the closer these circles are. You can't set the frequency to zero though, or you'll just get a dot. Also, computer roundoff calculations in our Fmd function can mess things up as well, but the principle behind it should still hold strong. What about a phase shift? The phase shift is passed right through with the function: X = X + radispeedX * F(afreqX * T + phaseX) Y = Y + radispeedY * F(afreqY * T + phaseY) is equal to X = origx + radispeedX / afreqX * antiF(afreqX * T + phaseX) Y = origy + radispeedY / afreqY * antiF(afreqY * T + phaseY) You will have to consider the phase when solving for the origx and origy origx = radiusX * antiF(phaseX) - Xi origy = radiusY * antiF(phaseY) - Yi When will the additive version be useful? It is useful anytime where you are not in direct control of the shape's position. This is often the case with an .Offset function, which is really just a function where you supply an X and a Y, and the object that you offset will move by that amount. So, .Offset(6, 3) moves the object 6 to the right, and 3 down. Similarly, .Offset(radispeedX * F(afreqX * T + phaseX), radispeedY * F(afreqY * T + phaseY)) uses our additive version to move our object in a circle. The reverse of this process would be useful as well, since we may actually want to get something that we can use the .Offset function for, in case we have to use .Offset. In calculus, this would be called finding the derivative of a function (perhaps I should've mentioned this first?). The derivative of +Sin() is +Cos(), and the derivative of +Cos() is -Sin(). We follow the same protocol as we did above, except that now, we have to multiply by the angular frequency. So: X = origx + radiusX * F(afreqX * T + phaseX) Y = origy + radiusY * F(afreqY * T + phaseY) would be written in the additive version as X = X + radiusX * afreqX * dF(afreqX * T + phaseX) Y = Y + radiusY * afreqY * dF(afreqY * T + phaseY) dF() is the derivative of the F() function. Note that the origx and origy disappear. This is why the additive version has to have a fixed starting point, which is probably applied to our object before we are able to .Offset() it. We can also take derivatives of our other functions that we've used for making squares, triangles, etc, and use those in our additive version as well. The derivative of the SquareWave is mostly zero (I mentioned that it's pretty useless already, but...). Our other functions have some meaningful derivatives: the TriangleWave has the SquareWave as its derivative, as: Trgl(afreq * T + phase) --> -2 * SquareWave(afreq * T + phase) A use for our SquareWave! The -2 comes from the TriangleWave beginning with a slope of -2, whereas the starting value for the SquareWave is 1. The explanation for all of these other functions comes with command of calculus (and remember, I'm skipping that for now), so I'll just give out the answers for now. The derivative of the HexagonWave is something that we'll have to define. Similarly, with TrapezoidWave and ScaleneWave.

Public Function Hxgndif(N As Single) As Single Dim Quotient As Single, Res As Single Quotient = N / 4 Res = Fmd(Quotient, 4) If Res >= 0 And Res < 1 Then Hxgndif = 2 'Rising edge of hexagon wave. ElseIf Res >= 1 And Res < 2 Then Hxgndif = 0 'Top part. ElseIf Res >= 2 And Res < 3 Then Hxgndif = -2 'Falling edge of hexagon wave. Else Hxgndif = 0 'Bottom part. End If End Function Public Function Trpzdif(N As Single) As Single Dim Quotient As Single, Res As Single Quotient = N / 3 Res = Fmd(Quotient, 3) If Res >= 0 And Res < 1 Then Trpzdif = 0 'Flat part. ElseIf Res >= 1 And Res < 2 Then Trpzdif = 2 'Rise to the point. Else Trpzdif = -2 'Fall from the point. End If End Function Public Function Sclndif(N As Single) As Single Dim Quotient As Single, Res As Single Quotient = N / 3 Res = Fmd(Quotient, 3) If Res >= 0 And Res < 1 Then Sclndif = 2 'Steep leading edge of wave. Else Sclndif = -1 'Long edge of wave End If End Function |