none
Cambiar origen de coordenadas en Graphics RRS feed

  • Pregunta

  • Hola estoy trabajando con visual C# 2010 express.

    Estoy dibujando algunos puntos con coordenadas X e Y en sistema cartesiano en un graphics, el problema que tengo es que el origen en visual C# esta en la esquina superior izquierda (es decir las coordenadas 0,0 para la X y la Y están en esa esquina) y yo quiero que el origen de coordenadas este en la esquina inferior izquierda (es decir las coordenadas 0,0 ), ¿como puedo hacer para cambiar el origen a esa esquina?,  ademas el incremento de coordenadas en Y es hacia abajo y yo lo quiero hacia arriba según miramos el cuadro.

    en resumen, ¿Cómo cambiar el origen de las coordenadas de la esquina superior izquierda a la esquina inferior izquierda y el incremento de las Y que vaya hacia abajo?

    Gracias

    domingo, 31 de marzo de 2013 19:29

Respuestas

  • Puedes pedir al Graphics que te entregue el dc de la ventana y modificar el origen de las coordenadas (SetWindowOrgEx) y el mapeo (SetMapMode). El punto es que no puedes usar los métodos de la clase Graphics mientras estés ocupando el dc. Y si haces el ReleaseDC, Graphics ignora el mapeo y el origen puesto. Osea, debes usar las funciones del gdi para dibujar tus puntos en la pantalla. Lo que no es ningún drama.
    O simplemente puedes usar TranslateTransform() para mover el origen, e invertir el signo de la ordenada en cada uno de tus puntos, cuando los pasas como argumentos. Por ejemplo,

    using System.Drawing;
    using System.Windows.Forms;
    
    namespace WindowsFormsApplication1
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }
    
            private Point[] pts = { new Point(14, 27), new Point(123, 204), new Point(200, 100) };
            private const int radio = 2;
            private const int lado = 2 * radio;
    
            private void Form1_Paint(object sender, PaintEventArgs e)
            {
                e.Graphics.TranslateTransform(0, ClientSize.Height);
    
                foreach (Point item in pts)
                {
                    e.Graphics.DrawEllipse(Pens.Blue, item.X - radio, -item.Y + radio, lado, lado);
                    e.Graphics.DrawString(item.ToString(), Font, Brushes.ForestGreen, item.X + lado, -item.Y); 
                }
    
            }
    
            private void Form1_Resize(object sender, EventArgs e)
            {
                Refresh();
            }
        }
    }
    
    

    • Marcado como respuesta cutuche lunes, 1 de abril de 2013 17:41
    domingo, 31 de marzo de 2013 20:32

Todas las respuestas

  • Puedes pedir al Graphics que te entregue el dc de la ventana y modificar el origen de las coordenadas (SetWindowOrgEx) y el mapeo (SetMapMode). El punto es que no puedes usar los métodos de la clase Graphics mientras estés ocupando el dc. Y si haces el ReleaseDC, Graphics ignora el mapeo y el origen puesto. Osea, debes usar las funciones del gdi para dibujar tus puntos en la pantalla. Lo que no es ningún drama.
    O simplemente puedes usar TranslateTransform() para mover el origen, e invertir el signo de la ordenada en cada uno de tus puntos, cuando los pasas como argumentos. Por ejemplo,

    using System.Drawing;
    using System.Windows.Forms;
    
    namespace WindowsFormsApplication1
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }
    
            private Point[] pts = { new Point(14, 27), new Point(123, 204), new Point(200, 100) };
            private const int radio = 2;
            private const int lado = 2 * radio;
    
            private void Form1_Paint(object sender, PaintEventArgs e)
            {
                e.Graphics.TranslateTransform(0, ClientSize.Height);
    
                foreach (Point item in pts)
                {
                    e.Graphics.DrawEllipse(Pens.Blue, item.X - radio, -item.Y + radio, lado, lado);
                    e.Graphics.DrawString(item.ToString(), Font, Brushes.ForestGreen, item.X + lado, -item.Y); 
                }
    
            }
    
            private void Form1_Resize(object sender, EventArgs e)
            {
                Refresh();
            }
        }
    }
    
    

    • Marcado como respuesta cutuche lunes, 1 de abril de 2013 17:41
    domingo, 31 de marzo de 2013 20:32
  • Gracias Walter es lo que buscaba.

    Pero al hilo de esta solución me surge un nuevo problema que no se como resolverlo.

    Yo represento los puntos sobre un group-box y el ancho y alto es de 400 * 600 (el tamaño de la ventana del group-box es de 400 * 600), cuando represento puntos que estan a una distancia mayor de esos 600 se salen fuera y no los veo.

    ¿Cómo podría hacer para verlos?

    Supongo que tendría que escalar el group-box para que se viesen todos los puntos.

    ¿Pero como lo hago?

    Gracias 

    lunes, 1 de abril de 2013 19:44
  • Si tu problema es sólo el eje x, puedes modificar la escala así

    using System.Drawing;
    using System.Windows.Forms;
    using System;
    using System.Linq;
    
    namespace WindowsFormsApplication1
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }
    
            private Point[] pts = { new Point(14, 27), new Point(123, 204), new Point(200, 100), new Point(530, 212) };
            private const int radio = 2;
            private const int lado = 2 * radio;
    
            private float m_escala;
    
            private void Form1_Paint(object sender, PaintEventArgs e)
            {
                e.Graphics.TranslateTransform(0, ClientSize.Height);
                e.Graphics.ScaleTransform(m_escala, 1F);
    
                foreach (Point item in pts)
                {
                    e.Graphics.DrawEllipse(Pens.DarkMagenta, item.X - radio, -item.Y + radio, lado, lado);
                }
    
            }
    
            private void Form1_Resize(object sender, EventArgs e)
            {
                m_escala = CalculaEscala();
                Refresh();
            }
    
            private void Form1_Load(object sender, EventArgs e)
            {
                m_escala = CalculaEscala();
            }
    
            private float CalculaEscala()
            {
                float escala_X = 1F * ClientSize.Width / (pts.Max(p => p.X) + 10);
                
                return escala_X < 1F ? escala_X : 1F;
            }
        }
    }
    

    Supongo que conoces el control chart y tienes buenos motivos para no usarlo.

    martes, 2 de abril de 2013 0:31
  • Hola de nuevo,

    No conocia el control chart, le estado hechando un vistazo y creo que es la mejor solución.

    Tengo un problema, estoy empezando con el control y cuando ejecuto el programa (iniciar depuración), me aparece en pantalla unos puntos que yo he metido y una linea que une esos puntos como yo he programado pero...

    Me aparece una cuadricula  junto a los puntos y líneas que yo he creado ¿Cómo edito esa cuadricula a mi gusto?

    Gracias

    martes, 2 de abril de 2013 11:40