Usuario
Predibujado de lineas siempre comienza en el punto anterior al punto de inicio del dibujo

Pregunta
-
Hola Amigos del Foro,
Tengo el siguiente código que traza lineas y rectangulos en un picturebox de WinForm mediante dos clase, clase Shape y clase Figura. Cuando doy click en el primer punto extremo, se inicia el predibujado de una linea que va desde el punto clickeado hasta la posición del puntero del mouse, esta linea se dibuja dinamicamente en linea discontinua y sigue el movimiento del mouse, una vez que se hace el segundo click, se dibuja la linea definitiva. El problema principal es que luego que se crea la linea definitiva, la nueva linea a predibujar inicia en el primer punto del la linea definitiva dibujada anteriormente, cuando debe iniciar en el segundo extremo de la mensionada linea o suspenderse hasta que se de click en el primer extremo de la siguiente linea. La misma situación ocurre cuando dibujo los rectangulos. Ver código siguiente:
using System; using System.Collections.Generic; using System.Drawing; using System.Drawing.Drawing2D; using System.Windows.Forms; namespace TrazarLineasEnPictureBox { /// <summary> /// Description of MainForm. /// </summary> public partial class MainForm : Form { List<Shape> Shapes; List<Figura> Figuras; List<PointF> Pt1, Pt1R; List<PointF> Pt2, Pt2R; Shape newShapes; Figura newRect; PointF pt1p, pt2p, pt1R, pt2R; PointF ptemp; int figura; Graphics g; public MainForm() { InitializeComponent(); } void picCanva_MouseDown(object sender, MouseEventArgs e) { } void picCanva_MouseMove(object sender, MouseEventArgs e) { if (figura == 1) { ptemp = (e.Location); if (newShapes != null) { newShapes.pt2 = (e.Location); pt2p = newShapes.pt2; picCanva.Invalidate(); } } else if (figura == 2) { ptemp = (e.Location); if (newRect != null) { newRect.pt2 = (e.Location); pt2R = newRect.pt2; picCanva.Invalidate(); } } picCanva.Invalidate(); } void picCanva_MouseClick(object sender, MouseEventArgs e) { // Sub-rutina para determinar los puntos extremos del segmento de linea if (figura == 1) { if (newShapes == null) { newShapes = new Shape() { pt1 = (e.Location), pt2 = (e.Location) }; pt1p = newShapes.pt1; } else { if (newShapes.pt1 != newShapes.pt2) { Shapes.Add(newShapes); } newShapes = null; } } // Sub-rutina para determinar los puntos superior izquierdo e inferior derecho de rectangulo else if (figura == 2) { if (newRect == null) { newRect = new Figura(g) { pt1 = (e.Location), pt2 = (e.Location) }; pt1R = newRect.pt1; } else { if (newRect.pt1 != newRect.pt2) { Figuras.Add(newRect); } newRect = null; } } picCanva.Refresh(); } void btnLinea_Click(object sender, EventArgs e) { figura = 1;// Indica que se esta dibujando una linea } void btnRect_Click(object sender, EventArgs e) { figura = 2;// Indica que se esta dibujando un rectangulo } void MainForm_Load(object sender, EventArgs e) { Shapes = new List<Shape>(); // Lista de lineas Figuras = new List<Figura>(); // Lista de rectangulos Pt1 = new List<PointF>(); Pt2 = new List<PointF>(); Pt1R = new List<PointF>(); Pt2R = new List<PointF>(); } void picCanva_Paint(object sender, PaintEventArgs e) { g = e.Graphics; e.Graphics.Clear(picCanva.BackColor); g.SmoothingMode = SmoothingMode.AntiAlias; float[] dashValues = { 5, 3 }; Pen psel = new Pen(Color.WhiteSmoke, 1); Pen p = new Pen(Color.YellowGreen, 1); psel.DashPattern = dashValues; // Aqui se colocan los puntos en las listas de puntos. if (newShapes != null) newShapes.Draw(g); for (int i = 0; i < Shapes.Count; i++) { Pt1.Add(Shapes[i].pt1); Pt2.Add(Shapes[i].pt2); } // Aqui se colocan los puntos en las listas de puntos. if (newRect != null) newRect.DrawRectangulo(g); for (int i = 0; i < Figuras.Count; i++) { Pt1R.Add(Figuras[i].pt1); Pt2R.Add(Figuras[i].pt2); } if (figura == 1) { // // Aqui se predibuja el segmento de linea hasta el punto provisional. if(ptemp == pt2p) return; g.DrawLine(psel, pt1p, ptemp); } if (figura == 2) { // Predibuja el rectangulo correspondiente a las losas using (SolidBrush brFig = new SolidBrush(Color.Gray)) { RectangleF rectFig = new RectangleF(pt1R, new SizeF((ptemp.X - pt1R.X),(ptemp.Y - pt1R.Y))); g.FillRectangle(brFig, rectFig); } } // Rutina para dibujar los segmentos de lineas for (int i = 0; i < Pt1.Count; i++) { g.DrawLine(p, Pt1[i], Pt2[i]); } // Rutina para dibujar los rectangulos correspondientes a las losas for (int i = 0; i < Pt1R.Count; i++) { RectangleF LosaRtg = new RectangleF(Pt1R[i], new SizeF((Pt2R[i].X-Pt1R[i].X), (Pt2R[i].Y-Pt1R[i].Y))); g.FillRectangle(new SolidBrush(Color.Gold), LosaRtg); } } void BtnSalir_Click(object sender, EventArgs e) { Close(); } } }
Código de clase Shape.
using System; using System.Drawing; namespace TrazarLineasEnPictureBox { /// <summary> /// Description of Shape. /// </summary> public class Shape { public PointF pt1{ get; set; } public PointF pt2{ get; set; } Pen psel = new Pen(Color.WhiteSmoke, 1); public void Draw(Graphics g) { g.DrawLine(psel, pt1, pt2); } } }
Código de clase Figura.
using System; using System.Drawing; namespace TrazarLineasEnPictureBox { /// <summary> /// Description of Figura. /// </summary> public class Figura { public PointF pt1 { get; set;} public PointF pt2 { get; set;} public Color color = Color.Yellow; private Graphics g; public Figura() { //Constructor sin parametro } public Figura(Graphics _g) { this.g = _g; } public void DrawRectangulo(Graphics g) { using (SolidBrush br = new SolidBrush(Color.FromArgb(20, 224, 224, 90))) { RectangleF rect = new RectangleF(pt1,new SizeF((pt2.X-pt1.X),(pt2.Y-pt1.Y))); g.FillRectangle(br,rect); } } } }
Agradecería su valiosa colaboración,
Atte. MLiranzo
MLiranzo