Witam ponownie!
Troszkę czasu się z tym męczyłem. Ale stwierdziłem, że to za dużo zabawy ze zwykłym GDI++, ponieważ przy tych wzorach na elipsę, które wykombinowałem, podczas obracania wszystkim to tak dziwnie przyspieszało i zwalniało w niektórych momentach. Liczyłem kąt pozycji myszki względem środka kontrolki, a potem różnicę z poprzednim kątem wyglądało to +/- tak:
private bool isDown = false;
private float lastAngle;
private float RadianToDegree(double angle)
{
return ((float)angle * (180.0f / (float)Math.PI) + 180.0f);
}
void Carousel_MouseMove(object sender, MouseEventArgs e)
{
if (isDown)
{
float angl = RadianToDegree(Math.Atan2(e.Y - this.Height / 2, e.X - this.Width / 2));
AngleOffset -= (lastAngle - angl);
lastAngle = angl;
this.Refresh();
}
}
void Carousel_MouseUp(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
isDown = false;
}
}
void Carousel_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
isDown = true;
lastAngle = RadianToDegree(Math.Atan2(e.Y - this.Height / 2, e.X - this.Width / 2));
}
}
Gdzie na podstawie angleOffset wszystko było rysowane:
private float obliczX(float stopnie, float r)
{
return (float)(r * Math.Cos(2.0F * Math.PI * stopnie / 360.0F));
}
private float obliczY(float stopnie, float r)
{
return (float)(r * Math.Sin(2.0F * Math.PI * stopnie / 360.0F));
}
e.Graphics.DrawEllipse(Pens.Red, obliczX(AngleOffset, this.Width / 2) - 3, obliczY(AngleOffset, this.Height / 2) - 3, 6, 6); //Gdzieś w OnPaint
Poza tym w żaden sposób nie mogłem poprawnie wyskalować obrazków, które tam dodawałem, ale cóż...
Jak znajdzie się ktoś chętny, to może ulepszy. :)
Z w/w powodów sięgam po DirectX'a. Tylko nasuwa mi się jedno pytanie... W jaki sposób mam wiedzieć w co kliknął user, zakładając, że będzie sobie mógł ruszać kamerą (lub zakładając, ze ja ją ustawię pod jakimś kątem)?
Coś czuję, że wiąże się to z pewną ilością nie koniecznie prostych obliczeń. Mam nadzieję, że się mylę ;-P
Pozdrawiam, Wronq!