# Move from point A to B in small increments in form of sinusoidal wave

UPDATE:

What I want is that given two points A and B, which are not in a straight line, I want a method thats gives me m and n. M and N are a couple of variables that adds to the previous coordinates. Therefore A' is (x0+m, y0+n). This method is going to be called a lot of times, to finally create a sinusoidal trajectory.

My main problem is that I don't really know how to put a sin equation with slope.

I would be grateful if you could help me out with the pseudocode of the method thats obtains m and n values. This method has access to the actual coordinates.

Thank you very much.

OLD POST:

Ok...if I didn't explain my self... I have a particle in a point A (X0, Y0) and I want to move it in a small increment toward point B (X1, Y1). So my new point will be A' which will be at coordinates (X0+m, Y0+n).

I'm totally blocked trying to find a way of obtaining m and n in order to form a sinusoidal wave that moves from one point to another.

Please, notice that it moves in very small intervals, I mean m and n are really small. For example, if the distance between A and B is 1000px, the values for m and n would be between 1 and 5 px.

Thank you very much.

-
what value should the sine have in B? – soulcheck Apr 10 '12 at 10:53
There is an infinite number of sinusoidal waves which can be drawn between 2 points in the plane. You need to be a lot more restrictive in your requirements. If you are more restrictive, and if you understand basic trigonometry, you may solve the problem yourself. If don't understand basic trigonometry try editing your question and someone may help. – High Performance Mark Apr 10 '12 at 10:54
What will really help is if you draw a picture and show us what you want to do. – Li-aung Yip Apr 10 '12 at 11:11
Drawing a picture did, indeed, make your question much clearer. Thank you! – Li-aung Yip Apr 10 '12 at 14:55
However it's not as simple as adding 'm' and 'n' to the x,y coordinates of the sine wave. You can only achieve a translation (that is, an up/down/left/right shift) with that. Rotations require a more complicated calculation using trigonometry, which you can do using a rotation matrix. See answer. – Li-aung Yip Apr 10 '12 at 15:10
show 1 more comment

## migrated from stackoverflow.comApr 11 '12 at 14:24

Do you perhaps want to generate the x and y points for a sine wave, as a function of time, and then apply a linear/affine transformation?

A linear transformation includes rotation, shearing and stretching. An affine transformation can also include shifting the points up/down/left/right by a fixed amount.

The MATLAB code that produced the above figure is as follows. Most of it is declarations of the desired characteristics of the sine wave, its size, the rotation angles, and so on.

The core of what you need is just a matrix multiplication of the old point x1,y1 by a linear transformation matrix, which rotates, scales and skews, followed by adding the constant up/down/left/right shift. This gives the new transformed point x2,y2.

If you generalise to an "affine" transform, then you can do all of this in one 3x3 matrix multiplication. This is just as easy, but the maths is (very slightly) more complicated. For this example I'll stick with the "most obvious" way.

% Define sine wave amplitude and frequency
frequency = 5;
amplitude = 2;

% Calculate sine wave (x,y) points over time interval t
t = 0:0.01:2*pi;  % vector of time values - 0 to 2*pi in steps of 0.01
x1 = t;
y1 = amplitude * sin(frequency*t);

% Produce plot
plot (x1,y1);
title 'original'
grid

% Define transform parameters
scale = 5; % 5 times bigger

shift = [ -15
-10 ]; % shift 15 units left, and 10 units down

theta = pi/6; % 30 degrees

rotation_matrix = [ cos(theta), -sin(theta)
sin(theta),  cos(theta)  ];

% Transform points via scaling, shifting, and rotation
% make empty arrays to store new points in
x2 = zeros(size(t));
y2 = zeros(size(t));
% Transform points one at a time
for i = 1:length(t)
old_xy = [ x1(i)
y1(i) ];
% calculate transformed x and y
new_xy = ( rotation_matrix * old_xy * scale ) + shift;

% Store calculated values to vector
x2(i) = new_xy(1);
y2(i) = new_xy(2);
end

% Make a pretty picture
figure;
plot(x2,y2);
set(gca,'XLim',[-20,20],'YLim',[-20,20])
title 'transformed'
grid


The ingredients for what you want are here: you just have to figure out how to get the sine wave to start and stop at your desired endpoints. I leave this exercise in trigonometry up to you.

(Note: If you can't figure out how to find the transformation that will give a sine wave starting a point A and ending at point B, it would be better to ask math.stackexchange.com instead of StackOverflow - that would be a geometry question, not a programming question. Do post links between the related questions, though.)

Edit 2: Slightly incorrect use of mathematical terms - translation is not a linear transformation; it's actually an affine transform, where affine transforms are the more general version of linear transforms.

-
 My problem is not the sin equation, my problem is that I don't know how tho create a sloped sine...check this out: imageshack.us/photo/my-images/848/38386776.png – kama Apr 10 '12 at 14:05 @kama: Right. What you really want to do is calculate x,y coordinates for points on a "normal" sine wave, then stretch, rotate and shift them into place. You can do this using a linear transformation. See my edited answer. – Li-aung Yip Apr 10 '12 at 14:46 This can work perfectly for me. Thank you very much. – kama Apr 10 '12 at 21:44 @kama: don't forget to upvote and accept answers which helped you. ;) – Li-aung Yip Apr 11 '12 at 13:54

The final endpoint doesn't matter. That's when you stop plotting when X >= ?? The increment is an angle, whether it's worth plotting, is the deltaX + deltaY >= 1, unless it's time based as well in which case you might want to show no "visible" change in the time slice.

-
 It would be polite to say why whoever marked me down did so.... – Tony Hopkinson Apr 10 '12 at 14:33

It sounds like you're looking for smooth half-sine motion from A to B, eg 0.5 + 0.5*sin(p), where p is is -pi/2 to +pi/2. If not you can pick whatever porion of a sine you wish by changing the start and end phases. The "fineness" of the points is set by the len.

void buildPointSet(int X0, int Y0, int X1, int Y1, int** points, int len)
{
int i;
double xm, ym, p, pinc;
double pi = 3.1415926536;
double pstart = -pi/2.0, pend = pi/2.0, p;

pinc = (pend - pstart) / ((double)(len - 1));
for (i = 0, p = pstart; i < len; i++, p += pinc)
{
double fraction = 0.5 + ( 0.5 * sin(p) );
xm = ( (1.0 - fraction) * ((double)X0) ) + ( fraction * ((double)X1) );
ym = ( (1.0 - fraction) * ((double)Y0) ) + ( fraction * ((double)Y1) );
points[i][0] = (int)xm;
points[i][1] = (int)ym;
} // end for
}

-
 Note: when calling this C function, make sure points is an array large enough to accept all the points, lest ye create a buffer overflow bug. – Li-aung Yip Apr 10 '12 at 11:26 This is closer to what I actually want to do. However, I want a sloped sine. Check this out: imageshack.us/photo/my-images/848/38386776.png Do you have any clue about how to work it out?? – kama Apr 10 '12 at 14:06