Программа реализует триангуляцию Делоне.(при нажатии лкм строится точка )
помогите исправить код, чтобы точки считывались из файла и по ним строилась триангуляция
Код:
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
namespace Csharp_Delauney
{
/// <summary>
/// Summary description for Form1.
/// </summary>
public class Form1 : System.Windows.Forms.Form
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.Container components = null;
// ---------------------------------------------------------------
// ---------------------------------------------------------------
// ---------------------------------------------------------------
//Points (Vertices)
public struct dVertex
{
public int x;
public int y;
public int z;
}
//Created Triangles, vv# are the vertex pointers
public struct dTriangle
{
public int vv0;
public int vv1;
public int vv2;
}
//Set these as applicable
public int MaxVertices = 500;
public int MaxTriangles = 1000;
public dVertex[] Vertex;
public dTriangle[] Triangle;
private System.Windows.Forms.PictureBox pictureBox2;
private System.Windows.Forms.Label label4;
private System.Windows.Forms.Label label5;
private System.Windows.Forms.Label label6;
int tPoints; //Variable for total number of points (vertices)
// ---------------------------------------------------------------
// ---------------------------------------------------------------
// ---------------------------------------------------------------
public Form1()
{
//
// Required for Windows Form Designer support
//
InitializeComponent();
// ------------------------------------------------------------------------------------
//Our points
Vertex = new dVertex[MaxVertices];
//Our Created Triangles
Triangle = new dTriangle[MaxTriangles] ;
//Initiate total points to 1, using base 0 causes problems in the functions
tPoints = 1;
// ------------------------------------------------------------------------------------
//
// TODO: Add any constructor code after InitializeComponent call
//
}
/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.pictureBox2 = new System.Windows.Forms.PictureBox();
this.label4 = new System.Windows.Forms.Label();
this.label5 = new System.Windows.Forms.Label();
this.label6 = new System.Windows.Forms.Label();
this.SuspendLayout();
//
// pictureBox2
//
this.pictureBox2.BackColor = System.Drawing.Color.White;
this.pictureBox2.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.pictureBox2.Location = new System.Drawing.Point(8, 32);
this.pictureBox2.Name = "pictureBox2";
this.pictureBox2.Size = new System.Drawing.Size(280, 208);
this.pictureBox2.TabIndex = 0;
this.pictureBox2.TabStop = false;
this.pictureBox2.MouseMove += new System.Windows.Forms.MouseEventHandler(this.pictureBox2_MouseMove);
this.pictureBox2.MouseDown += new System.Windows.Forms.MouseEventHandler(this.pictureBox2_MouseDown);
//
// label4
//
this.label4.Location = new System.Drawing.Point(8, 8);
this.label4.Name = "label4";
this.label4.Size = new System.Drawing.Size(120, 16);
this.label4.TabIndex = 1;
this.label4.Text = "# points";
this.label4.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
//
// label5
//
this.label5.Location = new System.Drawing.Point(160, 8);
this.label5.Name = "label5";
this.label5.Size = new System.Drawing.Size(128, 16);
this.label5.TabIndex = 2;
this.label5.Text = "# triangles";
this.label5.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
//
// label6
//
this.label6.Location = new System.Drawing.Point(16, 248);
this.label6.Name = "label6";
this.label6.Size = new System.Drawing.Size(272, 16);
this.label6.TabIndex = 3;
this.label6.Text = "X,Y";
this.label6.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(296, 269);
this.Controls.Add(this.label6);
this.Controls.Add(this.label5);
this.Controls.Add(this.label4);
this.Controls.Add(this.pictureBox2);
this.Name = "Form1";
this.ResumeLayout(false);
}
#endregion
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.Run(new Form1());
}
// --------------------------------------------------------------------------------------
// --------------------------------------------------------------------------------------
// --------------------------------------------------------------------------------------
// --------------------------------------------------------------------------------------
// --------------------------------------------------------------------------------------
private bool InCircle(ref int xp, ref int yp, ref int x1 , ref int y1 , ref int x2 , ref int y2 , ref int x3 , ref int y3 , ref double xc, ref double yc, ref double r)
{
//Return TRUE if the point (xp,yp) lies inside the circumcircle
//made up by points (x1,y1) (x2,y2) (x3,y3)
//The circumcircle centre is returned in (xc,yc) and the radius r
//NOTE: A point on the edge is inside the circumcircle
bool TheResult;
double eps;
double m1;
double m2;
double mx1;
double mx2;
double my1;
double my2;
double dx;
double dy;
double rsqr;
double drsqr;
TheResult = false;
eps = 0.000001;
if (System.Math.Abs(y1 - y2) < eps && System.Math.Abs(y2 - y3) < eps)
{
MessageBox.Show("INCIRCUM - F - Points are coincident !!");
TheResult = false;
return TheResult;
}
if (System.Math.Abs(y2 - y1) < eps)
{
m2 = (double) -(x3 - x2) / (y3 - y2);
mx2 = (double) (x2 + x3) / 2;
my2 = (double) (y2 + y3) / 2;
xc = (x2 + x1) / 2;
yc = m2 * (xc - mx2) + my2;
}
else if (System.Math.Abs(y3 - y2) < eps)
{
m1 = (double) -(x2 - x1) / (y2 - y1);
mx1 = (double) (x1 + x2) / 2;
my1 = (double) (y1 + y2) / 2;
xc = (x3 + x2) / 2;
yc = m1 * (xc - mx1) + my1;
}
else
{
m1 = (double) -(x2 - x1) / (y2 - y1);
m2 = (double) -(x3 - x2) / (y3 - y2);
mx1 = (double) (x1 + x2) / 2;
mx2 = (double) (x2 + x3) / 2;
my1 = (double) (y1 + y2) / 2;
my2 = (double) (y2 + y3) / 2;
xc = (m1 * mx1 - m2 * mx2 + my2 - my1) / (m1 - m2);
yc = m1 * (xc - mx1) + my1;
}
dx = x2 - xc;
dy = y2 - yc;
rsqr = dx * dx + dy * dy;
r = System.Math.Sqrt(rsqr);
dx = xp - xc;
dy = yp - yc;
drsqr = dx * dx + dy * dy;
if (drsqr <= rsqr)
{
TheResult = true;
}
return TheResult;
}
private int WhichSide(ref int xp, ref int yp, ref int x1, ref int y1, ref int x2, ref int y2)
{
// Determines which side of a line the point (xp,yp) lies.
// The line goes from (x1,y1) to (x2,y2)
// Returns -1 for a point to the left
// 0 for a point on the line
// +1 for a point to the right
double equation;
equation = ((yp - y1) * (x2 - x1)) - ((y2 - y1) * (xp - x1));
if (equation > 0)
{
return -1;
}
else if (equation == 0)
{
return 0;
}
else
{
return 1;
}
}
public int Triangulate(ref int nvert)
{
// Takes as input NVERT vertices in arrays Vertex()
// Returned is a list of NTRI triangular faces in the array
// Triangle(). These triangles are arranged in clockwise order.
bool[] Complete = new bool[MaxTriangles];
int[,] Edges = new int[3, MaxTriangles * 3];
int Nedge;
// For Super Triangle
int xmin;
int xmax;
int ymin;
int ymax;
int xmid;
int ymid;
double dx;
double dy;
double dmax;
// General Variables
int i;
int j;
int k;
int ntri;
bool inc;
double xc;
xc = 0;
double yc;
yc = 0;
double r;
r = 0;
// Find the maximum and minimum vertex bounds.
// This is to allow calculation of the bounding triangle
xmin = Vertex[1].x;
ymin = Vertex[1].y;
xmax = xmin;
ymax = ymin;
for (i=2; i <= nvert; i++)
{
if (Vertex[i].x < xmin)
{
xmin = Vertex[i].x;
}
if (Vertex[i].x > xmax)
{
xmax = Vertex[i].x;
}
if (Vertex[i].y < ymin)
{
ymin = Vertex[i].y;
}
if (Vertex[i].y > ymax)
{
ymax = Vertex[i].y;
}
}
dx = xmax - xmin;
dy = ymax - ymin;
if (dx > dy)
{
dmax = dx;
}
else
{
dmax = dy;
}
xmid = (xmax + xmin) / 2;
ymid = (ymax + ymin) / 2;
// Set up the supertriangle
// This is a triangle which encompasses all the sample points.
// The supertriangle coordinates are added to the end of the
// vertex list. The supertriangle is the first triangle in
// the triangle list.
Vertex[nvert + 1].x = (int) (xmid - 2 * dmax);
Vertex[nvert + 1].y = (int) (ymid - dmax);
Vertex[nvert + 2].x = (int) xmid;
Vertex[nvert + 2].y = (int) (ymid + 2 * dmax);
Vertex[nvert + 3].x = (int) (xmid + 2 * dmax);
Vertex[nvert + 3].y = (int) (ymid - dmax);
Triangle[1].vv0 = nvert + 1;
Triangle[1].vv1 = nvert + 2;
Triangle[1].vv2 = nvert + 3;
Complete[1] = false;
ntri = 1;
// Include each point one at a time into the existing mesh
for (i=1; i <= nvert; i++)
{
Nedge = 0;
// Set up the edge buffer.
// If the point (Vertex(i).x,Vertex(i).y) lies inside the circumcircle then the
// three edges of that triangle are added to the edge buffer.
j = 0;
do
{
j = j + 1;
if (Complete[j] != true)
{
inc = InCircle(ref Vertex[i].x, ref Vertex[i].y, ref Vertex[Triangle[j].vv0].x, ref Vertex[Triangle[j].vv0].y, ref Vertex[Triangle[j].vv1].x, ref Vertex[Triangle[j].vv1].y, ref Vertex[Triangle[j].vv2].x, ref Vertex[Triangle[j].vv2].y, ref xc, ref yc, ref r);
// Include this if points are sorted by X
// If (xc + r) < Vertex(i).x Then
// complete(j) = True
// Else
if (inc)
{
Edges[1, Nedge + 1] = Triangle[j].vv0;
Edges[2, Nedge + 1] = Triangle[j].vv1;
Edges[1, Nedge + 2] = Triangle[j].vv1;
Edges[2, Nedge + 2] = Triangle[j].vv2;
Edges[1, Nedge + 3] = Triangle[j].vv2;
Edges[2, Nedge + 3] = Triangle[j].vv0;
Nedge = Nedge + 3;
Triangle[j].vv0 = Triangle[ntri].vv0;
Triangle[j].vv1 = Triangle[ntri].vv1;
Triangle[j].vv2 = Triangle[ntri].vv2;
Complete[j] = Complete[ntri];
j = j - 1;
ntri = ntri - 1;
}
}
} while (j < ntri);
// Form new triangles for the current point
// Skipping over any tagged edges.
// All edges are arranged in clockwise order.
for (j=1; j <= Nedge; j++)
{
if (Edges[1, j] != 0 && Edges[2, j] != 0)
{
ntri = ntri + 1;
Triangle[ntri].vv0 = Edges[1, j];
Triangle[ntri].vv1 = Edges[2, j];
Triangle[ntri].vv2 = i;
Complete[ntri] = false;
}
}
}
// Remove triangles with supertriangle vertices
// These are triangles which have a vertex number greater than NVERT
i = 0;
do
{
i = i + 1;
if (Triangle[i].vv0 > nvert || Triangle[i].vv1 > nvert || Triangle[i].vv2 > nvert)
{
Triangle[i].vv0 = Triangle[ntri].vv0;
Triangle[i].vv1 = Triangle[ntri].vv1;
Triangle[i].vv2 = Triangle[ntri].vv2;
i = i - 1;
ntri = ntri - 1;
}
}while (i < ntri);
return ntri;
}
private void pictureBox2_MouseMove( object sender, System.Windows.Forms.MouseEventArgs e )
{
// local mouse coords
label6.Text = e.X.ToString() + "," + e.Y.ToString();
}
private void pictureBox2_MouseDown(System.Object eventSender, System.Windows.Forms.MouseEventArgs eventArgs)
{
Graphics g;
g = pictureBox2.CreateGraphics();
g.CompositingMode = CompositingMode.SourceOver;
g.SmoothingMode = SmoothingMode.None;
Pen myPen = new Pen(Color.Blue, 1);
int i;
// variable to hold how many triangles are created by the triangulate function
int HowMany = 0;
// Set Vertex coordinates where you clicked the pic box
Vertex[tPoints].x = eventArgs.X;
Vertex[tPoints].y = eventArgs.Y;
// Perform Triangulation Function if there are more than 2 points
if (tPoints > 2)
// Clear the Picture Box
{
pictureBox2.Refresh();
// Returns number of triangles created.
HowMany = Triangulate(ref tPoints);
}
else
{
// Draw a circle where you clicked so it does something
// g.DrawRectangle(myPen, Vertex(tPoints).x, Vertex(tPoints).y, 14, 14)
g.DrawEllipse(myPen, Vertex[tPoints].x, Vertex[tPoints].y, 4, 4);
}
// Display the total points and total triangles
label4.Text = "Points: " + tPoints;
label5.Text = "Triangles: " + HowMany;
// Increment the total number of points
tPoints = tPoints + 1;
// Draw the created triangles
for (i=1; i <= HowMany; i++)
{
g.DrawLine(myPen, Vertex[Triangle[i].vv0].x, Vertex[Triangle[i].vv0].y, Vertex[Triangle[i].vv1].x, Vertex[Triangle[i].vv1].y);
g.DrawLine(myPen, Vertex[Triangle[i].vv1].x, Vertex[Triangle[i].vv1].y, Vertex[Triangle[i].vv2].x, Vertex[Triangle[i].vv2].y);
g.DrawLine(myPen, Vertex[Triangle[i].vv0].x, Vertex[Triangle[i].vv0].y, Vertex[Triangle[i].vv2].x, Vertex[Triangle[i].vv2].y);
}
g.Dispose();
}
}
}