Koordinatensystem drehen

Für allgemeine Fragen zur Programmierung mit PureBasic.
BSP
Beiträge: 201
Registriert: 01.02.2009 14:04

Koordinatensystem drehen

Beitrag von BSP »

Hallo Allerseits.

Ich habe ein Koordinatensystem, das ich drehen möchte.
Aber nicht im Kreis, sondern im Quadrat.
Das Koordinatensystem geht von:
Xrichtung: 0,0 bis 4,0
Yrichtung: 0,0 bis 0,4
Ich habe bereits nach "Matrix drehen" gegoogelt.
Aber ich gestehe, ich kann mit den Beschreibungen nichts anfangen.
Ich lerne besser aus funktionierenden Beispielen.

Ich habe da mal was ausgetüfftelt, damit Ihr seht, wie ich mir das vorstelle.
(Bitte nicht schimpfen, ich weiss, das Prg ist noch sehr kuddelmuddelig).

Könnt Ihr mir helfen, das zu verbessern?
Ich möchte meine Symbole nicht einfach im Kreis drehen,
weil, meine Symbole dann entweder über die Kanten hinaus
oder nicht bis in die Ecken hinein zeichnen.

Ich hoffe, Ihr versteht, was ich meine.

Gruß & Dank im Voraus:
Bernd

Code: Alles auswählen

Global Dim m1.Point(16)
Global Dim m2.Point( 8)
Global PBlack=CreatePen_(#PS_SOLID|#PS_ENDCAP_SQUARE , 7, $000000)
Global PGelb =CreatePen_(#PS_SOLID|#PS_ENDCAP_SQUARE , 3, $00D7FF)
Global raster=10

Restore matrix
Read.s a$
For i=1 To 16
  m$=StringField(a$,i,",")
  m1(i-1)\x=Val(StringField(m$,1,"."))
  m1(i-1)\y=Val(StringField(m$,2,"."))
Next
Read.s a$
For i=1 To 8
  m$=StringField(a$,i,",")
  m2(i-1)\x=Val(StringField(m$,1,"."))
  m2(i-1)\y=Val(StringField(m$,2,"."))
Next
DataSection
matrix:
Data.s "0.2,0.1,0.0,1.0,2.0,3.0,4.0,4.1,4.2,4.3,4.4,3.4,2.4,1.4,0.4,0.3"
Data.s "1.2,1.1,2.1,3.1,3.2,3.3,2.3,1.3"
EndDataSection

;- ====== Konstanten
; - Fenster
Enumeration
  #hwnd
EndEnumeration

Procedure Create_Window()
  fl=#PB_Window_SystemMenu
  fl|#PB_Window_ScreenCentered
  OpenWindow(#hwnd,0,0,300,400,"Gleisplan- Editor",fl)
  
EndProcedure

Procedure objekt(hdc,a$,xpos,ypos,winkel,pen)
    
    dgi$=StringField(a$,1,",") ; Zeichnenfunktion
    xy$=Mid(a$,Len(dgi$)+2)
    
    Select dgi$
    Case "pol"  ; pol = Polyline als eine mögliche Zeichnenfunktion
        ip=(CountString(xy$,","))/2 +1
        Dim p.point(ip)
        For j=0 To ip-1
          x =Val(StringField(xy$,1+j*2,",")); *fx
          y =Val(StringField(xy$,2+j*2,",")); *fy
          ok=0
          For w=0 To 15
            If x=m1(w)\x And y=m1(w)\y
              w1=w+winkel*2
              If w1>15:w1-16:EndIf
              p(j)\x =m1(w1)\x*raster +raster
              p(j)\y =m1(w1)\y*raster +raster
              ok=1
              Break
            EndIf
          Next
          If Not ok
            For w=0 To 7
              If x=m2(w)\x And y=m2(w)\y
                w1=w+winkel
                If w1>7:w1-8:EndIf
                p(j)\x =m2(w1)\x*raster +raster
                p(j)\y =m2(w1)\y*raster +raster
                ok=1
                Break
              EndIf
            Next
          EndIf
          If Not ok
            p(j)\x =2*raster +raster
            p(j)\y =2*raster +raster          
          EndIf
        Next
        SelectObject_(hdc,pen)
        Polyline_(hdc,@p(),ip)
    EndSelect
EndProcedure

Procedure zeichne_objekt(hdc,objekt$,x,y,winkel,richtung)
  Box(raster-4,raster-4,4*raster+8,4*raster+8,$A9A9A9)
  For i=1 To CountString(objekt$,"+") +1
    a$=StringField(objekt$,i,"+")
    objekt(hdc,a$,x,y,winkel,PBlack)
  Next
  If richtung
    a$=StringField(objekt$,richtung,"+")
    objekt(hdc,a$,x,y,winkel,PGelb)
  EndIf
EndProcedure

Create_Window()
hdc=StartDrawing(WindowOutput(#hwnd))
Box(0,0,WindowWidth(#hwnd),WindowHeight(#hwnd),$00ff00)
StopDrawing()

x=10
y=150
objekt$= "pol,0,2,4,2"
objekt$+ "+pol,0,2,1,2,3,3,4,4"
objekt$+ "+pol,0,2,2,2,4,4"
richtung=2
Repeat
If ElapsedMilliseconds()-zeit>1000
  zeit=ElapsedMilliseconds()
  hdc=StartDrawing(WindowOutput(#hwnd))
  zeichne_objekt(hdc,objekt$,x,y,winkel,richtung)
  winkel+1:If winkel>7:winkel-8:EndIf
  StopDrawing()
EndIf
ev = WaitWindowEvent(20)
Select ev
Case #PB_Event_CloseWindow
  ende=1
EndSelect
Until ende
DeleteObject_(PBlack)
DeleteObject_(PGelb)
End
PB 5.31 (x86) & (x64) Win10
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7028
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: Koordinatensystem drehen

Beitrag von STARGÅTE »

Ich kann nur so viel sagen, dass du das nicht mit einer Rotationsmatrix lösen kannst, denn Matrizen sind für lineare Transformationen.
Bei deinem Vorhaben kann aber auch einer geraden Linie (die oben an der Kante liegt, von 1,0 nach 3,0) eine Ecke werden, die dann global von 3,0 über 4,0 nach 4,1 geht. Richtig?
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8807
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Re: Koordinatensystem drehen

Beitrag von NicTheQuick »

Also im Grunde willst du nicht die euklidische, sondern die p-Norm mit p = unendlich bzw. die Supremumsnorm nutzen um deinen Raum aufzuspannen. Im Grunde müsste man den auch drehen können, ich komme gerade nur nicht so richtig drauf wie man das am geschicktesten anstellt. Ich suche mal weiter.

Nachtrag:
Ich hab zumindest mal ein Paper dazu gefunden: Infinity-Norm Rotation Transforms. Aber im Abstract stet auch schon drin, dass das dann eine stückchenweise definierte lineare Transformation ist, also mit einer einfachen Matrixmultiplikation nicht zu lösen.
BSP
Beiträge: 201
Registriert: 01.02.2009 14:04

Re: Koordinatensystem drehen

Beitrag von BSP »

Hallo Stargate.
Bei deinem Vorhaben kann aber auch einer geraden Linie (die oben an der Kante liegt, von 1,0 nach 3,0) eine Ecke werden, die dann global von 3,0 über 4,0 nach 4,1 geht. Richtig?
Das ist zwar nicht direkt vorgesehen, aber ja, möglich wäre es.

Ich habe das noch mal etwas erweitert, eine Box gezeichnet.

Code: Alles auswählen

objekt$= "pol,1,0,3,0,3,2,1,2,1,0"
Auch sowas wäre möglich, aber nicht vorgesehen.
Für den Zweck habe ich eine Erweiterung der "Befehlssätze" vorgesehen,
so das ich an die Koordinatenpunkte auch:
"cir" = circle, "box" = box
direkt zeichnen kann.

Hallo Nick.

Hey, Mensch, uff, Kopfqualm.
Ich bin doch blos einfacher Hauptschüler, und das ist auch schon 40 Jahre her. :oops:

Im Grunde ist das garnicht so doll, was ich vorhabe.
Ihr müsst Euch das so vorstellen:
Eine Schalttafel, in die ich verschiedene Schaltungssymbole "einklipsen" kann.
Bisher bin ich so vorgegangen, das ich jedes Symbol für jede Richtung direkt "gebastellt" habe.
Ich hatte nur gehofft, wenn ich schon vor so einer Zauberkiste namen Computer sitze,
soll die mir doch die Arbeit abnehmen.
Ich "bastel" immer nur ein Grundsymbol, und der PC dreht das dann in die gewünschte Richtung.
Ich habe es auch schon mit "im Kreis drehen" versucht, Beispiele für Image drehen gibts hier im Forum ja genug.
Aber das gefiel mir von der Optik her auch nicht wirklich.
Na gut. Dann bleibt wohl nur der Weg, jedes Symbol einzeln zu bauen. "Wie im wahren Leben".

Ich danke Euch für Eure Mühe.
MfG: Bernd
PB 5.31 (x86) & (x64) Win10
Benutzeravatar
Sunny
Beiträge: 290
Registriert: 19.02.2009 06:02

Re: Koordinatensystem drehen

Beitrag von Sunny »

Mal so nebenbei gefragt...

Wäre es in deinem Fall nicht einfacher auf die 3D-Lib von PB zurückzugreifen?
BSP
Beiträge: 201
Registriert: 01.02.2009 14:04

Re: Koordinatensystem drehen

Beitrag von BSP »

Hallo Sunny.
Nein, ich denke, das wäre viel zu viel Aufwand.
Die 2D- Funktionen reichen für mein Vorhaben völlig aus.
Am Ende soll das Prg sogar von einem alten WinMe- Laptop betrieben werden.
Der Steuert meine Modellbahn bisher und macht seine Arbeit gut.
(Ist ja nur eine kleine Wohnzimmeranlage und kein MiWuLa). :D

Na ja, Und soo schlecht ist meine obige Lösung ja auch nicht.
Noch ein wenig unaufgeräumt, aber es funktioniert.
Ich brauche ein Symbol nur noch einmal bestimmen, das "drehen" übernimmt das Prg.
Und so lassen sich dann schnell neue Symbole entwerfen.
Für die Modellbahn, einer Alarmanlage oder, wenns denn sein soll, sogar einer Haushaltsgerätesteuerung.
Und es werden dann ja auch nicht alle Symbole gedreht.
Nur die für den Gleis- oder Stromlaufplan. Signale beispielsweise müssen ja nicht auf dem Kopf stehen.

Nein, die 3D- Funktionen wären hier wohl total überqualifiziert.
Gruß: Bernd
PB 5.31 (x86) & (x64) Win10
Antworten