2010-11-30 17 views
3

J'essaie de créer un canevas pour dessiner différents objets. J'ai créé des fonctions de zoom et de panoramique en utilisant graphics.scaleTransform et graphics.translateTransform, mais je ne veux pas que l'arrière-plan de la toile (une grille) remplisse la totalité de la fenêtre, mais ce n'est pas le cas:Comment puis-je dessiner n'importe où dans un objet graphique après sa transformation

EDIT: J'ai essayé d'utiliser les coordonnées dans l'objet graphique transformé, mais il semble qu'il n'acceptera pas les nombres négatifs?!?

EDIT: Cette image explique mon problème:

alt text

public partial class Form1 : Form 
     { 

      PointF mouseDown; 

      float newX; 
      float newY; 
      float zoomFactor = 1F; 

      Region _rgn; 
      Graphics _dc; 
      PointF zoomPoint = new PointF(150, 150); 

      public Form1() 
      { 
       InitializeComponent(); 

       mouseDown = new PointF(0F, 0F); 

       this.panel1.Paint += new PaintEventHandler(panel1_Paint); 
       this.panel1.MouseDown += new System.Windows.Forms.MouseEventHandler(panel1_MouseDown); 
       this.panel1.MouseMove += new System.Windows.Forms.MouseEventHandler(panel1_MouseMove); 

      } 



      private void panel1_Paint(object sender, PaintEventArgs e) 
      { 

       base.OnPaint(e); 

       //Graphics bg = 

       Graphics dc = e.Graphics; 
       _dc = dc; 

       dc.SmoothingMode = SmoothingMode.AntiAlias; 

Color gridColor = Color.FromArgb(230, 230, 230); 
      Pen gridPen = new Pen(gridColor, 1); 

      for (float i = 0; i < this.Height * (zoomFactor); i = i + 30*zoomFactor) 
      { 
       dc.DrawLine(gridPen, 0, i, this.Width * (zoomFactor), i); 
      } 
      for (float i = 0; i < this.Width * (zoomFactor); i = i + 30*zoomFactor) 
      { 
       dc.DrawLine(gridPen, i, 0, i, this.Height * (zoomFactor)); 
      } 

       dc.TranslateTransform(newX, newY); 
       dc.ScaleTransform(zoomFactor, zoomFactor, MatrixOrder.Prepend); 



       float XPosition = 10; 
       float YPosition = 10; 
       float CornerRadius = 5; 
       float Width = 50; 
       float Height = 50; 

       Color BoxColor = Color.FromArgb(0, 0, 0); 
       Pen BoxPen = new Pen(BoxColor, 2); 

       GraphicsPath Path = new GraphicsPath(); 

       Path.AddLine(XPosition + CornerRadius, YPosition, XPosition + Width - (CornerRadius * 2), YPosition); 
       Path.AddArc(XPosition + Width - (CornerRadius * 2), YPosition, CornerRadius * 2, CornerRadius * 2, 270, 90); 
       Path.AddLine(XPosition + Width, YPosition + CornerRadius, XPosition + Width, YPosition + Height - (CornerRadius * 2)); 
       Path.AddArc(XPosition + Width - (CornerRadius * 2), YPosition + Height - (CornerRadius * 2), CornerRadius * 2, CornerRadius * 2, 0, 90); 
       Path.AddLine(XPosition + Width - (CornerRadius * 2), YPosition + Height, XPosition + CornerRadius, YPosition + Height); 
       Path.AddArc(XPosition, YPosition + Height - (CornerRadius * 2), CornerRadius * 2, CornerRadius * 2, 90, 90); 
       Path.AddLine(XPosition, YPosition + Height - (CornerRadius * 2), XPosition, YPosition + CornerRadius); 
       Path.AddArc(XPosition, YPosition, CornerRadius * 2, CornerRadius * 2, 180, 90); 

       Path.CloseFigure(); 



       LinearGradientBrush lgb = new LinearGradientBrush(new PointF(XPosition+(Width/2),YPosition), new PointF(XPosition+(Width/2),YPosition + Height), Color.RosyBrown, Color.Red); 

       dc.FillPath(lgb, Path); 


       dc.DrawPath(BoxPen, Path); 

       Matrix transformMatrix = new Matrix(); 
       transformMatrix.Translate(newX, newY); 
       transformMatrix.Scale(zoomFactor, zoomFactor); 

       _rgn = new Region(Path); 

       _rgn.Transform(transformMatrix); 

      } 

      private void panel1_MouseDown(object sender, EventArgs e) 
      { 
       MouseEventArgs mouse = e as MouseEventArgs; 

       if (mouse.Button == MouseButtons.Right) 
       { 

        mouseDown = mouse.Location; 

        mouseDown.X = mouseDown.X - newX; 
        mouseDown.Y = mouseDown.Y - newY; 

       } 

       else if (mouse.Button == MouseButtons.Left) 
       { 

        if (_rgn.IsVisible(mouse.Location, _dc)) 
        { 
         MessageBox.Show("tada"); 
        } 


       } 

      } 

      private void panel1_MouseMove(object sender, EventArgs e) 
      { 
       MouseEventArgs mouse = e as MouseEventArgs; 

       if (mouse.Button == MouseButtons.Right) 
       { 
        PointF mousePosNow = mouse.Location; 

        float deltaX = mousePosNow.X - mouseDown.X; 
        float deltaY = mousePosNow.Y - mouseDown.Y; 

        newX = deltaX; 
        newY = deltaY; 

        panel1.Invalidate(); 

       } 


      } 

      protected override void OnMouseWheel(MouseEventArgs e) 
      { 

       MouseEventArgs mouse = e as MouseEventArgs; 

       PointF mP = mouse.Location; 

       if (e.Delta > 0) 
       { 
        if (zoomFactor >= 1 && zoomFactor <= 10) 
        { 
         zoomFactor += 1F; 

         newX = newX - ((mP.X - newX)/(zoomFactor - 1)); 
         newY = newY - ((mP.Y - newY)/(zoomFactor - 1)); 
        } 
        else if (zoomFactor == 0.5) 
        { 
         zoomFactor = zoomFactor * 2; 
         newX = 2 * newX - mP.X ; 
         newY = 2 * newY - mP.Y ; 
        } 
        else if (zoomFactor < 0.5) 
        { 
         zoomFactor = zoomFactor * 2; 
         newX = 2 * newX - mP.X; 
         newY = 2 * newY - mP.Y; 
        } 
       } 

       else if (e.Delta < 0) 
       { 
        if (zoomFactor >2) 
        { 
         zoomFactor -= 1F; 
         newX = newX + (((mP.X - newX))/(zoomFactor+1)); 
         newY = newY + (((mP.Y - newY))/(zoomFactor+1)); 
        } 
        else if (zoomFactor == 2) { 
         zoomFactor -= 1F; 

         newX = newX + ((mP.X - newX)/2); 
         newY = newY + ((mP.Y - newY)/2); 
        }else if(zoomFactor <= 1 && zoomFactor > 0.2) 
        { 
         zoomFactor = zoomFactor/2; 

         newX = newX + ((mP.X - newX)/2); 
         newY = newY + ((mP.Y - newY)/2); 

        } 


       } 

       panel1.Invalidate(); 

      } 
     } 
+0

+1 pour le montage dans l'image. –

Répondre

2

Dessiner votre grille avant de transformer le système de coordonnées.

Si vous ne le pouvez pas, utilisez GetTransform() et ResetTransform(), puis dessinez la grille, puis retournez SetTransform (celui qui a été obtenu dans la première étape).

IMHO: Il serait beaucoup mieux si vous redimensionnez votre image «manuellement» au lieu d'utiliser la transformation de coordonnées. Vous aurez beaucoup plus de contrôle de cette façon, et ne frapperez pas le mur avec quoi que ce soit.

EDIT:

aussi: vous avez un bug dans votre grille de dessin de routine:

for (float i = 0; i < this.Height * (zoomFactor); i = i + 30*zoomFactor) 

essayez de remplacer avec

for (float i = 0; i < this.Height; i = i + 30*zoomFactor) 
+0

@Daniel - que voulez-vous dire par mise à l'échelle manuellement? que je redimensionne l'objet individuel sur la toile? – Bildsoe

+0

@Daniel - Oh, et je dessine la grille avant la mise à l'échelle, mais quand je la redimensionne, elle n'est pas assez grande, surtout quand je fais du zoom et du panoramique. – Bildsoe

+0

oui, mettez à l'échelle et déplacez-les manuellement. que voulez-vous dire - pas assez grand? aussi, à partir de votre code, il semble que vous ne dessinez pas de grille avant la transformation ... peut-être si vous pouvez produire une image de 'C'EST COMMENT JE VEUX' et 'C'EST COMME C'EST MAINTENANT' –