Καθολικοί μετασχηματισμοί σε μία επιφάνεια σχεδίασης

Ένα ενδιαφέρον θέμα στα γραφικά είναι το πώς θα εφαρμόσουμε μία περιστροφή, μετακίνηση, και αλλαγή διαστάσεων σε μερικά ή όλα τα γραφικά αντικείμενα μίας επιφάνειας σχεδίασης (μίας φόρμας ή ενός picturebox για παράδειγμα). Η πρώτη περίπτωση αφορά το λεγόμενο τοπικό μετασχηματισμό ενώ η δεύτερη (που θα εξετάσουμε εδώ) επιδρά σε όλα τα σχήματα της επιφάνειας σχεδίασης.

Στο παρακάτω παράδειγμα, έχουμε βάλει ένα PictureBox εντός του οποίου σχεδιάζουμε ένα ορθογώνιο με κόκκινο χρώμα. Στη συνέχεια, εφαρμόζουμε ένα μετασχηματισμό που περιλαμβάνει : Μετακίνηση της αρχικής θέσης κατά 200 pixels δεξιότερα, περιστροφή 10 μοίρες δεξιά και σμίκρυνση στο μισό του πλάτους. Για την περίπτωση αυτή, η VB.NET παρέχει το αντικείμενο Matrix. Πρόκειται για έναν πίνακα 3x3 που αντιπροσωπεύει έναν γεωμετρικό μετασχηματισμό. Η μέθοδος Translate του αντικειμένου μας επιτρέπει να μετακινήσουμε τις αρχικές θέσεις κατά ένα ποσό στο x-άξονα ή/και στον y-άξονα, να περιστρέψουμε με τη μέθοδο Rotate, να αλλάξουμε διαστάσεις με τη μέθοδο Scale. Εσωτερικά η VB.NET κάνει αλγεβρικές πράξεις μεταξύ πινάκων (ανατρέξτε στο διαδίκτυο για περισσότερες πληροφορίες).

Αφού καθορίσουμε τις μετατροπές που επιθυμούμε μέσω του Matrix, τον εκχωρούμε, κατόπιν, στην ιδιότητα Transform του αντικειμένου Graphics που παριστάνει την επιφάνεια σχεδίασης. Αυτά πραγματοποιούνται στο γεγονός Paint της φόρμας ή ενός picturebox.

http://users.sch.gr/mouratx/VB-NET_Tips/Graphics/Images/WorldTransformation.gif

Imports System.Drawing.Drawing2D

 

Public Class Form1

Inherits System.Windows.Forms.Form

 

 

'Τί ενέργεια θα κάνει στη ρουτίνα OnPaint του PicBox.
Private Enum DrawActionEnum

 

Reset = 1
Transform = 2

 

End Enum

Dim DrawAction As DrawActionEnum = DrawActionEnum.Reset

'-----------------------------------------------------------------


'Σχεδίασε από την αρχή το γραφικό αντικείμενο.
Private Sub btnDraw_Click(ByVal sender As System.Object,_

                          ByVal e As System.EventArgs)_

    Handles btnDraw.Click

 

DrawAction = DrawActionEnum.Reset
PicBox.Refresh()

 

End Sub

'-----------------------------------------------------------------


'Σχεδίασε το γραφικό αντικείμενο με μετατροπές.
Private Sub btnTransform_Click(ByVal sender As System.Object,_

 ByVal e As System.EventArgs) _

 Handles btnTransform.Click

 

DrawAction = DrawActionEnum.Transform
PicBox.Refresh()

 

End Sub

'-----------------------------------------------------------------


'Σχεδίαση του ορθογωνίου ανάλογα με την τιμή DrawAction
Private Sub PicBox_Paint(ByVal sender As Object, _

                  ByVal e As System.Windows.Forms.PaintEventArgs) _

Handles PicBox.Paint

 

'Η περιοχή σχεδίασης του ορθογωνίου (θέση (5,50),

πλάτος 150 pixels, ύψος 100 pixels).
Dim rectDraw As Rectangle = New Rectangle(5, 50, 150, 100)


'Κόκκινο πινέλο για το γέμισμα στο εσωτερικό του.
Dim br As SolidBrush = Brushes.Red

'Σχεδίασέ το.
e.Graphics.FillRectangle(br, rectDraw)

Select Case DrawAction

Case Is = DrawActionEnum.Transform

'Όρισε το γενικό μετασχηματισμό: Μετατόπισε πιο δεξιά,
'όρισε περιστροφή 10 μοίρες δεξιόστροφα και
'σμίκρυνση 1/2 φορά στο πλάτος (κατά x-άξονα).

Dim myMatrix As New Matrix()


'Μετατόπιση κατά 200 pixels δεξιότερα, ίδιο ύψος.
myMatrix.Translate(+200, 0)

'Περιστροφή 10 μοίρες δεξιά.
myMatrix.Rotate(+10)


'Σμίκρυνση 1/2 φορά στο πλάτος (κατά x-άξονα).
myMatrix.Scale(0.5, 1)

'Εφάρμοσέ τον σε όλη την επιφάνεια σχεδίασης (γενικός μετασχημ.).
'Τα γραφικά αντικείμενα θα σχεδιαστούν πλέον
‘με βάση τις μετατροπές.
e.Graphics.Transform = myMatrix

'Ξανασχεδίασε το ορθογώνιο με τα νέα δεδομένα.
e.Graphics.FillRectangle(br, rectDraw)

End Select

End Sub

'-----------------------------------------------------------------


End Class

 

Το παράδειγμα είναι απλοϊκό. Αν υπήρχαν περισσότερα σχήματα, θα εφαρμόζονταν οι μετατροπές του Matrix σε όλα. Αν θέλαμε σε ορισμένα μόνο, θα έπρεπε να τα προσθέσουμε σε ένα αντικείμενο GraphicsPath και κατόπιν να εκχωρήσουμε στην ιδιότητα Transform το αντικείμενο Matrix. Τότε, όλα τα σχήματα του GraphicsPath θα μετασχηματίζονταν (τοπικός μετασχηματισμός).

 

 

·        Χρήστος Μουρατίδης