Points along a rotated sine wave
Moderators: gmalivuk, Moderators General, Prelates

 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
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 theoryonly like or just woosh over my head.
Would be grateful if someone could give some pointers.
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 theoryonly like or just woosh over my head.
Would be grateful if someone could give some pointers.
Re: Points along a rotated sine wave
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.
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
Re: Points along a rotated sine wave
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!

 Posts: 131
 Joined: Sat Mar 21, 2009 1:40 am UTC
 Contact:
Re: Points along a rotated sine wave
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.
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.
Re: Points along a rotated sine wave
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?
[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?
Re: Points along a rotated sine wave
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.
[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
Re: Points along a rotated sine wave
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?
And whoops, I forgot about the constant rate. What exactly is rate, here? Magnitude of first derivative WRT t?
 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
Look more carefully: those are vectors, so it just means magnitude. (And I would expect it to mean determinant with a square matrix, actually.)

 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
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(10^{2} + 10^{2}) which gives a 'wavelength' of sqrt(10^{2} + 10^{2}) /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)
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(10^{2} + 10^{2}) which gives a 'wavelength' of sqrt(10^{2} + 10^{2}) /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)
Re: Points along a rotated sine wave
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

 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
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 semicircles, 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.Meem1029 wrote:For computer graphics, I would recommend seeing if you could cheat and use sections of a circle to represent the sine curve.
 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
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.
Re: Points along a rotated sine wave
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.
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.
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 httpequiv="ContentScriptType" content="text/javascript">
<style type="text/css">
H3 { textalign: center; fontsize: large; color: #9944aa; }
canvas { position:relative; }
#ocanvas { border: 1px solid black; }
#candiv {textalign: 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/requestanimationframeforsmartanimating/
http://my.opera.com/emoller/blog/2011/12/20/requestanimationframeforsmarteranimating
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="fontweight: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.

 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
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 nonoptimal 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.
Didn't take much to work to get a rotated sine wave working (Probably nonoptimal 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.
Re: Points along a rotated sine wave
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 nonoptimal 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 scalingrelated 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.
Who is online
Users browsing this forum: Majestic12 [Bot] and 10 guests