BaoKai_202508-Wms-Jingwang..../ShapeControl_CodeProject/TestShapeControl/Form5.cs
2025-08-24 09:35:55 +08:00

254 lines
8.1 KiB
C#

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace TestShapeControl
{
public partial class Form5 : Form
{
//mousedown start pos
private int sx, sy;
//count the number of times the movemove event is fired
private int num_mousemove = 0;
//sampling interval, record the coordinate after this number of mousemove
private int sampling_interval = 1;
//record the trail of the mousemove
private string str_trail = "";
//animation delay per frame in ms;
private int animation_delay = 0;
public Form5()
{
InitializeComponent();
}
private void ctrl1_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button.Equals(MouseButtons.Left))
{
sx = e.X;
sy = e.Y;
}
}
private void ctrl1_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button.Equals(MouseButtons.Left))
{
//num_mousemove is reset to 0 at each sampling interval
num_mousemove = (num_mousemove + 1) % sampling_interval ;
//we record the mouse cooridinate at each sampling interval
//when num_mousemove is reset to 0
if (num_mousemove == 0)
{
int w=((Control)sender).Width;
int h=((Control)sender).Height;
int lastx=((Control)sender).Left + w/2 ;
int lasty = ((Control)sender).Top +h/2;
((Control)sender).Left = ((Control)sender).Left + (e.X - sx);
((Control)sender).Top = ((Control)sender).Top + (e.Y - sy);
((Control)sender).Refresh();
Graphics.FromImage(this.panel1.BackgroundImage).DrawLine(new Pen(Color.White, 3),
new Point(lastx, lasty),
new Point(((Control)sender).Left + w / 2, ((Control)sender).Top + h / 2));
this.Refresh();
str_trail += lastx + "," + lasty + "|";
}
}
}
private void ResetPanelBackground()
{
object o = global::TestShapeControl.Properties.Resources.ResourceManager.GetObject("bluesky");
this.panel1.BackgroundImage = new Bitmap(this.Width, this.Height, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
Graphics.FromImage(this.panel1.BackgroundImage).DrawImage((Bitmap)o,
new Rectangle(0, 0, panel1.Width, panel1.Height),
new Rectangle(0, 0, ((Bitmap)o).Width, ((Bitmap)o).Height),
GraphicsUnit.Pixel);
//uncomment line below if you just want a plane background
// Graphics.FromImage(this.panel1.BackgroundImage).FillRectangle(new SolidBrush(Color.Green), 0, 0, this.Width, this.Height);
string s="Drag the red dot on the aeroplane around the image to map out a trail for the areoplane.\nDouble click on red dot to start animation.";
Graphics.FromImage(this.panel1.BackgroundImage).DrawString(s, new Font(FontFamily.GenericSansSerif,14,FontStyle.Bold),
new SolidBrush(Color.White), 0, 0);
}
private void Form5_Load(object sender, EventArgs e)
{
this.panel1.Width = this.Width;
this.panel1.Height = this.Height;
this.panel1.Top =0;
this.panel1.Left =0;
this.DoubleBuffered = true;
//invoke double buffer
typeof(Panel).InvokeMember(
"DoubleBuffered",
System.Reflection.BindingFlags.NonPublic |
System.Reflection.BindingFlags.Instance |
System.Reflection.BindingFlags.SetProperty,
null,
panel1,
new object[] { true });
ResetPanelBackground();
}
private double RadianToDegree(double angle)
{
return angle * (180.0 / Math.PI);
}
//Land the butterfly
private void Land(Point p0)
{
ctrlPlane.Left = p0.X - ctrlPlane.Width / 2;
ctrlPlane.Top = p0.Y - ctrlPlane.Height / 2;
ctrlPlane.Refresh();
}
//Move the butterfly, changing it orientation
private void Fly(Point p0, Point p1)
{
//calculate the angle to rotate so that the butterfly
//will be in the correct orientation as the direction
//of flight
double deltaX=(p1.X - p0.X);
double deltaY=(p1.Y - p0.Y);
//may not be necessary as Atan2 function probably handle div by 0
//double epsilon = 0.00001f;
//if (Math.Abs(deltaX) < epsilon && Math.Abs(deltaY) < epsilon)
// return;
double theta= Math.Atan2(deltaY,deltaX );
//if (theta == double.NaN)
// return;
double angle = RadianToDegree(theta);
//redefine angle to be between -180 and 180
if (angle > 180)
angle = angle - 360;
else
{
if (angle < -180)
angle = 360 + angle;
}
// System.Diagnostics.Debug.Print(""+ theta +"-->" + angle);
//set the min angle change
int deltaAngle = (int)Math.Abs(angle - ctrlPlane.ShapeImageRotation);
if(deltaAngle>=5)
ctrlPlane.ShapeImageRotation = (int)angle;
//set the position and orientation of the butterfly
ctrlPlane.Left = p0.X - ctrlPlane.Width / 2;
ctrlPlane.Top = p0.Y - ctrlPlane.Height / 2;
ctrlPlane.Refresh();
}
//trace out the trail, moving the plane along it
private void TraceTrail()
{
if(str_trail =="") return;
ResetPanelBackground();
//note that v[v.Length-1], the last split part is always ""
//as str_trail always end with "|" because we append "|"
//after each set of x,y coordinates to str_trail in the mousemove event handler
var v = str_trail.Split('|');
//we need at lest 5 points
if (v.Length < 5) return;
var v1=v[0].Split(',');
//default dummy values for init purposes
var v2 = v1;
var v3 = v1;
//p0 is start of trail segment
Point p0 = new Point(int.Parse(v1[0]),int.Parse(v1[1]));
Point p1 = Point.Empty;// new Point(int.Parse(v2[0]), int.Parse(v2[1]));
Point p2 = Point.Empty; // new Point(int.Parse(v3[0]), int.Parse(v3[1]));
//p3 is end of trail segment
Point p3 = Point.Empty;
for (int i = 1; i < v.Length - 4; i++)
{
v1= v[i].Split(',');
v2 = v[i + 1].Split(',');
v3 = v[i + 2].Split(',');
p1 = new Point(int.Parse(v1[0]), int.Parse(v1[1]));
p2 = new Point(int.Parse(v2[0]), int.Parse(v2[1]));
p3 = new Point(int.Parse(v3[0]), int.Parse(v3[1]));
Fly(p0, p3);
//move to the next point
p0 = new Point(p1.X, p1.Y);
this.panel1.Refresh();
//manage the speed of animation
System.Threading.Thread.Sleep(animation_delay);
}
Land(p1);
//clear the trail
str_trail = "";
}
private void ctrl1_DoubleClick(object sender, EventArgs e)
{
TraceTrail();
}
}
}