Points along a rotated sine wave

For the discussion of math. Duh.

Moderators: gmalivuk, Moderators General, Prelates

elminster
Posts: 1560
Joined: Mon Feb 26, 2007 1:56 pm UTC
Location: London, UK, Dimensions 1 to 42.
Contact:

Points along a rotated sine wave

Postby elminster » Thu May 03, 2012 8:03 pm UTC

I've got a medium level of understanding of maths, so bear with me if it's not clear. If any assumptions are need to be made, assume it's the simple case.

Say you have a path in the shape of a sine wave starting at point (0,0) going to point (X,Y). The path can be rotated around the origin to face any angle. Radians from (0,0) to point (X,Y) is always such that Sin(pi * radians) = 0.

If you were to travel along that path at a constant rate from the origin to the point (X,Y), how would you find the X,Y coordinates of points at regular specified intervals.

At first I tried calculate it for a regular sine wave then rotating that around the origin, but couldn't really get anything to work. I done calculus before but never did anything this complicated and couldn't really find anything on the internet that explained what I wanted without being too theory-only like or just woosh over my head.
Would be grateful if someone could give some pointers.
Image

User avatar
Qaanol
The Cheshirest Catamount
Posts: 3069
Joined: Sat May 09, 2009 11:55 pm UTC

Re: Points along a rotated sine wave

Postby Qaanol » Fri May 04, 2012 3:01 am UTC

The arc length of a differentiable function f(x) from x=a to x=b is [imath]\int_a^b\sqrt{1+(f'(t))^2}dt[/imath]. For the sinusoidal case, that requires an elliptic integral. Good luck.

Edit: Fixed typo, thanks Turiski.
Last edited by Qaanol on Fri May 04, 2012 4:38 am UTC, edited 2 times in total.
wee free kings

User avatar
Turiski
Posts: 31
Joined: Sat Aug 02, 2008 2:23 pm UTC

Re: Points along a rotated sine wave

Postby Turiski » Fri May 04, 2012 4:31 am UTC

It's actually an [f'(t)]^2 under that integral. But yes, that's still an integral that's not usually solvable (with elementary functions)
Approximately 100% of my forum contribution is in Nomic threads! In fact, if you're reading this signature, you probably knew that because you're reading a Nomic thread! But did you know that I've participated in both Nomic 16.0 AND Nomic 15.0? Woah!

Twelfthroot
Posts: 131
Joined: Sat Mar 21, 2009 1:40 am UTC
Contact:

Re: Points along a rotated sine wave

Postby Twelfthroot » Fri May 04, 2012 4:46 am UTC

I may be misinterpreting, but I think elminster is asking how to find the coordinates of the points which lie on a sine curve that has been rotated about the origin. In which case, the starting point is to parameterize the sine curve. For example, for a simple sine curve y = sin x, we can parameterize as x(t) = t, y(t) = sin t, which will give the x and y coordinates of the sine curve along any "regular specified intervals" of t -- at least, I think that's what was meant. To rotate (say, by θ radians) we can treat the points on the curve as the complex numbers x(t) + iy(t) and multiply every point by exp(iθ), giving us the number [math]z(t) = t\cos(\theta)-\sin(t)\sin(\theta) + i(t\sin(\theta)+\sin(t)\cos(\theta))[/math] and the x and y coordinates along the curve are the real and imaginary parts of z(t) respectively. For example, if you feed Mathematica / Wolfram Alpha this:

ParametricPlot[{t*cos(pi/4)-sin(t)*sin(pi/4), t*sin(pi/4) + sin(t)*cos(pi/4)}, {t, 0, 4pi}]

You'll see two cycles of sin(x) rotated by π/4 radians, with five evenly spaced 'zeros' along the y=x 'axis'.

You could also obtain this result by elementary trigonometry, first determining the coordinates of points along the new axis, then finding the corrections to add to travel orthogonally off the axis to where the sinewave would be, though that's certainly a bit more cumbersome.

gfauxpas
Posts: 97
Joined: Sun Oct 09, 2011 11:24 pm UTC
Contact:

Re: Points along a rotated sine wave

Postby gfauxpas » Fri May 04, 2012 1:09 pm UTC

What about this? p:4 → ℝ2 (or a subset of either):

[imath]p\left({x,y,\theta,t}\right) = \begin{bmatrix} \cos \theta & - \sin \theta \\ \sin \theta & \cos \theta \end{bmatrix}\begin{bmatrix} x \\ y \end{bmatrix}[/imath]

where x = t, y = sin t, θ can be held constant if you'd like, and the operation between them is matrix multiplication?

Meem1029
Posts: 379
Joined: Wed Jul 21, 2010 1:11 am UTC

Re: Points along a rotated sine wave

Postby Meem1029 » Fri May 04, 2012 7:50 pm UTC

Both of the above posts are a good idea, but fail to move along it at constant speed. Also in the example given by gfauxpas, x and y should not be parameters since they are in terms of t. I like the approach he took though, so we would have

[imath]\gamma\left({t}\right) = \begin{bmatrix} \cos \theta & - \sin \theta \\ \sin \theta & \cos \theta \end{bmatrix}\begin{bmatrix} t \\ \sin t \end{bmatrix}[/imath], or

[imath]\gamma (t) = \begin{bmatrix} t \cos \theta - \sin \theta \sin t \\ t \sin \theta + \cos \theta \sin t \end{bmatrix}[/imath] We can show that \

[imath][D \gamma (t)] = \begin{bmatrix} \cos \theta - \sin \theta \cos t \\ \sin \theta + \cos \theta \cos t\end{bmatrix}[/imath]

Now we want to find another function v(t), such that γ(v(t)) has a derivative with a magnitude equal to one at every point. Using the chain rule, we get

[imath]1 = |[D\gamma (v(t))] [v'(t)]| = |\begin{bmatrix} v'(t) (\cos \theta - \sin \theta \cos v(t))\\ v'(t)( \sin \theta + \cos \theta \cos v(t))\end{bmatrix}| = v'(t)^2 ( (\cos \theta - \sin \theta \cos v(t))^2 + (\sin \theta + \cos \theta \cos v(t))^2)[/imath]

Technically that last part is a square root, but since it is equal to 1, we don't have to worry about that. Now just expand that out and solve the differential equation that results to get v(t), and the function you want is γ(v(t)).

Edit: I should note that I'm not positive that equation can be solved using standard techniques.
cjmcjmcjmcjm wrote:If it can't be done in an 80x24 terminal, it's not worth doing

gfauxpas
Posts: 97
Joined: Sun Oct 09, 2011 11:24 pm UTC
Contact:

Re: Points along a rotated sine wave

Postby gfauxpas » Fri May 04, 2012 10:22 pm UTC

Meem, what are those horizontal lines outside your matrices, absolute value of each entry in the matrix? Never seen that notation before, but I guess it makes sense.

And whoops, I forgot about the constant rate. What exactly is rate, here? Magnitude of first derivative WRT t?

User avatar
gmalivuk
GNU Terry Pratchett
Posts: 26824
Joined: Wed Feb 28, 2007 6:02 pm UTC
Location: Here and There
Contact:

Re: Points along a rotated sine wave

Postby gmalivuk » Fri May 04, 2012 10:58 pm UTC

Look more carefully: those are vectors, so it just means magnitude. (And I would expect it to mean determinant with a square matrix, actually.)
Unless stated otherwise, I do not care whether a statement, by itself, constitutes a persuasive political argument. I care whether it's true.
---
If this post has math that doesn't work for you, use TeX the World for Firefox or Chrome

(he/him/his)

elminster
Posts: 1560
Joined: Mon Feb 26, 2007 1:56 pm UTC
Location: London, UK, Dimensions 1 to 42.
Contact:

Re: Points along a rotated sine wave

Postby elminster » Fri May 04, 2012 11:13 pm UTC

Thanks for the suggestions. For context, I was originally going to use it to represent something in computer graphics. Forgive me if I use wrong terminology.

To clarify, the set period of time or distances (given that speed is known)along the sine wave path are as if you were travelling along that path, not just representing a constant speed in the X nor Y direction.
A real world example of this would be something like a sine wave shaped road facing North east being (which would be the same pattern as what Twelfthroot equation would give from wolfram alpha: ParametricPlot[{t*cos(pi/4)-sin(t)*sin(pi/4), t*sin(pi/4) + sin(t)*cos(pi/4)}, {t, 0, 4pi}] ).

If you know the 'amplitude' of the road (i.e Width in relation to the average direction of motion) to be 0.5km and the destination to be 10km north and 10km east of the origin (10,10). You know that the road represents a integer number of pi radians (in the average direction of travel), e.g. 4 in the case of the graph above. So the straight line distance is sqrt(102 + 102) which gives a 'wavelength' of sqrt(102 + 102) /2 .

If you know the car was travelling that road at a constant 5 km/h from the point of origin (Just take it to be 0,0 for simplicity to factor it out), the what would the precise coordinates be at 15mins, 30mins, 45mins and so on (or every 1.25km if you like).
Basically the coordinates at a given interval (distance or speed + time) if you know (1)origin, (2)amplitude, (3)destination coordinates, (4)integer number of radians that the sine wave has, (5)the interval length.

Plotting basic sin(t) at intervals doesn't give a constant speed (in case of the above example, the car would be speeding up along the straighter sections rather than going a constant speed). e.g. sin(pi) - sin(0.9pi) is greater than sin(0.5pi) - sin(0.4pi)
Image

Meem1029
Posts: 379
Joined: Wed Jul 21, 2010 1:11 am UTC

Re: Points along a rotated sine wave

Postby Meem1029 » Fri May 04, 2012 11:42 pm UTC

For computer graphics, I would recommend seeing if you could cheat and use sections of a circle to represent the sine curve.
cjmcjmcjmcjm wrote:If it can't be done in an 80x24 terminal, it's not worth doing

elminster
Posts: 1560
Joined: Mon Feb 26, 2007 1:56 pm UTC
Location: London, UK, Dimensions 1 to 42.
Contact:

Re: Points along a rotated sine wave

Postby elminster » Sat May 05, 2012 12:00 am UTC

Meem1029 wrote:For computer graphics, I would recommend seeing if you could cheat and use sections of a circle to represent the sine curve.
Well no, this isn't going to be an actual wave, it's going to be an particle object travelling along it. More specifically quite a number of them with varying amplitude, etc as part of an effect. I was thinking of doing semi-circles, but the effect isn't quite what I wanted. I might try it with varying length of circular arcs to see what it looks like.
Image

User avatar
jestingrabbit
Factoids are just Datas that haven't grown up yet
Posts: 5967
Joined: Tue Nov 28, 2006 9:50 pm UTC
Location: Sydney

Re: Points along a rotated sine wave

Postby jestingrabbit » Sat May 05, 2012 12:05 am UTC

Another option would be to use cubic splines. Break your curve up into a finite number of sections, and then use a spline for each part. If you do it right, the difference between what you're doing and actual sine waves would be invisible to the naked eye, and the resources to calculate a particle's position would be significantly reduced.
ameretrifle wrote:Magic space feudalism is therefore a viable idea.

User avatar
PM 2Ring
Posts: 3715
Joined: Mon Jan 26, 2009 3:19 pm UTC
Location: Sydney, Australia

Re: Points along a rotated sine wave

Postby PM 2Ring » Sun May 06, 2012 10:51 am UTC

As mentioned earlier in the thread, to parametrize a sine curve by arc length requires an elliptic integral (of the second kind). Some math libraries do provide such functions, but that's probably overkill for this application, since we can approximate equal steps along a curve using the derivative of the curve's function.

Let ds be the desired step length. By Pythagoras' theorem
ds² = dx² + dy²
Thus
dx = ds / sqrt(1 + (dy/dx)² )

(See http://en.wikipedia.org/wiki/Arc_length#Finding_arc_lengths_by_integrating)

For y = a * sin(f * x)
dy/dx = a * f * cos(f * x)
So
dx = ds / sqrt(1 + (a * f * cos(f * x))² )

Here's a small HTML/JavaScript program that illustrates the technique, using the HTML5 canvas to do the animation. To improve the accuracy, use a smaller step size and perform several steps per frame.

Code: Select all

<!DOCTYPE HTML PUBLIC>
<html>
<head>
<title>Sine Anim</title>
<meta http-equiv="Content-Script-Type" content="text/javascript">
<style type="text/css">
    H3 { text-align: center; font-size: large; color: #9944aa; }
    canvas { position:relative; }
    #ocanvas { border: 1px solid black; }
    #candiv {text-align: center; }
</style>
<script>
var canvas, ctx, scanvas, params,
    width, height, Pi2 = 2 * Math.PI,
    framerate = 16, //how often to draw a new frame, in milliseconds
    frequency = 2, amplitude = 0.8, //sine wave parameters relative to canvas size
    delta = 1,  //sprite speed
    spriterad = 10, //sprite size
    spritepos = 0, spriteX = 0, spriteY = 0,
    count = 0, lastTime = 0, go = false;

function ById(id){return document.getElementById(id)}

//Create a canvas element
function make_canvas(w, h)
{
    var c = document.createElement('canvas');
    c.width = w;
    c.height = h;
    return c;
}

/*
A requestAnimationFrame selector with setTimeout fallback,
by Paul Irish, with improved fallback code by Erik Moller. See
http://paulirish.com/2011/requestanimationframe-for-smart-animating/
http://my.opera.com/emoller/blog/2011/12/20/requestanimationframe-for-smart-er-animating

requestAnimationFrame calls the callback with the current time.
*/

window.requestAnimFrame = (function(){
    var lastTime = 0;   

    return window.requestAnimationFrame ||
    window.webkitRequestAnimationFrame ||
    window.mozRequestAnimationFrame ||
    window.oRequestAnimationFrame ||
    window.msRequestAnimationFrame ||   
    function (callback)
    {
        var currTime = + new Date();
        var timeToCall = Math.max(0, 16 - (currTime - lastTime));
        window.setTimeout(function()
            {callback(currTime + timeToCall);}, timeToCall);
        lastTime = currTime + timeToCall;
    }
})();

//The animation callback. The parameter is the current time.
function animate(time)
{
    count += 1;
    if (!go)
        return;
       
    // Request the next animation frame
    window.requestAnimFrame(animate);

    if(time - lastTime > framerate)
    {
        lastTime = time;
        spritepos = spritepos + delta;
        draw();
    }
};

function show_params()
{
    params.innerHTML =
    'go=' + go + '<br>' +
    'spritepos=' + spritepos + '<br>' +
    'count=' + count + '<br>' +
    'lastTime=' + lastTime;   
}

function ev_mousedown(ev)
{
    go = !go;
    if (go)
        animate(+ new Date());
    else
        show_params();
}
   
//Move sprite with Approximate constant speed along sine curve
function draw()
{
    //Compute derivative at current point
    var slope = amplitude * frequency * Math.cos(spriteX * frequency);

    //Compute change in x using Pythagorean relation ds^2 = dx^2 + dy^2,
    // where ds is an element of arc length
    spriteX += delta / Math.sqrt(1 + slope * slope);
   
    if (spriteX >= width)
        spritepos = spriteX = 0;

    spriteY = amplitude * Math.sin(spriteX * frequency);
    put_sprite();
   
    show_params();
}

function put_sprite()
{
    scanvas.style.left = spriteX + scanvas.ox + 'px';
    //Make +Y up
    scanvas.style.top = -spriteY + scanvas.oy + 'px';
}

function draw_sine(canvas)
{
    var ctx = canvas.getContext('2d'), x, y;
       
    ctx.beginPath();
    ctx.moveTo(0, 0);
    for (x=0; x<=width; x++)
    {
        y = amplitude * Math.sin(x * frequency);
        ctx.lineTo(x, y);
    }
    ctx.closePath();
    ctx.stroke();
}
   
function setup()
{
    canvas = ById('ocanvas');
    if (canvas.getContext)
    {
        ctx = canvas.getContext('2d');

        //Get window dimensions & calculate canvas dimensions
        height = canvas.height = Math.floor(0.75 * window.innerHeight);
        width = canvas.width = Math.floor(0.75 * window.innerWidth);
       
        //Put origin at centre left
        ctx.translate(0, height / 2);
        //Make +Y up
        ctx.scale(1, -1);
        ctx.strokeStyle = '#000';
       
        //Draw sine wave path
        frequency *= Pi2 / width;
        amplitude *= height * 0.5;
        draw_sine(canvas, frequency, amplitude);
       
        //Set up sprite
        scanvas = make_canvas(2*spriterad, 2*spriterad);
        ById('candiv').appendChild(scanvas);
        ctx = scanvas.getContext('2d');

        //Set positioning origin for sprite, allowing for canvas border.
        scanvas.ox = -(canvas.width + 6 + spriterad);
        scanvas.oy = -(0.5 * canvas.height + 1 - spriterad);

        //Put drawing origin in centre
        ctx.translate(spriterad, spriterad);
        ctx.fillStyle ="hsla(" + 0 + ",100%, 50%, 0.5)";
        ctx.strokeStyle ="hsla(" + 240 + ",100%, 50%, 0.75)";
       
        //Draw sprite
        ctx.beginPath();
        ctx.arc(0,0, spriterad, 0, Pi2, false);
        ctx.fill();
        //ctx.stroke();
       
        params = ById('paramsdiv');
        //do initial frame
        draw();
       
        canvas.addEventListener('mousedown', ev_mousedown, false);
    }
    else alert("Sorry, I can't set up the canvas!");
}
</script>
</head>

<body onload="setup();">
<h3>Sine Animation</h3>
<div id=candiv>
<canvas id="ocanvas">
    If you can read this, your browser does not support the HTML5 Canvas.
</canvas>

</div>

<p>
<div style="font-weight:bold">Animation parameters</div>
<div id="paramsdiv"></div>

<p>
Sinusoidal motion demo. The particle moves along the sine wave with (approximately) constant speed.
<br>

</body>
</html>

Sorry about all the global variables. :)

To do a rotated sine wave, use rotated coordinates; your graphics library may allow you to provide a rotation matrix to simplify that process.

elminster
Posts: 1560
Joined: Mon Feb 26, 2007 1:56 pm UTC
Location: London, UK, Dimensions 1 to 42.
Contact:

Re: Points along a rotated sine wave

Postby elminster » Mon May 07, 2012 7:32 am UTC

Wow, that's great. Thanks for the time to even prepare a sample.

Didn't take much to work to get a rotated sine wave working (Probably non-optimal way), but wasn't consistent speed.
Were working off a really old DirectDraw (DirectX 7.0a) system, which frankly does barely anything useful, not even blending. Porting it is obviously not a small task.
Image

User avatar
PM 2Ring
Posts: 3715
Joined: Mon Jan 26, 2009 3:19 pm UTC
Location: Sydney, Australia

Re: Points along a rotated sine wave

Postby PM 2Ring » Tue May 08, 2012 3:22 am UTC

elminster wrote:Wow, that's great. Thanks for the time to even prepare a sample.

Didn't take much to work to get a rotated sine wave working (Probably non-optimal way), but wasn't consistent speed.
Were working off a really old DirectDraw (DirectX 7.0a) system, which frankly does barely anything useful, not even blending. Porting it is obviously not a small task.


No worries. I haven't done any HTML/CSS/JavaScript programming for a month or two, so it was a good opportunity to get some practice in and revise my rather patchy CSS knowledge. :)

Pity the speed's not consistent in your rotated version. Perhaps it's some sort of scaling-related issue. I don't know DirectX, but there are people in the Coding forum who could probably help, if you want to post your code over there.


Return to “Mathematics”

Who is online

Users browsing this forum: Majestic-12 [Bot] and 10 guests