Announcement

Collapse
No announcement yet.

Zeichenfläche

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Zeichenfläche

    Hallo!

    Hab da ein kleines Problem. Ist mir aber sehr wichtig.

    Also, ich habe eine Zeichenfläche (rechteckig), auf der ich verschiedene Linien und

    Rechtecke zeichne.
    Das klappt alles sehr gut. Nun will ich auf dieser Zeichenfläche ein Zoom-Rechteck

    aufziehen. Das klappt auch ohne Probleme. Die Koordinaten für das Zoom-Rechteck und die

    Koordinaten des Zeichenrechteckes sind mir auch bekannt.
    Es ist nun so, das verschiedene Linen und Rechtecke inerhalb meines Zoomrechteckes liegen,

    oder auch manche halt nicht.
    Wie schaffe ich es nun, die Koordinaten meiner Elemente (Linien und Rechtecke) so

    umzurechnen, das nur die auf meiner Zeichenfläche gezeichnet werden, die auch in meinem

    Zoomrechteck liegen ??

    Irgendwie muss ich die X und Y Koordinaten der Elemente anpassen, sodass sie entweder

    ausserhalb der Zeichenfläche gezeichnet werden (Nicht im Zoom-Rect) oder halt auf die

    Grösse der Zeichenfläche angepasst (innerhalb Zoom-Rect).

    Foffe es ist soweit klar, was ich möchte. Alles was im Zoomrechteck ist, muss auf die

    Grösse der Zeichenfläche umgerechnet werden.

    Danke für Eure Hilfe.

  • #2
    <html>

    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
    <meta name="GENERATOR" content="Microsoft FrontPage 4.0">
    <meta name="ProgId" content="FrontPage.Editor.Document">
    <title>Neue Seite 1</title>
    </head>

    <body>

    <p>Stell Dir Deine Zeichenfläche vollkommen losgelöst vom Bildschirm vor. Du hast ein X/Y-Koordinatensystem und kannst auf diesem von -unendlich
    bis +unendlich zeichnen. Unendlich ist dabei nur durch das verwendete Zahlenformat
    (int, float, double) begrenzt.</p>
    <p>Dann hast Du Deine Bildschirm-Zeichenfläche, die nur mit Integer arbeiten
    kann, und auch nur irgendeinen kleinen Ausschnitt aus Deiner großen Zeichnung
    darstellen kann. X=0 und Y=0 ist die obere linke Ecke, der Y-Wert ist nach unten
    zeigend positiv, genau entgegengesetzt zum Koordinatensystem.</p>
    <p>Den Versatz Deines Koordinatensystem zur Bildschirmkoordinate speicherst Du
    in den beiden globalen Variablen xMitte und yMitte. Und dann hast Du noch die
    globale Variable zoom, mit der Du Dein Bild vergrößern oder verkleinern
    kannst.&nbsp;</p>
    <p>Um eine Linie zu zeichnen, brauchst Du dann diese Funktion (die ist in C++
    geschrieben, mit C# bzw. .net hab ich das noch nicht gemacht):</p>
    <pre>
    void __fastcall TForm1::Linie(float x1, float y1, float x2, float y2)
    {
    float xa=xMitte+x1*zoom;
    float ya=yMitte-y1*zoom;
    float xb=xMitte+x2*zoom;
    float yb=yMitte-y2*zoom;
    Canvas-&gt;MoveTo((int) xa,(int) ya);
    Canvas-&gt;LineTo((int) xb,(int) yb);
    }</pre>
    <p>Und darüber, ob die Linie ganz oder teilweise außerhalb des
    Bildschirmfensters liegen könnte, würde ich mir keine Gedanken machen. Das
    erledigt Windows (oder das Framework?).</p>
    <p>Gruß, Günther</p>

    </body>

    </html&gt
    Günther

    Comment


    • #3
      Könntest Du mir nochmal erklären, was Du genau mit Versatz meines Koordinaten-Systems zur Bilschirmkoordinate meinst ? Wie berechnet man diesen ?

      Danke
      Bod

      Comment


      • #4
        <html>

        <head>
        <meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
        <meta name="GENERATOR" content="Microsoft FrontPage 4.0">
        <meta name="ProgId" content="FrontPage.Editor.Document">
        <title>Neue Seite 1</title>
        </head>

        <body>

        <p>Du kannst Dein Programm zunächst so aufbauen:</p>
        <pre>float xMitte=0.0;
        float yMitte=0.0;
        float zoom=1.0;</pre>
        <p>Selbstverständlich kannst Du auch mit beliebigen anderen Werten
        initialisieren.&nbsp;</p>
        <p>Dann läßt Du Dir was einfallen, wie Du die Werte verändern willst. Der
        nachstehende Code verändert beim Ziehen mit der Maus und gedrückter Maustaste
        die Werte von xMitte und yMitte, und verschiebt somit den sichtbaren Ausschnitt
        auf der Zeichnung. Um die Sache übersichtlich zu halten, wird jetzt noch nicht
        abgefragt, welche Maustaste, und eventuell welche Taste zusätzlich auf der
        Tastatur gedrückt wurde. Mit einer anderen Maustaste könnte man z.B. die
        Zoomfunktion steuern. Und wieder C++Builder-Code:</p>
        <pre>//---------------------------------------------------------------------------
        int mx,my; // letzte Mausposition
        int Status=0; // Flag, ob Verschiebefunktion aktiv sein soll
        //---------------------------------------------------------------------------
        void __fastcall TForm1::FormMouseDown(TObject *Sender, TMouseButton Button,
        TShiftState Shift, int X, int Y)
        {
        mx=X;
        my=Y;
        Status=1;
        }
        //---------------------------------------------------------------------------
        void __fastcall TForm1::FormMouseUp(TObject *Sender, TMouseButton Button,
        TShiftState Shift, int X, int Y)
        {
        Status=0;
        }
        //---------------------------------------------------------------------------
        void __fastcall TForm1::FormMouseMove(TObject *Sender, TShiftState Shift,
        int X, int Y)
        {
        if(Status==1)
        {
        xMitte=xMitte-mx+X;
        yMitte=yMitte-my+Y;
        mx=X;
        my=Y;
        Invalidate();
        }
        }
        //---------------------------------------------------------------------------
        </pre>

        </body>

        </html&gt
        Günther

        Comment


        • #5
          Hallo !

          Irgendwie funktioniert das nicht so ganz. Zumindest nicht bei ersten schieben.

          Wenn ich ein Line habe, die von links oben nach rechts unten verläuft, dann wird sie nach dem ersten Schieben gedreht. Sie läuft dann von links unten nach rechts oben.

          Ausserdem stimmt die Zeichenposition der Linie nach dem ersten zeichnen nicht mehr. Sie wird nach oben verschoben, obwohl nach unten gezogen wird.
          Alle weiteren Schiebeaktivitäten funktionieren

          Comment


          • #6
            Das hängt damit zusammen, daß die Y-Achse auf Fenster-Zeichenfläche von oben nach unten, im normalen Koordinatensystem von unten nach oben läuft. Da vertut man sich dann immer wieder mal. Ändere mal die Zeile yMitte=yMitte-my+Y; in yMitte=yMitte+my-Y
            Günther

            Comment


            • #7
              Jetzt geht es gar nicht mehr.
              Hier mal mein Code:
              <Pre>
              private void button1_Click(object sender, System.EventArgs e)
              {
              Draw();
              }

              private void Form1_Load(object sender, System.EventArgs e)
              {
              gr = Graphics.FromHwnd(panel.Handle);
              }

              private void Draw()
              {
              // gr.DrawRectangle(new Pen(Color.Green),30,30,30,30);
              int X1=100;
              int Y1=100;
              int X2=80;
              int Y2=80;

              if ((yMitte != 0) || (xMitte != 0))
              gr.DrawLine(new Pen(Color.Green),xMitte +X1* Zoom,yMitte-Y1*Zoom,xMitte+X2*Zoom,yMitte-Y2*Zoom);
              else
              gr.DrawLine(new Pen(Color.Green),100,100,80,80);
              }

              private void panel_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
              {
              bClicked = true;
              mx=e.X;
              my=e.Y;
              }

              private void panel_MouseUp(object sender, System.Windows.Forms.MouseEventArgs e)
              {
              //gr.Clear(Color.Gray);
              Draw();
              }

              private void panel_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e)
              {
              if (bClicked)
              {
              xMitte=xMitte-mx+e.X;
              yMitte=yMitte+my-e.Y;
              mx=e.X;
              my=e.Y;
              }
              }
              </pre&gt

              Comment


              • #8
                <html>

                <head>
                <meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
                <meta name="GENERATOR" content="Microsoft FrontPage 4.0">
                <meta name="ProgId" content="FrontPage.Editor.Document">
                <title>Neue Seite 1</title>
                </head>

                <body>

                <p>Ich hab jetzt mal versucht, den Code in C# zu übersetzen. Wenn der Wert von
                yMitte mit 0 initialisiert wird, dann kann man normalerweise nichts sehen, weil
                man ja normalerweise im 1. Quadranten malen möchte. Also, yMitte sollte etwas
                größer sein. So wie ich die Vorzeichen jetzt habe, funktioniert es richtig.</p>
                <pre>int mx,my;
                int Status=0;
                float xMitte=0.0F;
                float yMitte=100.0F;
                float zoom=1.0F;

                private void Linie(float x1, float y1, float x2, float y2, System.Windows.Forms.PaintEventArgs e, Pen P)
                {
                int ix1=(int)(xMitte+x1*zoom);
                int ix2=(int)(xMitte+x2*zoom);
                int iy1=(int)(yMitte-y1*zoom);
                int iy2=(int)(yMitte-y2*zoom);
                Point point1 = new Point(ix1,iy1);
                Point point2 = new Point(ix2,iy2);
                e.Graphics.DrawLine(P,point1,point2);
                }
                private void WinForm_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
                {
                Pen blackPen = new Pen(Color.Black, 3);
                Linie(10,10,120,30,e,blackPen);
                }
                private void WinForm_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
                {
                mx=e.X;
                my=e.Y;
                Status=1;
                }
                private void WinForm_MouseUp(object sender, System.Windows.Forms.MouseEventArgs e)
                {
                Status=0;
                }
                private void WinForm_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e)
                {
                if(Status==1)
                {
                xMitte=xMitte-mx+e.X;
                yMitte=yMitte-my+e.Y;
                mx=e.X;
                my=e.Y;
                Invalidate();
                }
                }</pre>

                Edit: Deinen Beitrag von 17:16 hatte ich noch nicht gesehen, als ich diesen hier gepostet habe.
                </body>

                </html&gt
                Günther

                Comment


                • #9
                  Die Abfrage

                  if ((yMitte != 0) || (xMitte != 0))

                  hat da nix zu suchen
                  Günther

                  Comment


                  • #10
                    Soo, hab noch ein wenig rumprobiert und nun scheint es mit dem Verschieben zu klappen. Hier mein abgeänderter Code:
                    <pre>
                    private void Draw()
                    {
                    // gr.DrawRectangle(new Pen(Color.Green),30,30,30,30);
                    int X1=400;
                    int Y1=400;
                    int X2=60;
                    int Y2=60;

                    if ((yMitte != 0) || (xMitte != 0))
                    gr.DrawLine(new Pen(Color.Green),xMitte -X1* Zoom,yMitte-Y1*Zoom,xMitte-X2*Zoom,yMitte-Y2*Zoom);
                    else
                    gr.DrawLine(new Pen(Color.Green),400,400,60,60);
                    }

                    private void Form1_Load(object sender, System.EventArgs e)
                    {
                    gr = Graphics.FromHwnd(panel.Handle);
                    }

                    private void panel_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
                    {
                    bClicked = true;
                    //Zoomrect = new Rectangle(e.X,e.Y,0,0);
                    StartX =e.X;
                    StartY =e.Y;
                    //gr.DrawRectangle(new Pen(new HatchBrush(HatchStyle.DottedGrid,Color.Black)),e.X ,e.Y,0,0);
                    }

                    private void panel_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e)
                    {
                    if (bClicked)
                    {
                    /*
                    yMitte = yMitte - StartY + e.Y;
                    xMitte = xMitte - StartX + e.X;
                    StartX = e.X;
                    StartY = e.Y;

                    Zoomrect.Width = e.X-StartX;
                    Zoomrect.Height = e.Y-StartY;*/
                    gr.Clear(Color.Red);
                    //gr.DrawRectangle(new Pen(new HatchBrush(HatchStyle.DottedGrid,Color.Black)),Zoo mrect);
                    }
                    }

                    private void panel_MouseUp(object sender, System.Windows.Forms.MouseEventArgs e)
                    {
                    bClicked = false;
                    //xMitte = 1;

                    if (xMitte != 0)
                    xMitte = xMitte - StartX + e.X;
                    else
                    xMitte = e.X + StartX;

                    if (yMitte != 0)
                    yMitte = yMitte - StartY + e.Y;
                    else
                    yMitte = e.Y + StartY;/*
                    */
                    //xMitte= (panel.Width / 2) - (Zoomrect.X + (Zoomrect.Width / 2));

                    //yMitte= (panel.Height / 2)- (Zoomrect.Y + (Zoomrect.Height / 2));
                    //CalcZoom();
                    StartX = e.X;
                    StartY = e.Y;
                    Draw();
                    }

                    private void button2_Click(object sender, System.EventArgs e)
                    {
                    gr.Clear(panel.ForeColor);
                    xMitte = 0;
                    yMitte = 0;
                    Zoom = 1;
                    }

                    </pre>

                    Bin mal gespannt, ob das auch mit Rechtecken und Polygonen klappt.

                    Nochmal vielen Dank. Werde mich dann mal ans Zoomen machen. Da brauch ich bestimmt auch nochmal Deine Hilfe.

                    Gruss
                    Bod

                    Comment


                    • #11
                      Hallo !

                      Scheint auch mit Rechtecken 1a zu klappen.
                      Nun noch meine Frage zu dem Zoomrechteck. Könntest Du mir da auch ein Beispiel geben ??

                      Danke nochmal für Deine Geduld mit mir.
                      Bod

                      Comment


                      • #12
                        <html>

                        <head>
                        <meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
                        <meta name="GENERATOR" content="Microsoft FrontPage 4.0">
                        <meta name="ProgId" content="FrontPage.Editor.Document">
                        <title>Neue Seite 1</title>
                        </head>

                        <body>

                        <p>Ein Beispiel für ein Zoom-Rechteck hab ich im Moment nicht. Aber einen
                        dynamischen Zoom kann ich anbieten:</p>
                        <pre>private void WinForm_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
                        {
                        mx=e.X;
                        my=e.Y;
                        if(e.Button==MouseButtons.Left) Status=1;
                        if(e.Button==MouseButtons.Right) Status=2;
                        }
                        private void WinForm_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e)
                        {
                        if(Status==1)
                        {
                        xMitte=xMitte-mx+e.X;
                        yMitte=yMitte-my+e.Y;
                        mx=e.X;
                        my=e.Y;
                        Invalidate();
                        }
                        else if(Status==2)
                        {
                        int dx=e.X-mx;
                        int dy=my-e.Y;
                        float z=1.0F;
                        if((dx&gt;0)&amp;(dy>0))
                        {
                        if(zoom&lt;50.0)
                        {
                        if((dx&gt;1)|(dy&gt;1)) z=1.01F;
                        if((dx&gt;5)|(dy&gt;5)) z=1.05F;
                        }
                        }
                        else
                        {
                        if(zoom>0.2)
                        {
                        if((dx&lt;-1)|(dy&lt;-1)) z=0.99F;
                        if((dx&lt;-5)|(dy&lt;-5)) z=0.95F;
                        }
                        }
                        if(z!=1.0)
                        {
                        zoom=zoom*z;
                        Invalidate();
                        }
                        mx=e.X;
                        my=e.Y;
                        }
                        }</pre>

                        </body>

                        </html&gt
                        Günther

                        Comment


                        • #13
                          Danke. Jedoch brauch ich ein Rechteck

                          Comment


                          • #14
                            <html>

                            <head>
                            <meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
                            <meta name="GENERATOR" content="Microsoft FrontPage 4.0">
                            <meta name="ProgId" content="FrontPage.Editor.Document">
                            <title>Neue Seite 1</title>
                            </head>

                            <body>

                            <p>So ganz passt die Berechnung im WinForm_MouseUp noch nicht. Aber ein wenig
                            kannst Du ja selbst anpassen.</p>
                            <pre><span style="background-color: #FFFF00">int MausRechteckBreite,MausRechteckHoehe;</span></pre>
                            <p> private void WinForm_Paint(object sender, System.Windows.Forms.PaintEventArgs e)<br>
                            {<br>
                            &nbsp;&nbsp; Pen myPen = new Pen(Color.Black, 3);<br>
                            &nbsp;&nbsp; Linie(10,10,120,30,e,myPen);<br>
                            &nbsp;&nbsp; Rechteck(10,10,120,30,e,myPen);<br>
                            &nbsp;&nbsp; Kreis(10,10,10,e,myPen);<br>
                            &nbsp;&nbsp; Bogen(10,10,20,90,180,e,myPen);<br>
                            &nbsp;&nbsp; <span style="background-color: #FFFF00">if(Status==3)<br>
                            &nbsp;&nbsp; {<br>
                            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; myPen.Color=Color.Red;<br>
                            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; e.Graphics.DrawRectangle(myPen,<br>
                            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mx-MausRechteckBreite/2,my-MausRechteckHoehe/2,<br>
                            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MausRechteckBreite,MausRechteckHoehe);<br>
                            &nbsp;&nbsp; }</span><br>
                            &nbsp;&nbsp; myPen.Color=Color.Yellow;<br>
                            &nbsp;&nbsp; myPen.Width=1;<br>
                            &nbsp;&nbsp; Linie(0,-10000,0,10000,e,myPen);<br>
                            &nbsp;&nbsp; Linie(-10000,0,10000,0,e,myPen);<br>
                            }<br>
                            private void WinForm_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)<br>
                            {<br>
                            &nbsp; mx=e.X;<br>
                            &nbsp; my=e.Y;<br>
                            &nbsp; if(e.Button==MouseButtons.Left) Status=1;<br>
                            &nbsp; if(e.Button==MouseButtons.Right) Status=2;<br>
                            &nbsp; <span style="background-color: #FFFF00">if(e.Button==MouseButtons.Middle)<br>
                            &nbsp; {<br>
                            &nbsp;&nbsp;&nbsp;&nbsp; Status=3;<br>
                            &nbsp;&nbsp;&nbsp;&nbsp; MausRechteckBreite=0;<br>
                            &nbsp;&nbsp;&nbsp;&nbsp; MausRechteckHoehe=0;<br>
                            &nbsp;&nbsp; }</span><br>
                            }<br>
                            private void WinForm_MouseUp(object sender, System.Windows.Forms.MouseEventArgs e)<br>
                            {<br>
                            &nbsp;&nbsp; <span style="background-color: #FFFF00">if(Status==3)<br>
                            &nbsp;&nbsp; {<br>
                            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(MausRechteckBreite>0)<br>
                            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>
                            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&n bsp;&nbsp; xMitte=mx+xMitte;<br>
                            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&n bsp;&nbsp; yMitte=yMitte+my;<br>
                            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&n bsp;&nbsp; zoom=zoom*this.Width/MausRechteckBreite;<br>
                            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;<br>
                            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Invalidate();<br>
                            &nbsp;&nbsp; }</span><br>
                            &nbsp;&nbsp; Status=0;<br>
                            }<br>
                            private void WinForm_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e)<br>
                            {<br>
                            ..... <span style="background-color: #FFFF00">else if(Status==3)<br>
                            {<br>
                            &nbsp;&nbsp; if(e.X&gt;mx) MausRechteckBreite=(e.X-mx)*2;<br>
                            &nbsp;&nbsp; else MausRechteckBreite=(mx-e.X)*2;<br>
                            &nbsp;&nbsp; MausRechteckHoehe=MausRechteckBreite*this.Height/this.Width;<br>
                            &nbsp;&nbsp; Invalidate();<br>
                            }</span><br>
                            <br>
                            viel Spaß,</p>
                            <p>Günther</p>

                            </body>

                            </html&gt
                            Günther

                            Comment


                            • #15
                              Hallo!
                              Wenn ich yMitte mit 100 initialisiere, dann stimmt ja die Position des zeichnens nicht. Sie ist ja dann bei 90 wenn ich "Linie(10,10,120,30,e,myPen);" zeichne.

                              Mein Mouse-Up sieht nun so aus:
                              <pre>
                              if(bClicked)
                              {
                              if(MausRechteckBreite>0)
                              {
                              xMitte=StartPt.X+xMitte;
                              yMitte=StartPt.Y+yMitte;
                              if (MausRechteckBreite<MausRechteckHoehe)
                              zoom=zoom*this.Width/MausRechteckBreite*2;
                              else
                              zoom=zoom*this.Height/MausRechteckHoehe*2;
                              }
                              }
                              Invalidate();
                              </pre>

                              Die Grösse er Linie wird zwar richtig angepasst, aber sie Position des zeichnens stimmt noch nicht ganz

                              Comment

                              Working...
                              X