C# animation - move object from A to B or by angle
Hi am just doing a little animation which moves an object from point a to point b or by angle/radians.
what I currently ha开发者_Python百科ve is this
Point CalcMove(Point pt, double angle, int speed)
{
Point ret = pt;
ret.X = (int)(ret.X + speed * Math.Sin(DegToRad(angle)));
ret.Y = (int)(ret.Y + speed * Math.Cos(DegToRad(angle)));
return ret;
}
but it doesn't look what i expected.
please help?
update:
oh and am using NETCFCalcMove(Point pt, double angle, int speed)
"Point pt" is the current object location. "angle" is where the object should go. "speed" is the step.so after days of work..
here's what I have worked on .. Neko for Windows Mobile 6.5Use a rotation matrix. This code will move from a point (x,y) by theta radians to a new point (px, px)
Point Rotate(x, y, theta)
int px = (x * Math.Cos(theta)) - (y * Math.Sin(theta));
int py = (y * Math.Cos(theta)) + (x * Math.Sin(theta));
return new Point(px, py);
end
The matrix used above,
[cosθ - sinθ][x]
[cosθ + sinθ][y]
Will move a point around the circle clockwise when using graphical coordinates.
I did the exact same thing last week. You can animate this by finding the total theta that you wish to move and then divide that by the number of frames (or steps). Now, start every move at some arbitrary point (for example, (0, radius)) and increment some counter totalSteps and move always beginning from that initial point. If you simply move the point itself each frame you will accumulate some error, but if you always move from the initial point by the current increment, stopping when the increment == totalTheta, it will be perfect. Let me know if that makes sense.
Maybe I should illustrate a bit more. Let's say you have a method "BeginMove":
double totalTheta = 0;
double increment = 0;
double currentTheta = 0;
bool moving = false;
void BeginMove()
{
totalTheta = (2 * Math.PI) / numObjects;
increment = totalTheta / steps;
currentTheta = 0;
moving = true;
}
Now you have a method which updates the move every frame:
void Update
{
if (!moving) return;
// do a min/max to ensure that you never pass totalTheta when incrementing.
// there will be more error handling, but this is the basic idea.
currentTheta += increment;
SomeObject.Location = Rotate(0, radius, currentTheta);
moving = (currentTheta < totalTheta);
}
There will obviously be more logic here depending upon your exact situation, but the idea is:
- Find the total theta to move.
- Find the increment (totalTheta / steps)
- Maintain a running total of how much you have moved already.
- Increment the running total by the angle increment before each move.
- Start each move from the same (arbitrary) point on the circle and rotate by the running total.
- Repeat until the running total == total theta.
yes, your formula is incorrect a bit:
let's call the actual angle α and the angle you want to rotate to is β d is length of the line : d = sqrt(xx + yy)
To calculate new coordinates we need:
sin(α+β) = cos β sin α + sin β cos α
cos(α+β) = cos α cos β – sin α sin β
cos α = x / d sin α = y / d
New coords will be: x = sin(α+β)*d y = cos(α+β)*d
all together:
double d = Math.Sqrt(x*x + y*y);
double sina = pt.Y / d;
double cosa = pt.X / d;
double sinb = Math.Sin(DegToRad(angle));
double cosb = Math.Cos(DegToRad(angle));
ret.X = (int)(cosb*sina + sinb*cosa);
ret.Y = (int)(cosa*cosb - sina*sinb);
After every test-fail of those suggested codes (shame on me).. I just came up with a very old solution.
to draw a circle per xypixel, here's a way I did it before back in TurboBasic(dos)
x = xcenter + radius * Cos(radian)<br/>
y = ycenter + radius * Sin(radian)
I applied the same idea by making xy center as the object location, radius is just a value the increments (per step), and the radian was calculated from the last xy object location and the destination xy
Now I have my object that moves from point A to point B
精彩评论