Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
590 views
in Technique[技术] by (71.8m points)

c# - Rotate a Graphics bitmap at its center

I am working on a project for school, we need to make a basic top down race game in C# without using XNA. First of all let me tell you that the stuff we have learned about programming so far has little to do with making something that even remotely looks like a racegame. It didn't get any more difficult than array's, loops etc. So we didn't learn about graphics or anything like that.

Having said all that I am having the following problem.

We have created a Graphics object, and then use DrawImage and use a bitmap from a car.jpg.

graphics = e.Graphics;
graphics.RotateTransform(angle);
graphics.DrawImage(car, xPos, yPos, car.Width, car.Height);

Then we wait for a key press e.g Right

case Keys.Right:
  if (angle != 360)
  {
    angle += 10;
  }
  else
  {
    angle = 0;
  }
  this.Refresh();
  break;

The problem we have is that the pivot point for the rotation is in the top left corner. So as soon as we move the car to something like (20,25) and start to rotate it, it will use (0,0) as the center of rotation. What we want to achieve is to have the center point of rotation at the center of our car.

We have tried looking for ways to change the centerX and centerY of the RotateTransform but have come to the conclusion that this isn't possible with the bitmap. We have been struggling with this problem for over 2 days and can't seem to find any solution for achieving the thing we want.

Is there something we are doing wrong creating the Graphics object, or is there a totally different way to change centerX and centerY for the car?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

To draw a rotated Bitmap you need to do a few steps to prepare the Graphics object:

  • first you move its origin onto the midpoint of the rotation
  • then you rotate by the desired angle
  • next you move it back
  • now you can draw the Bitmap
  • finally you reset the Graphics

This needs to be done for each bitmap.

Here are the steps in code to draw a Bitmap bmp at position (xPos, yPos):

float moveX = bmp.Width / 2f + xPos;   
float moveY = bmp.Height / 2f+ xPosf;   
e.Graphics.TranslateTransform(moveX , moveY );
e.Graphics.RotateTransform(angle);
e.Graphics.TranslateTransform(-moveX , -moveY );
e.Graphics.DrawImage(bmp, xPos, yPos);  
e.Graphics.ResetTransform();

There is one possible complication: If your Bitmap has different dpi resolution than the screen i.e. than the Graphics you must first adapt the Bitmap's dpi setting!

To adapt the Bitmapto the usual 96dpi you can simply do a

bmp.SetResolution(96,96);

To be prepared for future retina-like displays you can create a class variable you set at startup:

int ScreenDpi = 96;
private void Form1_Load(object sender, EventArgs e)
{
  using (Graphics G = this.CreateGraphics()) ScreenDpi = (int)G.DpiX;
}

and use it after loading the Bitmap:

bmp.SetResolution(ScreenDpi , ScreenDpi );

As usual the DrawImage method uses the top left corner of the Bitmap. You may need to use different Points for the rotation point and possibly also for the virtual position of your car, maybe in the middle of its front..


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...