C# 2D 游戏,在椭圆上的点中以切线的角度旋转
本文关键字:旋转 游戏 2D | 更新日期: 2023-09-27 18:32:23
我正在创建一个2D游戏,其中三角形的枪在圆顶上移动,使用drawArc绘制圆顶,这是椭圆的一半。我已经计算了 x 和 y 坐标,使三角形的中间沿着曲线,偏移量使其漂浮在圆顶上方,就像平面一样。问题是它必须旋转到点切线的天使,我相信我的数学是对的,但它不起作用。现在,它做了一些奇怪的旋转,根本没有意义。
这是我希望它如何移动的图纸:https://app.box.com/s/lh689tnhdjcduzxt0mp5
这是我使用的数学:https://app.box.com/s/ee0isbjnjds2yg32toqd
这是代码:
来自计算类的方法
public static double TangentialAngel(float XCoordinateInPoint, float YCoordinateInPoint, int centerToArcY, int centerToArcX, int centerCoordinateX, int centerCoordinateY)
{
return Math.Atan(-((Math.Pow(centerToArcX, 2) * (XCoordinateInPoint - centerCoordinateX)) / (Math.Pow(centerToArcY, 2) * (centerCoordinateY - YCoordinateInPoint))));
}
来自 OnPaint 的代码
startLine = new Point(spacing, this.Size.Height - 10);//Angir starten på linjen i bunnen av grafikken, trekker fra 10 forde jeg ønkser at det skal vere mellomrom mellom bunn av vindu og linja.
endLine = new Point(this.Size.Width - spacing, this.Size.Height - 10);//Angir slutten på linjen i bunnen av grafikken
startPointArcRect = new Point(spacing, this.Size.Height - 10 - this.Size.Height / (arcSizeDynamicModifier * 2) - arcSizeStaticModifier / 2);//Angir start pungtet til rektangeles som Arcen lages etter
sizeArcRect = new Size(this.Size.Width - spacing * 2, this.Size.Height / arcSizeDynamicModifier + arcSizeStaticModifier);//Angir størrelsen på rektangeles som Arcen lages etter
solidBlackBrush = new SolidBrush(Color.Black); //En solid svart brush som brukes flere steder
solidBackPen = new Pen(solidBlackBrush, 2);//En solid svart pen som brukes flere steder
//Tegner Linje og arc
e.Graphics.DrawLine(solidBackPen, startLine, endLine);
arc.Draw(e.Graphics, solidBackPen, new Rectangle(startPointArcRect, sizeArcRect));
int transformX = spacing*2; int transformY = this.Height - 10;
foreach (House house in houses)
{
if (transformX < this.Width - house.Width * 2 - 10)
{
e.Graphics.TranslateTransform(transformX, transformY - house.Height);
house.Draw(solidBackPen, e.Graphics);
transformX += house.Width*2;
e.Graphics.ResetTransform();
}
}
offsetGunY = plane.Height; //Definerer hvor mye Y kordinatet må flyttes for at flyet skal sveve over linen ikke under.
offsetGunX = plane.Width / 2; //Definerer hvor mye X kordiatet må flyttes for at rotasjonskpungtet til pistolen skal havne på mitten ikke gjørnet.
//Henter vinkele til flyet
planeLocationAngle = plane.LocationAngle;
//Beregner radius i pungtet
radiusInPoint = Compute.RadiusInPoint(arc.CenterToArcY, arc.CenterToArcX, planeLocationAngle);
xCoordinateInPoint = Compute.XCoordinateInPoint(arc.CenterX, radiusInPoint, planeLocationAngle);
yCoordinateInPoint = Compute.YCoordinateInPoint(arc.CenterY, radiusInPoint, planeLocationAngle);
plane.RotationAngle = Compute.TangentialAngel(xCoordinateInPoint, yCoordinateInPoint, arc.CenterToArcY, arc.CenterToArcX, arc.CenterY, arc.CenterX);
planeRotationAngle = plane.RotationAngle;
foreach (Bullet bullet in bullets)
{
bullet.Draw(solidBackPen, e.Graphics);
}
//Flytter 0 slik at pistolen havner på rett sted
e.Graphics.TranslateTransform(xCoordinateInPoint, yCoordinateInPoint);
e.Graphics.RotateTransform((float)Compute.RadianToDegree(planeRotationAngle));
//Flytter 0 slik at pistolen havner på linja ikke under
e.Graphics.TranslateTransform(-offsetGunX, -offsetGunY);
//Tegner pistol og resetter transformasjon
plane.Draw(e.Graphics);
e.Graphics.DrawString("0", new Font("Times new roman", 10, FontStyle.Regular), new SolidBrush(Color.Blue), 0, 0);
//TODO Fjern resetTransform før innlevering vis den ikke er nødvendeig da
e.Graphics.ResetTransform();
我修复了数学,并在此过程中发现了一个致命的错别字。错字是我在弧上交换了位置。中心X,弧。中心Y。这是它应该的样子:
plane.RotationAngle = Compute.TangentialAngel(xCoordinateInPoint, yCoordinateInPoint, arc.CenterToArcY, arc.CenterToArcX, arc.CenterX, arc.CenterY);
这是完成的数学方法:
public static double TangentialAngel(float XCoordinateInPoint, float YCoordinateInPoint, int centerToArcY, int centerToArcX, int centerCoordinateX, int centerCoordinateY)
{
double centerToArcYPowTwo = Math.Pow(centerToArcY, 2);
double centerToArcXPowTwo = Math.Pow(centerToArcX, 2);
float XcoordinateInCero = XCoordinateInPoint - centerCoordinateX;
float YcoordinateInCero = centerCoordinateY - YCoordinateInPoint;
return Math.Atan((centerToArcYPowTwo * XcoordinateInCero) / (centerToArcXPowTwo * YcoordinateInCero));
}