public Point2D (float xx, float yy) { x = xx; y = yy; }
public static Point2D operator+ (Point2D p1, Point2D p2)
{
return new Point2D (p1.x + p2.x, p1.y + p2.y);
}
public static Point2D operator- (Point2D p1, Point2D p2)
{
return new Point2D (p1.x - p2.x, p1.y - p2.y);
}
public static Point2D operator* (Point2D pt, float d)
{
return new Point2D (pt.x * d, pt.y * d);
}
public static float operator* (Point2D p1, Point2D p2)
{
return p1.x * p2.x + p1.y * p2.y;
}
//======= Convert to integer
public Point ToInt()
{
Point p = new Point();
p.X = (int)x; p.Y = (int)y;
return p;
}
//====== Vector norm
public static float operator! (Point2D pt)
{
return (float)Math.Sqrt (pt.x*pt.x + pt.y*pt.y);
}
public float Dist (Point2D pt)
{
float
dx = x - pt.x,
dy = y - pt.y;
return (float)Math.Sqrt (dx*dx + dy*dy);
}
public float Cos (Point2D pt)
{
return this * pt / (!this * !pt);
}
}
public class MainForm : Form
{
private Container components = null;
private PictureBox pbPos;
private PictureBox pbNeg;
private Label lblPercent;
private ProgressBar progress;
private Plot.PlotControl plot;
public uint nodes; // Количество узлов сетки
public float charge; // Величина зарядов диполя
public Point2D pPos, pNeg, pFirst, pLast;
private PointF[] points; // Массив координат точек графика
private bool isDragging = false;
private bool isCalculating = false;
private int x0, y0, x, y;
private Point org;
private Pen penFixed = new Pen (Color.Black, 1);
private Pen penDrag = new Pen (Color.Tan, 0);
private Thread thread;
private string title = "Electrostatic field";
public uint Nodes
{
get { return nodes; }
set
{
if (value < 4 || 1000 < value)
MessageBox.Show ("Количество узлов должно быть в диапазоне (4, 1000)");
else
nodes = value;
}
}
private void SetDefaults()
{
nodes = 200;
charge = 1e-6f / (4 * (float)Math.PI * 8.85e-12f);
points = new PointF[nodes];
}
public MainForm()
{
InitializeComponent();
SetDefaults();
SetStyle(
ControlStyles.UserPaint |
ControlStyles.AllPaintingInWmPaint |
ControlStyles.DoubleBuffer, true);
int w = pbPos.Width / 2,
h = pbPos.Height / 2,
y = pbPos.Location.Y,
dx = 140;
org.X = ClientRectangle.Right / 2;
org.Y = y + h;
pbNeg.Location = new Point (org.X + dx - w, y);
pbPos.Location = new Point (org.X - dx - w, y);
pPos = new Point2D (-dx, 0);
pNeg = new Point2D ( dx, 0);
}
private void Draw (Graphics g)
{
g.DrawLine (isDragging ? penDrag : penFixed, x0, y0, x, y);
if (!isDragging)
{
g.FillEllipse (Brushes.Black, x0-4, y0-4, 8, 8);
g.FillEllipse (Brushes.Black, x-4, y-4, 8, 8);
}
}
private void MainForm_MouseDown (object sender, MouseEventArgs e)
{
if (!isCalculating)
{
x0 = e.X; y0 = e.Y;
pFirst = new Point2D (x0-org.X, y0-org.Y);
isDragging = true;
Text = title + String.Format (", x = {0}, y = {1}", x, y);
}
}
private void MainForm_MouseMove (object sender, MouseEventArgs e)
{
if (isDragging)
{
x = e.X; y = e.Y;
Invalidate();
Text = title + String.Format (", x = {0}, y = {1}", x, y);
}
}
private void MainForm_MouseUp (object sender, MouseEventArgs e)
{
if (isDragging)
{
x = e.X; y = e.Y;
pLast = new Point2D (x-org.X, y-org.Y);
isDragging = false;
Graphics g = Graphics.FromHwnd(Handle);
Draw(g);
CalcField field = new CalcField (this, new ProgressHandler(OnProgress));
thread = new Thread (new ThreadStart (field.Recalc));
thread.Start();
isCalculating = true;
progress.Show();
lblPercent.Show();
}
}
public void OnProgress (int id, PointF pt)
{
int pos = (int) Math.Ceiling (100 * (double)id / nodes);
progress.Value = pos;
lblPercent.Text = pos.ToString() + '%';
points[id] = pt;
if (id == nodes - 1)
{
plot.Graph.SetData (points,
"Electrostatic field along the line (v/m)", "dist (m)");
plot.Invalidate();
isCalculating = false;
progress.Hide();
lblPercent.Hide();
thread.Abort();
}
}
protected override void OnPaint(PaintEventArgs e)
{
Draw (e.Graphics);
}
// Здесь следуют Dispose, Windows Form Designer generated code и Main
}
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.