Cuando necesites saber si tres puntos pertenecen a la misma recta puedes hacerlo verificando las pendientes entre los tres puntos, si resultan iguales significa que están todas en la misma recta.
Las operaciones las realizamos manejando solo las coordenadas X e Y de los puntos asumiendo que siempre están en el mismo plano. Utilizamos la clase ya conocida Point3D que ya conoces de posts anteriores.
Presentamos dos funciones: una devuelve la pendiente entre dos puntos y la otra especifica si los tres puntos están en la misma recta.
A continuación el código:
/// <summary>
/// Obtiene la pendiente de la recta definida por dos puntos
/// </summary>
/// <param name=”p1“>Primer punto</param>
/// <param name=”p2“>Segundo punto</param>
/// <param name=”precision“>Cantidad de decimales de para la precisión decimal</param>
/// <returns></returns>
public static double Pending(Point3D p1, Point3D p2, short precision)
{
double Infinity = 1.7E+308;
try
{
if (Trunk(p2.x, precision) – Trunk(p1.x, precision) == 0)
return Infinity;
else if (Trunk(p2.y, precision) – Trunk(p1.y, precision) == 0)
return 0;
else
return (Trunk(p2.y, precision) – Trunk(p1.y, precision)) /
(double)(Trunk(p2.x, precision) – Trunk(p1.x, precision));
}
catch (Exception ex)
{
MessageBox.Show(“Error:” + Environment.NewLine + ex.Message, “Test”,
MessageBoxButtons.OK, MessageBoxIcon.Error);
return Infinity;
}
}
/// <summary>
/// Establece si tres puntos pertenecen a una misma recta
/// </summary>
/// <param name=”p1“>Primer punto</param>
/// <param name=”p2“>Segundo punto</param>
/// <param name=”p3“>Tercer punto</param>
/// <param name=”precision“>Grado de precisión decimal para los cálculos</param>
/// <returns></returns>
public static bool IsColinear(Point3D p1, Point3D p2, Point3D p3, short precision)
{
try
{
if (p1.Equals(p2))
{
if (p2.Equals(p3))
return true;
}
else if (p2.Equals(p3))
return true;
else if (p1.Equals(p3))
return true;
double a = Pending(p1, p2, precision);
double b = Pending(p1, p3, precision);
double c = Pending(p2, p3, precision);
if ((Trunk(a, precision) == Trunk (b, precision)) &&
(Trunk(a, precision) == Trunk(c, precision)))
{
return true;
}
else
{
return false;
}
}
catch (Exception ex)
{
MessageBox.Show(“Error:” + Environment.NewLine + ex.Message, “Test”,
MessageBoxButtons.OK, MessageBoxIcon.Error);
return false;
}
}
Para poner a prueba las funcionalidades puedes crear un formulario parecido al siguiente:
A continuación el código para los eventos de los controles del formulario:
private void txtPt1X_KeyPress(object sender, KeyPressEventArgs e)
{
TextBox tb = sender as TextBox;
string antT = tb.Text;
string t = tb.Text;
e.Handled = MyClase.OnlyNumbers(e.KeyChar.ToString(), true, ref t);
if (antT != t)
{
tb.Text = t;
tb.SelectionStart = tb.Text.Length;
}
}
private void txtPt1Y_KeyPress(object sender, KeyPressEventArgs e)
{
TextBox tb = sender as TextBox;
string antT = tb.Text;
string t = tb.Text;
e.Handled = MyClase.OnlyNumbers(e.KeyChar.ToString(), true, ref t);
if (antT != t)
{
tb.Text = t;
tb.SelectionStart = tb.Text.Length;
}
}
private void txtPt1Z_KeyPress(object sender, KeyPressEventArgs e)
{
TextBox tb = sender as TextBox;
string antT = tb.Text;
string t = tb.Text;
e.Handled = MyClase.OnlyNumbers(e.KeyChar.ToString(), true, ref t);
if (antT != t)
{
tb.Text = t;
tb.SelectionStart = tb.Text.Length;
}
}
private void txtPt2X_KeyPress(object sender, KeyPressEventArgs e)
{
TextBox tb = sender as TextBox;
string antT = tb.Text;
string t = tb.Text;
e.Handled = MyClase.OnlyNumbers(e.KeyChar.ToString(), true, ref t);
if (antT != t)
{
tb.Text = t;
tb.SelectionStart = tb.Text.Length;
}
}
private void txtPt2Y_KeyPress(object sender, KeyPressEventArgs e)
{
TextBox tb = sender as TextBox;
string antT = tb.Text;
string t = tb.Text;
e.Handled = MyClase.OnlyNumbers(e.KeyChar.ToString(), true, ref t);
if (antT != t)
{
tb.Text = t;
tb.SelectionStart = tb.Text.Length;
}
}
private void txtPt2Z_KeyPress(object sender, KeyPressEventArgs e)
{
TextBox tb = sender as TextBox;
string antT = tb.Text;
string t = tb.Text;
e.Handled = MyClase.OnlyNumbers(e.KeyChar.ToString(), true, ref t);
if (antT != t)
{
tb.Text = t;
tb.SelectionStart = tb.Text.Length;
}
}
private void txtPt3X_KeyPress(object sender, KeyPressEventArgs e)
{
TextBox tb = sender as TextBox;
string antT = tb.Text;
string t = tb.Text;
e.Handled = MyClase.OnlyNumbers(e.KeyChar.ToString(), true, ref t);
if (antT != t)
{
tb.Text = t;
tb.SelectionStart = tb.Text.Length;
}
}
private void txtPt3Y_KeyPress(object sender, KeyPressEventArgs e)
{
TextBox tb = sender as TextBox;
string antT = tb.Text;
string t = tb.Text;
e.Handled = MyClase.OnlyNumbers(e.KeyChar.ToString(), true, ref t);
if (antT != t)
{
tb.Text = t;
tb.SelectionStart = tb.Text.Length;
}
}
private void txtPt3Z_KeyPress(object sender, KeyPressEventArgs e)
{
TextBox tb = sender as TextBox;
string antT = tb.Text;
string t = tb.Text;
e.Handled = MyClase.OnlyNumbers(e.KeyChar.ToString(), true, ref t);
if (antT != t)
{
tb.Text = t;
tb.SelectionStart = tb.Text.Length;
}
}
private void txtPrecision_KeyPress(object sender, KeyPressEventArgs e)
{
TextBox tb = sender as TextBox;
string antT = tb.Text;
string t = tb.Text;
e.Handled = MyClase.OnlyNumbers(e.KeyChar.ToString(), false, ref t);
if (antT != t)
{
tb.Text = t;
tb.SelectionStart = tb.Text.Length;
}
}
private void btCalcular_Click(object sender, EventArgs e)
{
this.lblMsg.Text = “Mensaje:”;
this.lblColienales.Text = “”;
// Verificar los valores en los TextBox
if (!MyClase.IsNumeric(this.txtPt1X.Text) ||
!MyClase.IsNumeric(this.txtPt1Y.Text) ||
!MyClase.IsNumeric(this.txtPt1Z.Text) ||
!MyClase.IsNumeric(this.txtPt2X.Text) ||
!MyClase.IsNumeric(this.txtPt2Y.Text) ||
!MyClase.IsNumeric(this.txtPt2Z.Text) ||
!MyClase.IsNumeric(this.txtPt3X.Text) ||
!MyClase.IsNumeric(this.txtPt3Y.Text) ||
!MyClase.IsNumeric(this.txtPt3Z.Text) ||
!MyClase.IsNumeric(this.txtPrecision.Text))
{
this.lblMsg.Text = “Formato erróneo en los números o en la precisión.”;
return;
}
Point3D _pt1 = new Point3D(this.txtPt1X.ToDouble(), this.txtPt1Y.ToDouble(), this.txtPt1Z.ToDouble());
Point3D _pt2 = new Point3D(this.txtPt2X.ToDouble(), this.txtPt2Y.ToDouble(), this.txtPt2Z.ToDouble());
Point3D _pt3 = new Point3D(this.txtPt3X.ToDouble(), this.txtPt3Y.ToDouble(), this.txtPt3Z.ToDouble());
Int16 precision = Convert.ToInt16(this.txtPrecision.ToInteger());
if (MyClase.IsColinear(_pt1, _pt2, _pt3, precision))
{
this.lblColienales.Text = “SI”;
}
else
{
this.lblColienales.Text = “NO”;
}
}
Si todo ha ido bien deberías obtener un resultado parecido al siguiente:
Ponlo a prueba, piensa en cómo mejorarlo y comparte con nosotros tus progresos.