今天是10.24,周六,各位coder不用加班,祝天下程序员们写码无bug
1、首先需要一张转盘图片,这里使用visio制作。
第一张图片是中心透明的png图,用于遮挡旋转时周围影响效果的图像。
2、导入图片为Image,然后转换为bitmap位图,最后导入到画刷中
1) Image tmpImage = Image.FromFile(picSpinTablePath[0]);
2)Bitmap tmpBitmap = new Bitmap(tmpImage);
3)TextureBrush MyBrush = new TextureBrush(tmpBitmap);
3、旋转与坐标变换
接下来使用brush的旋转函数,调用完会发现图片旋转了。
1)但是,他不是围绕中心点旋转的。而是围绕左上角的坐标原点旋转的。如图:
MyBrush.RotateTransform((float)dImageAngle);
2)上图设置的角度为45度。
如果做一个按钮,让图像左右平移, MyBrush.TranslateTransform((float)dX, 0);
y轴置0,只沿x轴平移。理想上图像应该是向右方平移。但实际上并不是。
可以发现,此时图像沿45度往右下方平移。很容易我们就猜到了,图片旋转的时候,不是单纯的旋转了图片。
而是整个坐标轴都跟着旋转了。于是我们需要做一个坐标变换。由于变换需要的几何我在电脑上画图不方便,
就不给出具体过程了,只说下思路,高中知识就可以了:
1)画出正方形A,以A的左上角为原点(0,0)。设正方形边长为L。
2)旋转角度a,这是得到正方形B。以B的边为坐标轴,绘制直角坐标系。
正方形A的中心点为Oa(0.5L,-0.5L),Ob(Xb, Yb)。
接着就是需要根据几何知识,求出Ob的坐标了。这里不给出具体求解过程了,有兴趣自己算。
3)转换结果为:
double dL = tmpImage.Width; //正方形边长
double dA = dImageAngle / 180 * Math.PI; //转换为弧度
Double dA45 = (double)(45) / 180 * Math.PI; //45度角对应的弧度
double dX = Math.Sqrt(2) * dL * Math.Sin(dA / 2) * Math.Cos(dA45 + dA / 2); //计算X轴平移量
double dY = (-1) * Math.Sqrt(2) * dL * Math.Sin(dA / 2) * Math.Sin(dA45 + dA / 2); //计算Y轴平移量
4)调用平移函数平移
MyBrush.TranslateTransform((float)dX, (float)dY);
4、接下来使用Graphics,调用画刷把处理好的图像画到位图上。其中picSpinTable是winform的picture控件
Graphics g = Graphics.FromImage(tmpBitmap);
g.FillRectangle(MyBrush, 0, 0, picSpinTable.Width, picSpinTable.Height);
g.DrawImage(tmpBitmap, new Point(0, 0));
picSpinTable.BackgroundImage = tmpBitmap;
5、整个旋转函数使用定时器实现,做为demo,没有做过多封装和层次化,下面贴主要代码,整个完整程序考虑也会上传上来,
链接为https://download.youkuaiyun.com/download/FHZZWZ/13033809
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace SpinTable
{
public partial class MainFrom : Form
{
public string[] picSpinTablePath = new string[9];
double dImageAngle = 0;
int nSpeed = 0;
public MainFrom()
{
InitializeComponent();
}
private void btnSpin_Click(object sender, EventArgs e)
{
if (timerSpin.Enabled)
{
timerSpin.Enabled = false;
btnSpin.Text = "旋转";
}
else
{
timerSpin.Interval = 45;
timerSpin.Enabled = true;
btnSpin.Text = "停止";
nSpeed = 0;
dImageAngle = (int)dImageAngle % 360;
}
}
private void MainFrom_Load(object sender, EventArgs e)
{
string strPath = System.Environment.CurrentDirectory + "/转盘/";
for(int i = 0; i < 9; i++)
picSpinTablePath[i] = strPath + String.Format("ZP{0}.png", i + 1);
picSpinTable.SizeMode = PictureBoxSizeMode.StretchImage;
// picSpinTable.Width = Image.FromFile(picSpinTablePath[8]).Width;
// picSpinTable.Height = picSpinTable.Width;
picSpinTable.Image = Image.FromFile(picSpinTablePath[8]);
}
double mX = 0; double mY = 0;
private void timerSpin_Tick(object sender, EventArgs e)
{
Random ran = new Random();
Image tmpImage = Image.FromFile(picSpinTablePath[0]);
Bitmap tmpBitmap = new Bitmap(tmpImage);
TextureBrush MyBrush = new TextureBrush(tmpBitmap);
nSpeed++;
if (nSpeed < 100)
{
dImageAngle += nSpeed * 0.2;
}
else if(nSpeed < 201)
{
dImageAngle += 20;
}
else if(nSpeed > 200)
{
if (nSpeed < 270)
dImageAngle += (300 - nSpeed) * 0.2;
else
dImageAngle += 3;
}
if(nSpeed > 300 + ran.Next(0, 100))
{
timerSpin.Enabled = false;
btnSpin.Text = "旋转";
}
//dImageAngle = 45;
MyBrush.RotateTransform((float)dImageAngle);
double dL = tmpImage.Width;
double dA = dImageAngle / 180 * Math.PI;
Double dA45 = (double)(45) / 180 * Math.PI;
double dX = Math.Sqrt(2) * dL * Math.Sin(dA / 2) * Math.Cos(dA45 + dA / 2);
double dY = (-1) * Math.Sqrt(2) * dL * Math.Sin(dA / 2) * Math.Sin(dA45 + dA / 2);
MyBrush.TranslateTransform((float)dX, (float)dY);
Graphics g = Graphics.FromImage(tmpBitmap);
g.FillRectangle(MyBrush, 0, 0, picSpinTable.Width, picSpinTable.Height);//this.ClientRectangle.Width, this.ClientRectangle.Height);
g.DrawImage(tmpBitmap, new Point(0, 0));
picSpinTable.BackgroundImage = tmpBitmap;
}
}
}