Καλώς ορίσατε στο dotNETZone.gr - Σύνδεση | Εγγραφή | Βοήθεια
σε

 

Αρχική σελίδα Ιστολόγια Συζητήσεις Εκθέσεις Φωτογραφιών Αρχειοθήκες

Γραφικά με Visual Basic 2008: επικάλυψη κειμένου για δυνατούς λύτες

Îåêßíçóå áðü ôï ìÝëïò Dataman. Τελευταία δημοσίευση από το μέλος Dataman στις 08-02-2009, 11:56. Υπάρχουν 14 απαντήσεις.
Ταξινόμηση Δημοσιεύσεων: Προηγούμενο Επόμενο
  •  04-02-2009, 10:56 48146

    Γραφικά με Visual Basic 2008: επικάλυψη κειμένου για δυνατούς λύτες

    Χαιρετώ,
    Όπως λέει και ο τίτλος είναι για δυνατούς λύτες το συγκεκριμένο πρόβλημα (τουλάχιστος έτσι το θεωρώ εγώ)

    Ας υποθέσουμε λοιπόν ότι έχουμε ένα γραφικό που προσθέτουμε κείμενο σε διάφορες θέσεις και υπό γωνία.
    Θα ήθελα ένα τρόπο έτσι ώστε κάθε νέο κείμενο που τοποθετείται στο γραφικό, να ελέγχει έαν υπάρχει άλλο στην ίδια θέση να μην το τοποθετεί. Να μην είναι δηλαδή το ένα επάνω στο άλλο.
    Τι τρόπο πρέπει να ακολουθήσω;

    Παραθέτω και παράδειγμα κώδικα (που γίνεται επικάλυψη)
    ------------------------------------------------------------------------------------------------------------------------------------------
          Dim GeneralGraph As Bitmap
          GeneralGraph = New Bitmap(PictureBox1.Width, PictureBox1.Height)

          Dim GraphTable As Bitmap
          Dim Moires(2) As Integer
          Moires(0) = 32 : Moires(1) = 240 : Moires(2) = 91

          Dim Thesi(2) As Point
          Thesi(0) = New Point(50, 50)
          Thesi(1) = New Point(120, 100)
          Thesi(2) = New Point(130, 100)

          Dim X As Integer = 0

          For X = 0 To 2

             'Σχεδίαση του κειμένου στην πρόχειρη εικόνα
             GraphTable = New Bitmap(GeneralGraph.Width, GeneralGraph.Height)
             Using gr As Graphics = Graphics.FromImage(GraphTable)

                Dim string_format As New StringFormat
                string_format.Alignment = StringAlignment.Center
                string_format.LineAlignment = StringAlignment.Center

                gr.TextRenderingHint = TextRenderingHint.AntiAliasGridFit

                gr.RotateTransform(Moires(X))

                gr.TranslateTransform(Thesi(X).X, Thesi(X).Y, Drawing2D.MatrixOrder.Append)

                gr.DrawString("Κείμενο", New Font("Arial", 22, FontStyle.Bold, GraphicsUnit.Pixel), Brushes.Black, 0, 0, string_format)

                gr.DrawImage(GraphTable, 0, 0)
             End Using

             'Προσθήκη του σχεδίου στην κεντρική εικόνα
             Using gr As Graphics = Graphics.FromImage(GeneralGraph)
                gr.DrawImage(GraphTable, 0, 0)
             End Using

          Next X

          'Εμφάνιση της κεντρικής εικόνας
          PictureBox1.Image = GeneralGraph
     --------------------------------------------------------------------------------------------------------------------------------------------------
    Αναμένω τις απαντήσεις - λύσεις σας
    Ευχαριστώ
    Δημοσίευση στην κατηγορία:
  •  04-02-2009, 13:24 48163 σε απάντηση της 48146

    Απ: Γραφικά με Visual Basic 2008: επικάλυψη κειμένου για δυνατούς λύτες

    Μπορεις να  χρησιμοποιήσεις την  Graphics.MeasureString() για να βρεις το ορθογώνιο μεσα στο οποίο είναι το κάθε κείμενο.

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




  •  04-02-2009, 21:59 48202 σε απάντηση της 48163

    Απ: Γραφικά με Visual Basic 2008: επικάλυψη κειμένου για δυνατούς λύτες

    Τελικά είναι όντως για "δυνατούς λύτες"

    nikos123:
    Μπορεις να  χρησιμοποιήσεις την  Graphics.MeasureString() για να βρεις το ορθογώνιο μεσα στο οποίο είναι το κάθε κείμενο.
    Μετά φτιαξε μια συνάρτιση για να ελέγχεις αν δύο (σε διαφορετική γωνία)  ορθογώνια επικαλύπτονται.

    Πειραματίστικα αρκετά με την Graphics.MeasureString() πριν κάνω post, αλλά δεν κατάφερα και πολλά πράγματα διότι δισκολεύτηκα γιατί το κείμενο είναι υπό γωνία.

    Μπορείς να με βοηθήσεις με την Graphics.MeasureString()? αυτό που έχεις κατα νου

    Σκέφτηκα επίσης να μετατρέψω το κέιμενο σε line και να συγκρίνω εάν οι lines τέμνονται μεταξύ του. Τι λέτε γι'αυτό?
  •  04-02-2009, 22:07 48203 σε απάντηση της 48202

    Απ: Γραφικά με Visual Basic 2008: επικάλυψη κειμένου για δυνατούς λύτες

    Πρωτού τοποθετήσεις οποιδήποτε κείμενο, μπορείς να κρατάς τις συντεταγμένες που το τοποθετείς.. Το μόνο που θα έχεις να κάνεις είναι να δεις εάν στις συντεταγμένες που θες να βάλεις το καινούργιο κείμενο, υπάρχιε ήδη ένα άλλο. Θα μπορούσες μάλιστα να φτιάξεις ένα object που κρατάει συντεταγμένες και να χρησιμοποιήσεις ένα collection το οποίο μετά μπορείς να το "filtrareis" και να checkareis ότι θες, χρησιμοποιώντας LINQ to Objects queries.
    Παναγιώτης Κεφαλίδης

    "Για να επιτύχεις, θα πρέπει το πάθος σου για την επιτυχία να είναι μεγαλύτερο απο τον φόβο σου για την αποτυχία"

    Οι απαντήσεις παρέχονται για συγκεκριμένες ερωτήσεις και χωρίς καμιά εγγύηση. Παρακαλώ διαβάστε τους όρους χρήσης.
  •  04-02-2009, 22:54 48206 σε απάντηση της 48203

    Απ: Γραφικά με Visual Basic 2008: επικάλυψη κειμένου για δυνατούς λύτες

    Panagiotis Kefalidis:
    Πρωτού τοποθετήσεις οποιδήποτε κείμενο, μπορείς να κρατάς τις συντεταγμένες που το τοποθετείς.. Το μόνο που θα έχεις να κάνεις είναι να δεις εάν στις συντεταγμένες που θες να βάλεις το καινούργιο κείμενο, υπάρχιε ήδη ένα άλλο.
    Αυτός είναι ο γενικός κανόνας.

    Panagiotis Kefalidis:
    μπορείς να κρατάς τις συντεταγμένες που το τοποθετείς.
    Αυτό ψάχνω να κάνω, αλλά αντιμετωπίζω πρόβλημα διότι δεν είναι ένα απλό ορθογώνιο, είναι κείμενο υπο γωνία. Δηλαδή ορθογώνιο υπό γωνία.

    Panagiotis Kefalidis:
    Θα μπορούσες μάλιστα να φτιάξεις ένα object που κρατάει συντεταγμένες και να χρησιμοποιήσεις ένα collection το οποίο μετά μπορείς να το "filtrareis" και να checkareis ότι θες, χρησιμοποιώντας LINQ to Objects queries.
    Μπορείς να γίνεις εδώ πιο συγκεκριμένος - αναλυτικός?
  •  05-02-2009, 10:01 48211 σε απάντηση της 48202

    Απ: Γραφικά με Visual Basic 2008: επικάλυψη κειμένου για δυνατούς λύτες

    Dataman:
    Τελικά είναι όντως για "δυνατούς λύτες"

    nikos123:
    Μπορεις να  χρησιμοποιήσεις την  Graphics.MeasureString() για να βρεις το ορθογώνιο μεσα στο οποίο είναι το κάθε κείμενο.
    Μετά φτιαξε μια συνάρτιση για να ελέγχεις αν δύο (σε διαφορετική γωνία)  ορθογώνια επικαλύπτονται.

    Πειραματίστικα αρκετά με την Graphics.MeasureString() πριν κάνω post, αλλά δεν κατάφερα και πολλά πράγματα διότι δισκολεύτηκα γιατί το κείμενο είναι υπό γωνία.

    Μπορείς να με βοηθήσεις με την Graphics.MeasureString()? αυτό που έχεις κατα νου

    Σκέφτηκα επίσης να μετατρέψω το κέιμενο σε line και να συγκρίνω εάν οι lines τέμνονται μεταξύ του. Τι λέτε γι'αυτό?


    gr.DrawString("Κείμενο", new Font("Arial", 22, FontStyle.Bold, GraphicsUnit.Pixel), Brushes.Black, 0, 0, string_format);

    SizeF sz = gr.MeasureString("Κείμενο", new Font("Arial", 22, FontStyle.Bold, GraphicsUnit.Pixel),new Point( 0, 0), string_format);



    Η sz θα σου δώσει  τo μέγιστο πλατος και ύψος το κειμενου.
    Άρα ξέρεις  Χ0, Υ0 , πλάτος, ύψος και γωνία.

     H MeasureString δινει διαφορετικα αποτελεσματα πριν και μετά το Graphics.RotateTransform() γιαυτο να την εφαρμόζεις σε μηδενικό Rotation.


    Εδώ παρουσιαζεται μια μέθοδος με κώδικα σε C για τα ορθογώνια ( testing whether two rotated rectangles intersect)
  •  05-02-2009, 10:20 48212 σε απάντηση της 48211

    Απ: Γραφικά με Visual Basic 2008: επικάλυψη κειμένου για δυνατούς λύτες

    nikos123:
    Η sz θα σου δώσει  τo μέγιστο πλατος και ύψος το κειμενου.
    Άρα ξέρεις  Χ0, Υ0 , πλάτος, ύψος και γωνία.

     H MeasureString δινει διαφορετικα αποτελεσματα πριν και μετά το Graphics.RotateTransform() γιαυτο να την εφαρμόζεις σε μηδενικό Rotation.

    Πρώτα απ'ολα ευχαριστώ για την απάντηση. Μέχρι εδώ είχα φτάσει, αλλά δισκολεύομαι στον αλγόριθμο σύγκρισης των ορθογωνίων όταν είναι υπό γωνία.
    Για παράδειγμα εάν έχουμε ένα ορθογώνιο 0,0 - 100,40 μπορώ να συγκρίνω το επόμενο. Εάν όμως αυτό είναι πχ υπο γωνία 30 μοίρες πως μπορεί να γίνει.
    Θα μου πεις τριγωνομετρία... μμμ και λέω μηπως υπάρχει πιο απλός τρόπος με VB 2008.

    Συγνώμη εάν γίνομαι κουραστικός!
  •  05-02-2009, 11:30 48215 σε απάντηση της 48212

    Απ: Γραφικά με Visual Basic 2008: επικάλυψη κειμένου για δυνατούς λύτες

    Κοιτα το link που σου έδωσα και κατέβασε το CDRR.C.
    Ο κώδικας  είναι λιγότερο απο 70 γραμμές.

    Το μόνο που χρειαζεται να κανεις είναι να βρεις το κέντρο.
    Αυτός καθε ορθογώνιο το παριστάνει με τη δομή (βάλε κλάση αν θες)

      struct  _RotRect
    {
       Point center;  //το κέντρο
       Point size ;  // Sizef  βάλε δηλαδη πλατος υψος
       float angle;
    }


    Αυτή η δομη ειναι το δικό μας PointF

    struct _Vector2D {
     float x, y;
    };









  •  05-02-2009, 13:27 48220 σε απάντηση της 48215

    Απ: Γραφικά με Visual Basic 2008: επικάλυψη κειμένου για δυνατούς λύτες

    ok κατανοητός ο τρόπος που μου λες. Με μια μικρή διαφορά όμως. Δεν γνωρίζω καθόλου C.
    Αν και βοήθησες αρκετά και πιστέυω ότι η λύση είναι στον κώδικα C που μου είπες και βέβαια εάν δεν γίνομαι καταπιεστικός θα ήθελα λίγη περισσότερη βοήθεια.

    Ευχαριστώ
  •  05-02-2009, 13:54 48224 σε απάντηση της 48220

    Απ: Γραφικά με Visual Basic 2008: επικάλυψη κειμένου για δυνατούς λύτες

    Δυστυχώς ουτε εγω ξέρω Basic.
    Αν μπορεί κάποιος ας το μεταφράσει
  •  05-02-2009, 14:27 48225 σε απάντηση της 48224

    Απ: Γραφικά με Visual Basic 2008: επικάλυψη κειμένου για δυνατούς λύτες

    nikos123:
    Δυστυχώς ουτε εγω ξέρω Basic.
    Αν μπορεί κάποιος ας το μεταφράσει

    1
    2
    3
    4
    5
    6
    7
    Structure _RotRect
    Private center As Point
    'το κέντρο
    Private size As Point
    ' Sizef βάλε δηλαδη πλατος υψος
    Private angle As Single
    End Structure


    This Business Is Binary. You are a 1 or a 0. Alive or Dead.-
  •  05-02-2009, 14:55 48226 σε απάντηση της 48225

    Απ: Γραφικά με Visual Basic 2008: επικάλυψη κειμένου για δυνατούς λύτες

    Johnnyxp64:
    nikos123:
    Δυστυχώς ουτε εγω ξέρω Basic.
    Αν μπορεί κάποιος ας το μεταφράσει

    1
    2
    3
    4
    5
    6
    7
    Structure _RotRect
    Private center As Point
    'το κέντρο
    Private size As Point
    ' Sizef βάλε δηλαδη πλατος υψος
    Private angle As Single
    End Structure



    Αλλά ο κώδικας δεν είναι μόνο αυτός.
    Ολόκληρος ο κώδικας σε C εδώ:
    ----------------------------------------------------------------
    struct _Vector2D {
     float x, y;
    };

    struct _RotRect {
     _Vector2D C;
     _Vector2D S;
     float ang;
    };

    inline void AddVectors2D(_Vector2D * v1, _Vector2D * v2)
    { v1->x += v2->x; v1->y += v2->y; }

    inline void SubVectors2D(_Vector2D * v1, _Vector2D * v2)
    { v1->x -= v2->x; v1->y -= v2->y; }

    inline void RotateVector2DClockwise(_Vector2D * v, float ang)
    {
     float t,
           cosa = cos(ang),
           sina = sin(ang);
     t = v->x; v->x = t*cosa + v->y*sina; v->y = -t*sina + v->y*cosa;
    }

    // Rotated Rectangles Collision Detection, Oren Becker, 2001
    int RotRectsCollision(_RotRect * rr1, _RotRect * rr2)
    {
     _Vector2D A, B,   // vertices of the rotated rr2
           C,      // center of rr2
           BL, TR; // vertices of rr2 (bottom-left, top-right)

     float ang = rr1->ang - rr2->ang, // orientation of rotated rr1
           cosa = cos(ang),           // precalculated trigonometic -
           sina = sin(ang);           // - values for repeated use

     float t, x, a;      // temporary variables for various uses
     float dx;           // deltaX for linear equations
     float ext1, ext2;   // min/max vertical values

     // move rr2 to make rr1 cannonic
     C = rr2->C;
     SubVectors2D(&C, &rr1->C);

     // rotate rr2 clockwise by rr2->ang to make rr2 axis-aligned
     RotateVector2DClockwise(&C, rr2->ang);

     // calculate vertices of (moved and axis-aligned := 'ma') rr2
     BL = TR = C;
     SubVectors2D(&BL, &rr2->S);
     AddVectors2D(&TR, &rr2->S);

     // calculate vertices of (rotated := 'r') rr1
     A.x = -rr1->S.y*sina; B.x = A.x; t = rr1->S.x*cosa; A.x += t; B.x -= t;
     A.y =  rr1->S.y*cosa; B.y = A.y; t = rr1->S.x*sina; A.y += t; B.y -= t;

     t = sina*cosa;

     // verify that A is vertical min/max, B is horizontal min/max
     if (t < 0)
     {
      t = A.x; A.x = B.x; B.x = t;
      t = A.y; A.y = B.y; B.y = t;
     }

     // verify that B is horizontal minimum (leftest-vertex)
     if (sina < 0) { B.x = -B.x; B.y = -B.y; }

     // if rr2(ma) isn't in the horizontal range of
     // colliding with rr1(r), collision is impossible
     if (B.x > TR.x || B.x > -BL.x) return 0;

     // if rr1(r) is axis-aligned, vertical min/max are easy to get
     if (t == 0) {ext1 = A.y; ext2 = -ext1; }
     // else, find vertical min/max in the range [BL.x, TR.x]
     else
     {
      x = BL.x-A.x; a = TR.x-A.x;
      ext1 = A.y;
      // if the first vertical min/max isn't in (BL.x, TR.x), then
      // find the vertical min/max on BL.x or on TR.x
      if (a*x > 0)
      {
       dx = A.x;
       if (x < 0) { dx -= B.x; ext1 -= B.y; x = a; }
       else       { dx += B.x; ext1 += B.y; }
       ext1 *= x; ext1 /= dx; ext1 += A.y;
      }
     
      x = BL.x+A.x; a = TR.x+A.x;
      ext2 = -A.y;
      // if the second vertical min/max isn't in (BL.x, TR.x), then
      // find the local vertical min/max on BL.x or on TR.x
      if (a*x > 0)
      {
       dx = -A.x;
       if (x < 0) { dx -= B.x; ext2 -= B.y; x = a; }
       else       { dx += B.x; ext2 += B.y; }
       ext2 *= x; ext2 /= dx; ext2 -= A.y;
      }
     }

     // check whether rr2(ma) is in the vertical range of colliding with rr1(r)
     // (for the horizontal range of rr2)
     return !((ext1 < BL.y && ext2 < BL.y) ||
          (ext1 > TR.y && ext2 > TR.y));
    }
    -------------------------------------------------------------------------------------------

    Γίνεται αυτός μετατροπή σε Visual Basic 2008?
    Πιστεύω ότι εδώ είναι η λύση. Έτσι δεν είναι nikos123 ?

    Τι λες Johnnyxp64, θα βοηθήσεις και για τον υπόλοιπο?
  •  05-02-2009, 22:18 48233 σε απάντηση της 48226

    Απ: Γραφικά με Visual Basic 2008: επικάλυψη κειμένου για δυνατούς λύτες

    Hope it works, κοιτα πιθανον να θελει να κανεις διορθωσεις δεν ξερω, δεν εχω χρονο να το δοκιμασω. αλλα καλητερα διορθωσεις απο το να το εγραφες απο το 0, 

    ελπιζω να σε βοηθησει. GL friendSmile

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    Imports System  
      
      Public Class Globals
       Public Shared Function Main(argv() As string) As Integer
       Return 0
       End Function
       Public Shared Sub AddVectors2D(ByRef v1 As _Vector2D ,ByRef v2 As _Vector2D)
       v1.x += v2.x
       v1.y += v2.y
       End Sub
       Public Shared Sub SubVectors2D(ByRef v1 As _Vector2D ,ByRef v2 As _Vector2D)
       v1.x -= v2.x
       v1.y -= v2.y
       End Sub
       Public Shared Sub RotateVector2DClockwise(ByRef v As _Vector2D ,ang As float)
       Dim t As float ,cosa As float = cos(ang),sina As float = sin(ang)
       t = v.x
       v.x = t * cosa + v.y * sina
       v.y = (-(t)) * sina + v.y * cosa
       End Sub
       Public Shared Function RotRectsCollision(ByRef rr1 As _RotRect ,ByRef rr2 As _RotRect) As Integer
       Dim A As _Vector2D = New _Vector2D(),B As _Vector2D = New _Vector2D(),C As _Vector2D = New _Vector2D(),BL As _Vector2D = New _Vector2D(),TR As _Vector2D = New _Vector2D()
       Dim ang As float = rr1.ang - rr2.ang ,cosa As float = cos(ang),sina As float = sin(ang)
       Dim t As float ,x As float ,a As float
       Dim dx As float
       Dim ext1 As float ,ext2 As float
       C = rr2.C
       SubVectors2D(C ,rr1.C)
       RotateVector2DClockwise(C ,rr2.ang)
       BL = TR = C
       SubVectors2D(BL ,rr2.S)
       AddVectors2D(TR ,rr2.S)
       A.x = (-(rr1.S.y)) * sina
       B.x = A.x
       t = rr1.S.x * cosa
       A.x += t
       B.x -= t
       A.y = rr1.S.y * cosa
       B.y = A.y
       t = rr1.S.x * sina
       A.y += t
       B.y -= t
       t = sina * cosa
       If t < 0 Then
       t = A.x
       A.x = B.x
       B.x = t
       t = A.y
       A.y = B.y
       B.y = t
       End If
       If sina < 0 Then
       B.x = -(B.x)
       B.y = -(B.y)
       End If
       If B.x > TR.x || B.x > -(BL.x) Then
       Return 0
       End If
       If t = 0 Then
       ext1 = A.y
       ext2 = -(ext1)
       End If
       Else
       x = BL.x - A.x
       a = TR.x - A.x
       ext1 = A.y
       If a * x > 0 Then
       dx = A.x
       If x < 0 Then
       dx -= B.x
       ext1 -= B.y
       x = a
       End If
       Else
       dx += B.x
       ext1 += B.y
       End If
       ext1 *= x
       ext1 /= dx
       ext1 += A.y
       End If
       x = BL.x + A.x
       a = TR.x + A.x
       ext2 = -(A.y)
       If a * x > 0 Then
       dx = -(A.x)
       If x < 0 Then
       dx -= B.x
       ext2 -= B.y
       x = a
       End If
       Else
       dx += B.x
       ext2 += B.y
       End If
    ext2 *= x
       ext2 /= dx
       ext2 -= A.y
       End If
       End If
       Return !(ext1 < BL.y && ext2 < BL.y || ext1 > TR.y && ext2 > TR.y)
       End Function
      End Class
      Public Structure _Vector2D
       Public x As float
       Public y As float
      End Structure
      Public Structure _RotRect
       Public C As _Vector2D
       Public S As _Vector2D
       Public ang As float
      End Structure


    This Business Is Binary. You are a 1 or a 0. Alive or Dead.-
  •  06-02-2009, 10:16 48239 σε απάντηση της 48233

    Απ: Γραφικά με Visual Basic 2008: επικάλυψη κειμένου για δυνατούς λύτες

    Εκτιμώ αφάνταστα την βοήθειά σας παιδιά. Θα το δοκιμάσω και θα ενημερώσω σχετικά.
  •  08-02-2009, 11:56 48285 σε απάντηση της 48239

    Απ: Γραφικά με Visual Basic 2008: επικάλυψη κειμένου για δυνατούς λύτες

    Τελικά δεν κατάφερα να αποκωδικοποιήσω τον παραπάνω κώδικα και τελικά κατέληξα στην υλοποίηση κώδικα εξ αρχής.

    Την βοήθεια την βρήκα σε αυτό το Link που πιστεύω εξηγεί ξεκάθαρα τον τρόπο και έχει και παραδείγματα. Το παραθέτω εδώ για ενημέρωση και των υπολοίπων.

    Ευχαριστώ όσους ασχολήθηκαν.
Προβολή Τροφοδοσίας RSS με μορφή XML
Με χρήση του Community Server (Commercial Edition), από την Telligent Systems