Abbildungsmodus
-
Halloo Leute,
Zur Zeit bin ich gerade dran eine Koordinatensystem zu programmieren.
Es soll mittig ausgerichtet sein und die Achsen sollen geanuso verlaufen wie
wir von der Mathemaik gewohnt sind. Ich benutze den Abbildungsmodus
ANISOTROPIC und da habe ich Verständnissprobleme mit Befehlen wie z.B
LPtoDP. Denn wenn ich die Achsenskalierung programmiere kommt Müll raus.
Ich verstehe also nicht was diese Funktion genau macht.Am besten gebe ich mein Code mal auch an, es ist ja nicht lang:
void C1QuadrantDlg::Plot1CoordinateLinear(long yMIN, long yMAX, long xMIN, long xMAX, long DELTA) { long xExtension = xMAX - xMIN; long yExtension = yMAX - yMIN; CPaintDC dc(this); CRect ClientRect; CRect Coordinate; GetClientRect(&ClientRect); //Größe des Ausgabebereichs ermitteln GetClientRect(&Coordinate); //soll die Größe des 1. Quadranten aufnehmen CPoint Border(ClientRect.Width()/10,ClientRect.Height()/10); //Randgröße Coordinate.DeflateRect(Border.x,Border.y); //Größe des 1.Quadrantes //Größe der Striche die zur Achsenaufteilung dienen CPoint Strich(Coordinate.Width()/100,Coordinate.Height()/100); //verschieben des Ursprunges dc.SetViewportOrg(Border.x,ClientRect.Height()-Border.y); dc.SetMapMode(MM_ANISOTROPIC); dc.SetWindowExt(xExtension,yExtension); //Ausrichtung der Achse Y so daß pos. Werte nach oben gehen dc.SetViewportExt(Coordinate.Width(),-Coordinate.Height()); //Umwandlung der festgelegten Werte in log. Koordinaten dc.DPtoLP(&Border); dc.DPtoLP(&Strich); dc.DPtoLP(&Coordinate); dc.Rectangle(0,0,1000,1000); //dc.Rectangle(Coordinate); //dc.Ellipse(0,0,xExtension,yExtension); //Achsenaufteilung zeichnen for(int i=1;i<5;i++) { dc.MoveTo(0,DELTA*i); dc.LineTo(Strich.x,DELTA*i); } for(int j=1;j<5;j++) { dc.MoveTo(DELTA*j,0); dc.LineTo(DELTA*j,Strich.y); }
Edit by Moderator. Bitte Codetag nicht vergessen.
Vielen Dank für Antworten Bolilein
[ Dieser Beitrag wurde am 11.12.2002 um 14:05 Uhr von Unix-Tom editiert. ]
-
Hi,
also, ich kenne mich zwar mit "ANISOTROPIC" nicht aus,
aber ich schreibe gerade selber eine Dialogfeldanwendung, bei
der ein Koordinatensystem verwendet wird.
Hier einfach mal der Code:void CGraphDlg::OnCkoordinatensystem() { UpdateData(TRUE); CClientDC dc(this); CPen Pen; if(m_bKoordinatenSystem) // Wenn Koordinatensystem erwünscht { Pen.CreatePen(PS_SOLID,1,RGB(0,0,0)); // schwarzer Stift } else { Pen.CreatePen(PS_SOLID,1,DLG_BACKGROUND); // Stift mit der Hintergrundfarbe } dc.SelectObject(&Pen); // Stift verwenden dc.MoveTo(Rect.CenterPoint().x,Rect.BottomRight().y); // "Kreuz" zeichnen // Rect ist eine CRect Variable mit der Größe des Zeichenbereiches dc.LineTo(Rect.CenterPoint().x,0); dc.MoveTo(Rect.TopLeft().x,Rect.CenterPoint().y); dc.LineTo(Rect.BottomRight().x,Rect.CenterPoint().y); for(int x = Rect.CenterPoint().x;x <= Rect.right;x += 10) // x Striche alle 10 Punkte zeichnen { dc.MoveTo(x,Rect.CenterPoint().y+5); // folgende 2: positiver Bereich dc.LineTo(x,Rect.CenterPoint().y-5); dc.MoveTo(Rect.CenterPoint().x - (x - Rect.CenterPoint().x),Rect.CenterPoint().y+5); // negativer Bereich dc.LineTo(Rect.CenterPoint().x - (x - Rect.CenterPoint().x),Rect.CenterPoint().y-5); } for(int y = Rect.CenterPoint().y;y <= Rect.bottom;y += 10) // y Striche alle 10 Punkte zeichnen { dc.MoveTo(Rect.CenterPoint().x+5,y); dc.LineTo(Rect.CenterPoint().x-5,y); dc.MoveTo(Rect.CenterPoint().x+5,Rect.CenterPoint().y - (y - Rect.CenterPoint().y)); dc.LineTo(Rect.CenterPoint().x-5,Rect.CenterPoint().y - (y - Rect.CenterPoint().y)); } if(!m_bKoordinatenSystem)RePaintDC(); }
Ich hoffe, dass das dir weiterhilft.
mfg takeiteasy
-
@Bolilein
Jo, has Du wirklich falsch verstanden .. wie ich sehe, setzt Du überall clientrect ein, egal, ob für Viewport oder Window! Das ist falsch.----------------------------------- ClientWindow |WindowOrg (Border) | | ------------------------------- | | | | | | | WindowExt | | | | | | | | | | | ------------------------------- | | | -----------------------------------
Du setzt also mit SetWindowOrg den Rahmen, mit SetWindowExt die Grösse des Bereichs des Koordinatensystems in Device-Koordinaten.
Jetzt kannst Du mit SetViewportExt die Dimension von WindowExt für Dich bestimmen, z.B. WindowExt( 200, 100) -> ViewportExt( 2000, 200)
Wenn Du nun SetPixel( 1000, 100) aufrufst, wird der Pixel umgerechnet in Fensterkoordinaten bzw. DevicePoints und auf Punkt(100, 50) gesetzt.
Du musst also DPtoLP nicht aufrufen, um zu zeichnen.
Andersrum, wenn Du mit der Maus reinklickst, bekommst Du die Device-Koordinaten. Um diese auf Deine Koordinatensystemkoordinaten umzurechnen, musst Du nun DPtoLP aufrufen!
Soweit verständlich?
-
Hallo René
Ich denke ich habe deine Ausführungen noch nicht verstanden.
Daher versuche ich mal darzustellen wie ich die Sache verstanden habe.Also es gibt die sogennanten logische Koordinatenraum. Das ist der Koordinatensystem die ich einfach nur vorstelle und dessen Ursprung und Ausdehnung ich mit SetWindowOrg()und SetWindowExt() festlege.
So, und dann gibt es die sogenannte physikalische Koordinatensystem die den tatsächlichen Ausgabebereich (Client-bereich) darstellt in Pixeln (**standardmäßig).
Es werden grundsätzlich die logischen Koordinaten ins physikalische Koordinaten
abgebildet (umgerechnet).Also z.B bei SetWindowsExt(100,100) -> SetViewportExt(1000,1000)
wird mit dem Aufruf Rectangle(50,50) ein Rechteck mit 500 Pixel Seitenlänge gezeichnet.Nach mein Verständniss ist also alles was mit viewport zu tun hat der physikalische Bereich;also das was ich am Bildschirm tatsächlich sehe; das ist also der sichtbare Dialog oder irgendein Fenster.
Und der logische Koordinatenraum ist nur ein ´gedachte´ Koordinatenraum. Dessen Ursprung und Größe lege ich mit SetWindowOrg() und SetWindowExt() fest.Also nochmal : Ich sage ich will ein Koordinatensystem darstellen mit der Ausdehnung
100 Einheiten nach oben und rechts. Also SetWindowExt(100,100).
Dann ermittel´ ich die Größe des wirklichen Ausgabebereiches mit
GetClientRect(&ClientRect) in Pixeln. Dann kann ich mit
SetviewportExt(&ClientRect) erreichen ,daß wenn ich irgendein
Zeichnen-Funktion (100,100) übergebe, dann der gesammte
Ausgabebereich ausgefüllt wird (z.B bei Rectangle()) .Jetzt bin ich mal gespannt ob ich immer noch voll auf dem Holzweg bin.
Ich habe zum diesen Thema schon 3 Bücher gelesen und irgendwie ist es nicht 100% klar.Vielen Dank im voraus und have a nice day .... bolilein**
-
Ja, so habe ich das bisher immer gemacht und hat auch funktioniert .. bei meiner obigen Erklärung habe ich leider die Befehle SetViewportExt und SetWindowExt verwechselt, hoffe, Du verzeihst mir das ...
Das erste, was ich nicht verstehe, ist, dass Du Deine Strichbreite und Border abhängig vom ClientRect machst, kann mir nicht vorstellen, dass diese 80Px breit sein sollen, wenn das Rect 800 breit ist.
Als zweites verwendest Du CPaintDC, dieses darf aber nur innerhalb des OnPaint-Befehls stehen. Bei Deiner Funktion müsstest Du CClientDC verwenden.
Als 3. wäre es gut, wenn Du ein Beispiel angibst, wo Du LPtoDP verwendest. In Deinem Codebeispiel verwendest Du nur DPtoLP und dass scheint zu funktionieren, ausser dass Du nur 5 Striche für die Skalierung zeichnen willst, was ich aber abhängig von Min<->Max machen würde.
-
Hallo René
Dank für Antwort
1. Ich mache den Rand von Fenstergröße abhängig da mein Ausgabefenster in der
Größe änderbar sein soll.
Den Rand habe ich definiert damit ich meine Koordinatensystem (nur 1.Quadrant!!) mittig im Ausgabefenster positionieren kann.Ich richte also mein Koordinatensystem so aus wie ich von Mathe aus gewohnt bin.
Y nach oben X nach rechts. Dazu verschiebe ich den Ursprung um "Rand" nach rechts und Ausgabefensterhöhe-"Rand".2. Ja ich habe auch schon gelesen daß ich eigentlich CClientDC benutzen sollte aber wenn ich das mache dann flackert es wild und ich weiß nicht warum. Das müßte ich aber nochmal probieren (ich weiß es nicht mehr genau).
3. nach diesen Befehl DPtoLP bzw. LPtoD habe ich deshalb gefragt, weil der irgendwie (glaub ich) auch die Achsenausrichtungen mit berücksichtigt. Nur ich habe keine ahnung wie. Zumindest kriege ich meine Achsenstriche mit dem Befehl nicht hin. Nur wenn ich diese konvertierung sein lasse dann kommt ein akzeptabler Ergebniss raus. nach meine Logik müßte ich aber die Konvertierung DPtoLP vornehmen. Na ja ich weiß nicht ....
Danke danke ,und falls du noch was für mich hast freue ich mich
Gruß bolilein