Vamos a crear una clase a la que vamos a llamar Point3D que va a representar un punto 3D en el espacio. Dentro de esta clase vamos a implementar dos métodos, uno para medir la distancia entre dos puntos y otro para medir el ángulo de la recta que forman ambos puntos. Los ángulos se cuentan en sentido trigonométrico (en sentido antihorario) iniciándose en la posición “Este”, es decir, a la derecha, por lo que al norte tendríamos 90 grados, al oeste 180 grados y al sur 270 grados.
Aquí el código de la clase:
public class Point3D
{
public Point3D() { }
public Point3D(double X, double Y, double Z)
{
x = X;
y = Y;
z = Z;
}
public double x { get; set; } = 0;
public double y { get; set; } = 0;
public double z { get; set; } = 0;
public override string ToString()
{
return this.x.ToString() + “;” + this.y.ToString() + “;” + this.z.ToString();
}
public double DistanceTo (Point3D OtherPoint)
{
return Math.Sqrt(Math.Pow((OtherPoint.x – this.x), 2) +
Math.Pow((OtherPoint.y – this.y), 2) +
Math.Pow((OtherPoint.z – this.z), 2));
}
public double AngleTo (Point3D OtherPoint)
{
return Math.Atan2(OtherPoint.y – this.y, OtherPoint.x – this.x);
}
}
Para poner a prueba las funcionalidades puedes crear un formulario parecido al siguiente:
Solicitaremos dos puntos mediante las coordenadas X, Y, Z obteniendo la distancia y la precisión. En los TextBox hemos aplicado el método OnlyNumbers para forzar a que solo puedan admitir números. Si no sabes cómo lo hemos hecho puedes visitar el tip donde tratamos este tema. También hemos usado la función Trunk para controlar la precisión de los resultados, si no la conoces visita el tip dedicado a este tema. También aprovechamos las funciones de conversión de radianes a grados decimales y viceversa.
Ya ves que lo vamos aprovechando todo.
A continuación el código del formulario para los distintos eventos de los controles.
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 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:”;
// Verificar los valores en los TextBox
// Si recibimos MinValue significa que no hay valor válido.
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.txtPrecision.Text))
{
this.lblDistancia.Text = “0”;
this.lblAngulo.Text = “0”;
this.lblMsg.Text = “Formato erróneo en los números o en la precisión.”;
}
Point3D punto1 = new Point3D(this.txtPt1X.ToDouble(), this.txtPt1Y.ToDouble(), this.txtPt1Z.ToDouble());
Point3D punto2 = new Point3D(this.txtPt2X.ToDouble(), this.txtPt2Y.ToDouble(), this.txtPt2Z.ToDouble());
this.lblDistancia.Text = MyClase.Trunk(punto1.DistanceTo(punto2), Convert.ToInt16(this.txtPrecision.Text)).ToString();
double ang = punto1.AngleTo(punto2);
int precision = this.txtPrecision.ToInteger();
double result = MyClase.r2d(ang); // Convertir el ángulo en radianes a grados decimales.
this.lblAngulo.Text = MyClase.Trunk(result, Convert.ToInt16(precision)).ToString();
}
Los resultados deberían ser parecidos a los siguientes:
Pon las rutinas a prueba, piensa en cómo mejorarlas y comparte con nosotros tus progresos.