Seite 2 von 3
Verfasst: 16.07.2007 20:48
von PureLust
Fluid Byte hat geschrieben:Kannste machen was de willst. Die Linie ist immer 1 Pixel zu weit rechts. Wie kann ich das beheben?
Also bei mir klappts (PB4.10-Beta2, Intel, WinXP).
Wenn ich bei Deinem Ursprungscode #WIDTH = 351 und #HEIGHT = 351 setze (that's it - nothing else) sitzt alles perfekt.
Code: Alles auswählen
#WIDTH = 351 : #HEIGHT = 351 : #WSPACE = 40
CreateImage(0,#WIDTH + (#WSPACE * 2),#HEIGHT + (#WSPACE * 2))
OpenWindow(0,0,0,#WIDTH + (#WSPACE * 2),#HEIGHT + (#WSPACE * 2),"void",#WS_OVERLAPPEDWINDOW | 1)
CreateGadgetList(WindowID(0))
ImageGadget(0,0,0,0,0,ImageID(0))
SetWindowColor(0,0)
SetTimer_(WindowID(0),0,20,0)
#Linelength = 100
Procedure WindowCallback(hWnd,uMsg,wParam,lParam)
Static Angle = 45
Select uMsg
Case #WM_TIMER
Angle + 1
StartDrawing(ImageOutput(0))
Box(0,0,#WIDTH + (#WSPACE * 2),#HEIGHT + (#WSPACE * 2))
Circle((#WIDTH / 2) + #WSPACE,(#HEIGHT / 2) + #WSPACE,11,#Red)
DrawingMode(4)
Circle((#WIDTH / 2) + #WSPACE,(#HEIGHT / 2) + #WSPACE,#WIDTH / 2,#HEIGHT / 2)
DrawingMode(0)
X1.f = Cos((Angle - 45) * #PI/180) * #WIDTH/2
Y1.f = Sin((Angle - 45) * #PI/180) * #HEIGHT/2
X2.f = Cos((Angle + 45) * #PI/180) * 100
Y2.f = Sin((Angle + 45) * #PI/180) * 100
FX.f = X1 + (#WIDTH / 2) + #WSPACE
FY.f = Y1 + (#HEIGHT / 2) + #WSPACE
LineXY(FX-X2-1,FY-Y2-1,FX + X2-1,FY + Y2-1,#Green)
StopDrawing()
SetGadgetState(0,ImageID(0))
EndSelect
ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure
SetWindowCallback(@WindowCallback())
While WaitWindowEvent() ! 16 : Wend
Verfasst: 16.07.2007 20:49
von Fluid Byte
Nix bei misch alde. Guckst du hier:
Code: Alles auswählen
#Width = 351
#Height = 351
#WhiteSpace = 30
#Linelength = 100
#Radius = #Height / 2
#CenterX = (#Width / 2) + #WhiteSpace
#CenterY = (#Height / 2) + #WhiteSpace
CreateImage(0,#Width + (#WhiteSpace * 2),#Height + (#WhiteSpace * 2))
OpenWindow(0,0,0,#Width + (#WhiteSpace * 2),#Height + (#WhiteSpace * 2),"void",#WS_OVERLAPPEDWINDOW | 1)
CreateGadgetList(WindowID(0))
ImageGadget(0,0,0,0,0,ImageID(0))
SetWindowColor(0,0)
SetTimer_(WindowID(0),0,40,0)
Procedure WindowCallback(hWnd,uMsg,wParam,lParam)
Static Angle = 0
Select uMsg
Case #WM_TIMER
Angle + 0
StartDrawing(ImageOutput(0))
Box(0,0,#Width + (#WhiteSpace * 2),#Height + (#WhiteSpace * 2))
Circle((#Width / 2) + #WhiteSpace,(#Height / 2) + #WhiteSpace,11,#Red)
DrawingMode(4)
Circle((#Width / 2) + #WhiteSpace,(#Height / 2) + #WhiteSpace,#Width / 2,#Red)
DrawingMode(0)
X1.f = Cos((Angle - 90) * #PI/180) * #Linelength/2
Y1.f = Sin((Angle - 90) * #PI/180) * #Linelength/2
X2.f = Cos((Angle + 90) * #PI/180) * #Linelength/2
Y2.f = Sin((Angle + 90) * #PI/180) * #Linelength/2
FX.f = #CenterX + Cos(Angle * #PI/180) * #Radius
FY.f = #CenterY + Sin(Angle * #PI/180) * #Radius
LineXY(FX + X1, FY + Y1, FX + X2, FY + Y2,#Green)
StopDrawing()
SetGadgetState(0,ImageID(0))
EndSelect
ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure
SetWindowCallback(@WindowCallback())
While WaitWindowEvent() ! 16 : Wend
Verfasst: 16.07.2007 20:53
von STARGÅTE
dann muss du einfach so tun als ob der Kreis weiter links ist :
x = Kreis_x - 1
wenn du den x-Wert des Kreises für die Linien brauchst.
Verfasst: 16.07.2007 20:57
von Fluid Byte
STARGÅTE hat geschrieben:dann muss du einfach so tun als ob der Kreis weiter links ist :
x = Kreis_x - 1
wenn du den x-Wert des Kreises für die Linien brauchst.
Theorie oder Praxis? Ich meine wie soll das ausehen? Dann stimmt es doch auf linken Seite nicht mehr. Oder hab das sprichwörtliche Brett vorm Kopf?
Verfasst: 16.07.2007 20:59
von PureLust
STARGÅTE hat geschrieben:dann muss du einfach so tun als ob der Kreis weiter links ist :
x = Kreis_x - 1
wenn du den x-Wert des Kreises für die Linien brauchst.
Das wär'n Tick zu einfach.
Das Problem ist, dass der Durchmesser des von Circle() gezeichneten Kreises im Grunde um 1 Pixel abweicht von der Durchmesser der durch Sin()/Cos() berechneten Kreisbahn auf der sich die Linie bewegt.
Wenn man nun also einfach die Umlaufbahn um einen Pixel verschiebt, so passt es dann plötzlich auf der anderen Seite nicht mehr.
[Edit] @FB: Haste mal meinen oben geposteten Code getestet?
Verfasst: 16.07.2007 21:01
von Fluid Byte
Hehehe
Jesus, Maria und Joseph! Es wird doch wohl möglich sein das so hinzukriegen das es links/rechts und oben/unten
exakt auf der Linie des Kreises liegt. Oder wat?
PS: Ja hab ich, selbes Ergebniss. Links liegt sie genau auf, nicht aber rechts.
Verfasst: 16.07.2007 21:02
von Kaeru Gaman
wie wäre es dann, nicht die Circle-funktion von DicertDraw zu benutzen,
sondern den kreis selber zu zeichnen, mit der selben formel, mit der man den tagentialpunkt berechnet?
Verfasst: 16.07.2007 21:04
von Fluid Byte
Ne, der Radius brechnet sich durch die angegeben Breite bzw. Höhe. In meinen Beispiel 350 Px. Ich habs gescheckt, die Maße des Kreises stimmen. Es nicht der Kreis der angepaßt werden muss sondern die Formel.
Verfasst: 16.07.2007 21:21
von PureLust
Wie gesagt, mit Deiner ursprünglichen Berechnungsmethode klappts:
Code: Alles auswählen
;Code aus Platzgründen entfernt, da Code in Folgepost allgemeingültiger sein dürfte.
Verfasst: 16.07.2007 22:15
von PureLust
Sodele .. nun hamm wir's abba.
Das Problem war, dass der Circle()-Befehl ja einen Kreis mit einem geradzahligen Durchmesser zeichnet (2 x den angegebenen Radius).
Bei der eigene Kreisformel hingegen kommt ja immer ein Kreis mit einem ungeraden Durchmesser heraus (Radius+MittelPunkt+Radius).
Um nun also diese Abweichung von einem Pixel aufzufangen muss sowohl der Mittelpunkt als auch der Radius etwas angepasst werden (um etwa 0.333 Pixel).
Nachfolgend mal der angepasste Code der die von Kaeru beschriebene Formel verwendet:
(Die eigentlichen Anpassungen befinden sich in Zeile 5-7 bei den Werten für die Konstanten.)
Code: Alles auswählen
#Width = 350
#Height = 350
#WhiteSpace = 30
#Linelength = 100
#Radius = #Height / 2 - 0.333
#CenterX = (#Width / 2) + #WhiteSpace - 0.333
#CenterY = (#Height / 2) + #WhiteSpace - 0.333
Debug #CenterX
CreateImage(0,#Width + (#WhiteSpace * 2),#Height + (#WhiteSpace * 2))
OpenWindow(0,0,0,#Width + (#WhiteSpace * 2),#Height + (#WhiteSpace * 2),"void",#WS_OVERLAPPEDWINDOW | 1)
CreateGadgetList(WindowID(0))
ImageGadget(0,0,0,0,0,ImageID(0))
SetWindowColor(0,0)
SetTimer_(WindowID(0),0,40,0)
Procedure WindowCallback(hWnd,uMsg,wParam,lParam)
Static Angle = 0
Select uMsg
Case #WM_TIMER
Angle + 90
StartDrawing(ImageOutput(0))
; Box(0,0,#Width + (#WhiteSpace * 2),#Height + (#WhiteSpace * 2))
Circle((#Width / 2) + #WhiteSpace,(#Height / 2) + #WhiteSpace,11,#Red)
DrawingMode(4)
Circle((#Width / 2) + #WhiteSpace,(#Height / 2) + #WhiteSpace,#Width / 2,#Red)
DrawingMode(0)
X1.f = Cos((Angle - 90) * #PI/180) * #Linelength/2
Y1.f = Sin((Angle - 90) * #PI/180) * #Linelength/2
X2.f = Cos((Angle + 90) * #PI/180) * #Linelength/2
Y2.f = Sin((Angle + 90) * #PI/180) * #Linelength/2
FX.f = #CenterX + Cos(Angle * #PI/180) * #Radius
FY.f = #CenterY + Sin(Angle * #PI/180) * #Radius
LineXY(FX + X1, FY + Y1, FX + X2, FY + Y2,#Green)
StopDrawing()
SetGadgetState(0,ImageID(0))
EndSelect
ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure
SetWindowCallback(@WindowCallback())
While WaitWindowEvent() ! 16 : Wend
Grüße, PL.