You can make use of the MathF.Atan2(..)
MathF function.
Wiki on Atan2 explains what atan2 is used for.
The function atan2 (y,x)
or arctan2(y,x)
(from "2-argument
arctangent") is defined as the angle in the Euclidean plane, given in
radians, between the positive x axis and the ray to the point (x, y) ≠
(0, 0).
Calculate the Euclidean plane in relation to the picture box.
Vector2 direction = new Vector2(e.X - pictureBox2.Location.X, e.Y - pictureBox2.Location.Y);
Then calculate the angle using Atan2 and convert the radiant value returned by Atan2 to degrees by multiplying it with the constant 57.2978. See wiki on Radian
then using the code linked in this answer to change the bitmap angle.
I used a simple Form with 2 picture boxes on it.
- Assigned picture box 1 a picture as source.
- Leave picture Box 2 blank.
- Implement the code in the
Form1_MouseMove
Event.
EDIT:
I changed to code to display a calculated method using the TranslateTransform(..)
method and another method using the Matrix.RotateAt(...)
method.
Also implemented the Dispose of the image as suggested by @Jimi
Code:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
Image _Image = Image.FromFile(@"S:\Images\next.png");
private void Form1_MouseMove(object sender, MouseEventArgs e)
{
//get the direction of the mouse by looking at the position of the picture box in relation to the mouse pointer
Vector2 pictureBoxMtxPlane = new Vector2(e.X - pictureBoxMtx.Location.X, e.Y - pictureBoxMtx.Location.Y);
Vector2 pictureBoxCalcPlane = new Vector2(e.X - pictureBoxCalc.Location.X, e.Y - pictureBoxCalc.Location.Y);
//https://en.wikipedia.org/wiki/Atan2
//atan2 - calculates the angle between the x axis and the ray line to a point. gt 0
//57.2978 is a constant used for radians to degrees conversion (One radian is equal 57.295779513 degrees)
//https://en.wikipedia.org/wiki/Radian
float convertToDeg = (180 / MathF.PI);
float angleMtx = MathF.Atan2(pictureBoxMtxPlane.Y, pictureBoxMtxPlane.X) * convertToDeg;
float angleCalc = MathF.Atan2(pictureBoxCalcPlane.Y, pictureBoxCalcPlane.X) * convertToDeg;
//show the angle values on the label controls
lblMtxDeg.Text = angleMtx.ToString();
lblCalcDeg.Text = angleCalc.ToString();
//dispose the previously drawn image if there was an image (? - null conditional)
pictureBoxMtx.Image?.Dispose();
Bitmap mtxBitmap = new Bitmap(_Image, pictureBoxMtx.Size.Width, pictureBoxMtx.Size.Height);
pictureBoxCalc.Image?.Dispose();
Bitmap calcBitmap = new Bitmap(_Image, pictureBoxCalc.Size.Width, pictureBoxCalc.Size.Height);
//set picture box 2 to the rotated source image.
pictureBoxMtx.Image = RotateImageMatrix(mtxBitmap, angleMtx);
pictureBoxCalc.Image = RotateImage(calcBitmap, angleCalc);
}
public Bitmap RotateImageMatrix(Bitmap mtxBitmap, float angle)
{
using (var g = Graphics.FromImage(mtxBitmap))
using (var matrix = new Matrix()) {
//rotate at image mid point
matrix.RotateAt(angle, new PointF(mtxBitmap.Width / 2, mtxBitmap.Height / 2));
g.Transform = matrix;
//draw passed in image onto graphics object
g.DrawImage(mtxBitmap, new PointF(0, 0));
}
return mtxBitmap;
}
public Bitmap RotateImage(Bitmap calcBitMap, float angle)
{
using (Graphics g = Graphics.FromImage(calcBitMap))
{
//move rotation point to center of image
g.TranslateTransform((float)calcBitMap.Width / 2, (float)calcBitMap.Height / 2);
//rotate
g.RotateTransform(angle);
//move image back
g.TranslateTransform(-(float)calcBitMap.Width / 2, -(float)calcBitMap.Height / 2);
//draw passed in image onto graphics object
g.DrawImage(calcBitMap, new PointF(0, 0));
}
return calcBitMap;
}
}
It looks like this.
