none
Pasar dos list<> a points y dibujar el poligono RRS feed

  • Pregunta

  • Hola,

    Trabajo con visual C# 2010 express desarrollando windows from.

    Quisiera pasar dos listas una con las coordenadas X y otra con las coordenadas Y, a un points y a partir de aqui "escalar" para dibujar el poligono formado por los puntos.

    Creo que debería se algo así, me falta meter todo el código:

    Las list son ListX y ListY

    Aqui crear un for o algo así para pasar los puntos de la list a point...   

        Point point1 = new Point(listX[0],listY[0]);

        Point point2 = new Point(listX[1],listY[1]);

        Point point3 = new Point(listX[2],listY[2]);

        .....

    así hasta que termine toda la lista de las X e Y.

    Despues meter todos los point en curvePoints

        Point[] curvePoints =  {point1, point2,point3,.... };

    Después hacer una transformaión de puntos ya que los points a dibujar se pueden salir de la zona de dibujo

    e.Graphics.TransformPoints(CoordinateSpace.Page, CoordinateSpace.World, points);

    Alguien me puede explicar lo (no lo entiendo):

    Page: Especifica que las coordenadas están en el contexto de coordenadas de la página.<//span> PageUnit define sus unidades y debe ser uno de los elementos de la enumeración GraphicsUnit

    World: Especifica que las coordenadas están en el contexto de coordenadas de la realidad.<//span> Las coordenadas de la realidad se usan en un entorno no físico, por ejemplo un entorno de creación de modelos.

     

    Por último dibujo el poligono a partir de los puntos escalados:

    // Dibuja el poligono.

        e.Graphics.DrawPolygon(blackPen, curvePoints);

     

    Gracias

    • Editado cutuche martes, 30 de octubre de 2012 18:26 modificacion
    • Tipo cambiado webJoseModerator martes, 30 de octubre de 2012 20:46
    martes, 30 de octubre de 2012 18:25

Todas las respuestas

  • Sugerencia para los primeros pasos:

    List<int> listX = new List<int> { 1, 2, 3, 4 }; //Ejemplo
    List<int> listY = new List<int> { 5, 6, 7, 8 }; //Ejemplo
    //Construir array de Point con los List<int>
    Point[] curvePoints = new Point[listX.Count];
    for (int i=0; i<listX.Count; i++)
    {
      curvePoints[i] = new Point(listX[i], listY[i]);
    }
    martes, 30 de octubre de 2012 20:43
  • Hola,

    Alberto tu aportación me ha sido muy útil.

    Hasta ahora tengo una aplicación donde introduzco puntos (x e Y) y me dibuja un rectangulo en los puntos y un poligono a partir de 2 puntos introducidos, pero me falta la segunda parte, me explico, si yo introduzco puntos mayores del tamaño (Size: Width y Height) de mi groupBox1, el punto no se verá representado porque sale fuera del rando del groupBox1, necesito hacer una transformación o escala, para ello "Creo" que habría que utilizar :

    formGraphics.TransformPoints(CoordinateSpace.Page, CoordinateSpace.World, points);

    Pero no se como funciona.

    ¿Alguien me puede ayudar a escalar los puntos para que siempre aparezcan dentro de groupBox1 sea cual sea sus coordenadas?

    El codigo hasta ahora es este:

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    namespace WindowsFormsApplication1
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }
            List<int> listX = new List<int>();  //Ejemplo
            List<int> listY = new List<int>();  //Ejemplo
            private void button1_Click(object sender, EventArgs e)
            {
                
                listX.Add(int.Parse(textBox1.Text));
                listY.Add(int.Parse(textBox2.Text));
                
                Graphics formGraphics = groupBox1.CreateGraphics();
                formGraphics.Clear(groupBox1.BackColor);
                
                //Construir array de Point con los List<int>
                Point[] curvePoints = new Point[listX.Count];
                for (int i = 0; i < listX.Count; i++)
                {
                    curvePoints[i] = new Point(listX[i], listY[i]);
                }
                /*Crear lapiz*/
                Pen lapiz = new Pen(Color.Green, 2);
               /*dibujo rectangulos*/
                for (int i = 0; i < listX.Count; i++)
                {
                    formGraphics.DrawRectangle(lapiz, listX[i]-2, listY[i]-2, 4, 4);
                }
                
                          
                if (listX.Count > 1)
                {
                    /*Dibuja el poligono*/
                    formGraphics.DrawPolygon(lapiz, curvePoints);
                }
                          
                label1.Text = listX.Count.ToString();
                formGraphics.Dispose(); //libera recursos del sistema
                    
                }
           }
    }
            
    Gracias
    miércoles, 31 de octubre de 2012 16:32
  • necesito hacer una transformación o escala, para ello "Creo" que habría que utilizar : formGraphics.TransformPoints(CoordinateSpace.Page, CoordinateSpace.World, points); Pero no se como funciona.

    Aunque efectivamente en System.Drawing.Graphics hay funciones para realizar la rotación y escalado de los gráficos, la verdad es que no las he usado nunca. Si el programa lo tuviera que hacer yo, para una labor tan simple como es la de sencillamente cambiar la escala del gráfico para que encaje en el espacio disponible, yo lo haría directamente realizando el cálculo a mano. Basta con un bucle que recorra todo el array de puntos y multiplique la X y la Y por una constante para cambiar de tamaño el gráfico (por ejemplo, 0.5 si lo quieres reducir a la mitad). Opcionalmente puedes además sumar o restar un valor constante a la X y la Y si quieres desplazar los puntos con el fin de centrar el gráfico antes o después de escalarlo.

    Por cierto, a lo mejor te conviene utilizar PointF en lugar de Point para realizar los cálculos en coma flotante en lugar de usar números enteros.

    miércoles, 31 de octubre de 2012 18:49
  • Hola,

    Estoy trabajando en lo que ha comentado Alberto (realizar el cálculo a mano), pero obtengo un error, pongo el código y os comento:

    using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace WindowsFormsApplication1 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } List<double> listX = new List<double>(); //Ejemplo List<double> listY = new List<double>(); //Ejemplo List<float> listXfloat = new List<float>(); //Ejemplo List<float> listYfloat = new List<float>(); //Ejemplo private void button1_Click(object sender, EventArgs e) { listX.Add(double.Parse(textBox1.Text)); listY.Add(double.Parse(textBox2.Text)); //Pasar a float desde el double for (int i = 0; i < listX.Count; i++) { listXfloat.Add(Convert.ToInt64(listX[i])); listYfloat.Add(Convert.ToInt64(listY[i])); } if (listXfloat.Count > 1) { float Xmax = listXfloat.Max(); //Obtengo el valor maximo de la lista de las X float Ymax = listYfloat.Max(); //Obtengo el valor maximo de la lista de las Y float Xmin = listXfloat.Min(); //Obtengo el valor minimo de la lista de las X float Ymin = listYfloat.Min(); //Obtengo el valor minimo de la lista de las Y float IncXdatos = Xmax - Xmin; //Obtengo el incremento de X sobre el terreno float IncYdatos = Ymax - Ymin; //Obtengo el incremento de Y sobre el terreno float IncXgra = groupBox1.Size.Width; //Obtengo el incremento X del grafico float IncYgra = groupBox1.Size.Height;//Obtengo el incremento Y del grafico float EscX = IncXdatos / IncXgra; //Calculo la escala float EscY = IncYdatos / IncYgra; float Escalagrafica = Math.Max(EscX, EscY); //de las escalas X e Y me quedo con la mayor. Escalagrafica = Escalagrafica + (Escalagrafica / 10); //Aplico un 10 % para no tocar con los extremos

    //le aplico la escala grafica for (int i = 0; i < listXfloat.Count; i++) { listXfloat.Add(listXfloat[i] / Escalagrafica); listYfloat.Add(listYfloat[i] / Escalagrafica); } } Graphics formGraphics = groupBox1.CreateGraphics(); formGraphics.Clear(groupBox1.BackColor); //Construir array de Point con los List<float> PointF[] curvePoints = new PointF[listXfloat.Count]; for (int i = 0; i < listXfloat.Count; i++) { curvePoints[i] = new PointF(listXfloat[i], listYfloat[i]); } /*Crear lapiz*/ Pen lapiz = new Pen(Color.Green, 2); /*dibujo rectangulos*/ for (int i = 0; i < listXfloat.Count; i++) { formGraphics.DrawRectangle(lapiz, listXfloat[i] - 2, listYfloat[i] - 2, 4, 4); } if (listX.Count > 1) { /*Dibuja el poligono*/ formGraphics.DrawPolygon(lapiz, curvePoints); } label1.Text = listX.Count.ToString(); formGraphics.Dispose(); //libera recursos del sistema } } }

    el problema me le da aqui: listYfloat.Add(listYfloat[i] / Escalagrafica);

    me dice: Se produjo una excepción de tipo 'System.OutOfMemoryException'.

    sugerencia.:

    Si esta creando una raiz, asegurese de que su tamaño es correcto.

    compruebe que hay memoria suficiente para asignarla a  fines internos.

    ¿Qué me puede ocurrir?

    Gracias


    Alfonso

    sábado, 3 de noviembre de 2012 12:40
  • El problema está en el bucle. Ejecutas un bucle "for" diciéndole que llegue hasta  listXfloat.Count. Pero dentro del bucle haces listXfloat.Add(...), con lo que añade un elemento a la lista por cada vuelta del bucle. Por tanto, el "Count" va creciendo, y el bucle nunca termina. Las dos listas van creciendo, hasta que se agota la memoria disponible, y recibes el error que has mencionado.

    En resumen: para aplicar la escala el bucle no tiene que hacer un "Add" para añadir nuevos elementos a la lista, sino únicamente cambiar el valor de los elementos que ya están dentro de la lista.

    listXfloat[i] = listXfloat[i] / Escalagrafica;

    y lo mismo para la Y.

    sábado, 3 de noviembre de 2012 17:48
  • Hola de nuevo,

    Gracias Alberto ya vi lo del bucle.

    En cuanto a Walter, gracias también pero pongo el siguiente codigo y no sale nada en el groupbox.

    Pongo codigo:

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    using System.Drawing.Drawing2D;
    
    namespace WindowsFormsApplication1
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
                groupBox1_Resize(groupBox1, null);
            }
    
            List<int> listX = new List<int>();  //Ejemplo
            List<int> listY = new List<int>();  //Ejemplo
            Point[] curvePoints;
            SizeF área;
            const float margen = 20;
            
            
            
            private void button1_Click(object sender, EventArgs e)
            {
                listX.Add(int.Parse(textBox1.Text));
                listY.Add(int.Parse(textBox2.Text));
    
                /* realizas las tranformaciones sobre el array */
                Calcula();
    
                label1.Text = listX.Count.ToString();
                //groupBox1.Invalidate();
    
            }
    
    
            private void groupBox1_Paint(object sender, PaintEventArgs e)
            {
                /*Crear lapiz*/
                Pen lapiz = new Pen(Color.Green, 2);
    
                e.Graphics.TranslateTransform(margen, margen);
    
                /*dibujo rectangulos*/
                for (int i = 0; i < listX.Count; i++)
                {
                    e.Graphics.DrawRectangle(lapiz, curvePoints[i].X - 2, curvePoints[i].Y - 2, 4, 4);
                }
    
                if (listX.Count > 1)
                {
                    /*Dibuja el poligono*/
                    e.Graphics.DrawPolygon(lapiz, curvePoints);
                }
    
            }
    
            private void groupBox1_Resize(object sender, System.EventArgs e)
            {
                área = new SizeF(groupBox1.ClientRectangle.Width - margen * 2, groupBox1.ClientRectangle.Height - margen * 2);
                Calcula();
            }
    
            private void Calcula()
            {
                if (listX.Count < 1) return;
    
                //Construir array de Point con los List<int>
                curvePoints = new Point[listX.Count];
                for (int i = 0; i < listX.Count; i++)
                {
                    curvePoints[i] = new Point(listX[i], listY[i]);
                }
    
                //
                Matrix m = new Matrix();
    
                float minX = curvePoints.Min(p => p.X);
                float minY = curvePoints.Min(p => p.Y);
    
                float maxX = curvePoints.Max(p => p.X);
                float maxY = curvePoints.Max(p => p.Y);
    
                float figAncho = maxX - minX;
                float figAlto = maxY - minY;
    
                float escalaX = área.Width < figAncho ? área.Width / figAncho : 1;
                float escalaY = área.Height < figAlto ? área.Height / figAlto : 1;
    
                float trasladaX = minX < 0 || escalaX < 1 ? -minX : 0;
    
                if (trasladaX == 0 && área.Width < maxX)
                {
                    trasladaX = -minX + (área.Width - figAncho) / 2;
                }
    
                float trasladaY = minY < 0 || escalaY < 1 ? -minY : 0;
    
                if (trasladaY == 0 && área.Height < maxY)
                {
                    trasladaX = -minY + (área.Height - figAlto) / 2;
                }
    
                m.Scale(escalaX, escalaY);
                m.Translate(trasladaX, trasladaY);
                m.TransformPoints(curvePoints);
            }
    
    
        }
    }
    

    ¿Por que no sale nada cuando meto datos?

    Gracias.


    Alfonso

    lunes, 5 de noviembre de 2012 18:53
  • Te pego la versión final, separada del post anterior.

    using System.Collections.Generic;
    using System.Drawing;
    using System.Linq;
    using System.Windows.Forms;
    using System.Drawing.Drawing2D;
    
    namespace WindowsFormsApplication1
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
                groupBox1_Resize(groupBox1, null);
            }
    
            List<int> listX = new List<int>();  //Ejemplo
            List<int> listY = new List<int>();  //Ejemplo
    
            Point[] curvePoints;
            SizeF área;
            const float margen = 20;
    
            private void button1_Click(object sender, System.EventArgs e)
            {
                listX.Add(int.Parse(textBox1.Text));
                listY.Add(int.Parse(textBox2.Text));
    
                /* realizas las tranformaciones sobre el array */
                Calcula();
    
                label1.Text = listX.Count.ToString();
                groupBox1.Invalidate();
            }
    
            private void groupBox1_Paint(object sender, PaintEventArgs e)
            {
                /*Crear lapiz*/
                Pen lapiz = new Pen(Color.Green, 2);
    
                e.Graphics.TranslateTransform(margen, margen);
    
                /*dibujo rectangulos*/
                for (int i = 0; i < listX.Count; i++)
                {
                    e.Graphics.DrawRectangle(lapiz, curvePoints[i].X - 2, curvePoints[i].Y - 2, 4, 4);
                }
    
                if (listX.Count > 1)
                {
                    /*Dibuja el poligono*/
                    e.Graphics.DrawPolygon(lapiz, curvePoints);
                }
    
            }
    
            private void groupBox1_Resize(object sender, System.EventArgs e)
            {
                área = new SizeF(groupBox1.ClientRectangle.Width - margen * 2, groupBox1.ClientRectangle.Height - margen * 2);
                Calcula();
            }
    
            private void Calcula()
            {
                if (listX.Count < 1) return;
    
                //Construir array de Point con los List<int>
                curvePoints = new Point[listX.Count];
                for (int i = 0; i < listX.Count; i++)
                {
                    curvePoints[i] = new Point(listX[i], listY[i]);
                }
    
                //
                Matrix m = new Matrix();
    
                float minX = curvePoints.Min(p => p.X);
                float minY = curvePoints.Min(p => p.Y);
    
                float maxX = curvePoints.Max(p => p.X);
                float maxY = curvePoints.Max(p => p.Y);
    
                float figAncho = maxX - minX;
                float figAlto = maxY - minY;
    
                float escalaX = área.Width < figAncho ? área.Width / figAncho : 1;
                float escalaY = área.Height < figAlto ? área.Height / figAlto : 1;
    
                float trasladaX = minX < 0 || escalaX < 1 ? -minX : 0;
    
                if (área.Width < maxX && escalaX == 1)
                {
                    trasladaX = -(maxX - área.Width);
                }
    
                float trasladaY = minY < 0 || escalaY < 1 ? -minY : 0;
    
                if (área.Height < maxY && escalaY == 1)
                {
                    trasladaY = -(maxY - área.Height);
                }
    
                m.Scale(escalaX, escalaY);
                m.Translate(trasladaX, trasladaY);
                m.TransformPoints(curvePoints);
            }
    
         }
    }
    

    lunes, 5 de noviembre de 2012 19:05
  • Hola,

    Ejecuto el programa y no me da ningún error, pero introduzco puntos en los texbox y no me dibuja nada.

    ¿^Qué puede pasar?

    Gracias


    Alfonso

    lunes, 5 de noviembre de 2012 19:27