2011-02-23 6 views
2

Je travaille avec des données (comme les ondes Sin/Cosin, etc.) qui se répètent avec la fréquence M. J'ai écrit un simple contrôle d'affichage où il faut les données et peint les lignes connectées pour représenter les données dans Une belle photo. Ma question est, les données sont données où si elles sont peintes sur un bitmap, les données du quadrant 1 sont dans le quadrant 3 et les données du quadrant 2 dans le quadrant 4 (et vice versa). La bitmap est de largeur M et array.Max - array.Min.Transformations graphiques

Existe-t-il une simple transformation pour modifier les données afin qu'elles s'affichent dans les quadrants appropriés?

Répondre

3

Une bonne façon de penser est que (0,0) en coordonnées monde est divisé entre

(0,0), (width, 0), (0,height), (width, height)

qui serait (largeur/2, la hauteur/2) dans l'image de coordonnées.

De là, la transformation serait:

Data(x,y) => x = ABS(x - (width/2)), y = ABS(y - (Height/2)) 
2

Essayez d'inverser l'axe Y en utilisant

g.ScaleTransform(1, -1); 
+0

Je ne suis pas familier avec ScaleTransform. Je vais regarder dedans. Si je pouvais t'avancer, je le ferais! Mais j'ai besoin des axes x et y. Joe a fait un meilleur travail que moi pour l'expliquer. –

3

Graphics.ScaleTransform est pas une bonne idée, car cela affectera non seulement la mise en page mais dessinant lui-même (épaisseur des traits, textes et ainsi de suite).

Je vous suggère de préparer une liste de points, puis d'effectuer une transformation en utilisant la classe Matrix. C'est un petit exemple que j'ai fait pour vous, j'espère que cela vous sera utile.

private PointF[] sourcePoints = GenerateFunctionPoints(); 

    protected override void OnPaint(PaintEventArgs e) 
    { 
     base.OnPaint(e); 

     e.Graphics.Clear(Color.Black); 

     // Wee need to perform transformation on a copy of a points array. 
     PointF[] points = (PointF[])sourcePoints.Clone(); 

     // The way to calculate width and height of our drawing. 
     // Of course this operation may be performed outside this method for better performance. 
     float drawingWidth = points.Max(p => p.X) - points.Min(p => p.X); 
     float drawingHeight = points.Max(p => p.Y) - points.Min(p => p.Y); 

     // Calculate the scale aspect we need to apply to points. 
     float scaleAspect = Math.Min(ClientSize.Width/drawingWidth, ClientSize.Height/drawingHeight); 

     // This matrix transofrmation allow us to scale and translate points so the (0,0) point will be 
     // in the center of the screen. X and Y axis will be scaled to fit the drawing on the screen. 
     // Also the Y axis will be inverted. 
     Matrix matrix = new Matrix(); 
     matrix.Scale(scaleAspect, -scaleAspect); 
     matrix.Translate(drawingWidth/2, -drawingHeight/2); 

     // Perform a transformation and draw curve using out points. 
     matrix.TransformPoints(points); 
     e.Graphics.DrawCurve(Pens.Green, points); 
    } 

    private static PointF[] GenerateFunctionPoints() 
    { 
     List<PointF> result = new List<PointF>(); 

     for (double x = -Math.PI; x < Math.PI; x = x + 0.1) 
     { 
      double y = Math.Sin(x); 
      result.Add(new PointF((float)x, (float)y)); 
     } 

     return result.ToArray(); 
    } 

    protected override void OnSizeChanged(EventArgs e) 
    { 
     base.OnSizeChanged(e); 
     Invalidate(); 
    } 
+0

Merci, où avez-vous trouvé l'ensemble de données Matrix? –

+0

Oh désolé, j'ai oublié de mentionner, vous devez importer l'espace de noms System.Drawing.Drawing2D –

1

Rappelez-vous aussi que pour le dessin dans un contexte à l'échelle, si vous devez, Pen prend par exemple la largeur comme unique dans certains de ses constructeurs, ce qui signifie des fractions inversement proportionnelle peut être utilisé pour faire une compensation invariant pour la effet de ScaleTransform. MISE À JOUR: oubliez que Pen a son propre ScaleTransform local, donc les deux x peuvent être compensés.