Koordinatensystem ändern



  • Ich kann ja mit der Funktion LineTo(); Linien innerhalb eines angegebenen Device-Kontextes zeichnen, dabei entspricht bei derKoordinatenangabe 1 == 1 Pixel. Jetz meine Frage:

    Gibt es in der WinAPI irgendeine Funktion um dieses Koordinatensystem für einen Device-Kontext zu ändern, so dass dann z.B. 1 == 2 Pixel wäre?



  • Man kann das koordinatensystem ändern mittels

    SetMapMode(hdc, iMapMode
    

    Für iMapMode kannst Du dann :
    *
    MM_HIENGLISH Each logical unit is converted to 0.001 inch. Positive x is to the right; positive y is up.

    MM_HIMETRIC Each logical unit is converted to 0.01 millimeter. Positive x is to the right; positive y is up.

    MM_ISOTROPIC Logical units are converted to arbitrary units with equally scaled axes; that is, 1 unit along the x-axis is equal to 1 unit along the y-axis. Use the SetWindowExt and SetViewportExt member functions to specify the desired units and the orientation of the axes. GDI makes adjustments as necessary to ensure that the x and y units remain the same size.

    MM_LOENGLISH Each logical unit is converted to 0.01 inch. Positive x is to the right; positive y is up.

    MM_LOMETRIC Each logical unit is converted to 0.1 millimeter. Positive x is to the right; positive y is up.

    MM_TEXT Each logical unit is converted to 1 device pixel. Positive x is to the right; positive y is down.

    MM_TWIPS Each logical unit is converted to 1/20 of a point. (Because a point is 1/72 inch, a twip is 1/1440 inch.) Positive x is to the right; positive y is up.* einsetzen.

    Sorry war zu faul zum tippen und hab nur kopiert. Hilft das??



  • Erstmal thx für deine Antwort, ich hab das jetz mal ausprobiert aber werde daraus irgendwie nicht schlau! Kann bitte nochmal jemand zeigen wie ich das Koordinatensystem von

    HDC dc;
    

    so abändern kann dass alles was ich darin zeichne z.B um 10% größer erscheint?



  • MM_ISOTROPIC ist IMHO das sinnvollste aller koordinatensysteme. 🙂
    Dabei wird das Bild nämlich nicht in eine Richtung gestreckt oder gestaucht, was bei MM_ANISOTROPIC der Fall ist, und du hast die volle Kontrolle was wie viel Pixel entspricht.

    Also:
    Es gibt 2 Typen von Einheiten: logische Einheiten und physische Einheiten. Fast alle GDI-Funktionen erwarten logische Einheiten. Eine physische Einheit ist in der Regel ein Pixel (muss aber nicht sein, z.B. plotter).
    Im "normalen" standard-Modus entspricht eine logische Einheit genau einer physischen Einheit.
    Windows rechnet das wie folgt um:
    Physisch = Logisch * (ViewportExt / WindowExt);
    Man könnte das eigentlich genauso gut als fließkommazahl speichern, aber das wäre um Längen langsamer als es schon ist.
    Also gibt es, um die Unübersichtlichkeit zu fördern, 2 Funktionen: SetViewportExtEx und SetWindowExtEx. Die eine setzt den Zähler, die andere den Nenner des obigen Bruches.

    Nehmen wir mal ein Beispiel:
    Du willst, dass 1 logische Einheit 2 Pixel entsprechen.

    SetViewportExtEx(hDC, 2, 2, NULL);
    SetWindowExtEx(hDC, 1, 1, NULL);
    

    Dann steht im Bruch nämlich 2/1, was 2 ergibt. d.h. jede logische Koordinate wird mit 2 multipliziert. Allerdings sehen Linien u.a. ein wenig eckig aus, da das Raster jetzt 2 Pixel beträgt. Die GDI kann nur noch auf jeden 2ten Pixel zugreifen (die pixel dazwischen werden auch mit erwischt).
    Das ist da noch nicht so extrem, aber wenn du z.B. sagst, dass 1 logisch==10 physisch, dann sieht man das schon ziemlich stark.

    Verkleinern geht genau umgekehrt, da hat man auch nicht das Problem mit dem groben Pixelraster. Dafür aber ein anderes, viel größeres: Bei Win9x (IMHO auch WinME) dürfen logische Koordinaten maximal 32767 groß sein und minimal -32767. Bei starker Verkleinerung ist das schnell erreicht. Bei mir reagiert windows so darauf, dass es einfach nix mehr zeichnet, was darüber geht.
    Wie man sieht gibt es viele fallen, und das waren noch nicht mal alle. 😮
    Aber man kann schon einiges anfangen mit eigenen Koordinatensystemen. 🙂



  • Ah, hab ich doch auch mal wieder was gelernt. Hatte nämlich meinen Vorschlag aus dem Petzhold entnommen (hatte ich mal durchgearbeitet aber das Thema GDI wieder schnell übersprungen).
    Hatte da dann auch was mit
    *
    SetViewportExtEx() und
    SetWindowExtEx()*
    gelesen, aber da ich das nicht so genau erklären konnte hab ichmal meine Klappte gehalten.



  • @cd9000

    MM_ISOTROPIC ist IMHO das sinnvollste aller koordinatensysteme.

    Naja, 1. ist das kein Koordinatensystem, sondern ein Abbildungsmodus. 2. ist die horizontale Auflösung eines Monitors/Druckers meist höher als die vertikale. Womit sich ergibt, dass MM_ANISOTROPIC sehr viel häufiger benutzt werden muss als MM_ISOTROPIC.



  • Sorry das ich lange nicht da war, ich war im Urlaub. 🙂

    @ReneG:
    Zu 1.: Okay... wer wird denn da so pingelig sein? 😉
    Zu 2.:
    Wieso? Man kann auch im MM_ISOTROPIC Modus alle Pixel ansprechen. Man ist ja nicht auf 1000*1000 Werte beschränkt, nur weil man gesagt hat, 1000 logische Einheiten entsprechen der Schirm-/Blatt-Breite.
    Der riesige Vorteil ist, dass z.B. Rectangle(hDC, 0, 0, 100, 100) IMMER ein Quadrat ergibt.
    Wenn man den Modus MM_ANISOTROPIC nutzt, und unterschiedliche Achsengrößen für x bzw. y festlegt, ist es sehr viel komplizierter, ein gescheites Quadrat zu zeichnen.

    Bei meinen drei Programmen, die Koordinatensysteme verwenden, (hauptsächlich Mathe-Programme) habe ich auch immer MM_ISOTROPIC benutzt. Ich will ja nicht, dass eine Sinuskurve plötzlich gestreckt oder gestaucht wird. Beim Drucken dieser Graphen nutze ich auch MM_ISOTROPIC.

    p.s.:
    Ich finde, dieser Beitrag gehört in die FAQ. Aber da du vielleicht noch etwas posten willst, warte ich noch ein bisschen.

    [ Dieser Beitrag wurde am 11.10.2002 um 19:51 Uhr von cd9000 editiert. ]



  • Keine Postings mehr? Ok, dann in FAQ. 🙂


Anmelden zum Antworten