"Bounding-Box" von DrawRotatedText() ?

Anfängerfragen zum Programmieren mit PureBasic.
c4s
Beiträge: 1235
Registriert: 19.09.2007 22:18

"Bounding-Box" von DrawRotatedText() ?

Beitrag von c4s »

Folgender Code beschreibt meine Frage wohl am Besten:

Code: Alles auswählen

Text.s = "Hello World!"

NBoxX = 50 : NBoxY = 50
GBoxX = 50 : GBoxY = 150  ;

CreateImage(0, 200, 200)
StartDrawing(ImageOutput(0))
	; Normal:
	DrawingMode(#PB_2DDrawing_Transparent)
	DrawText(NBoxX, NBoxY, Text, $FF00FF)
	DrawingMode(#PB_2DDrawing_Outlined)
	Box(NBoxX, NBoxY, TextWidth(Text), TextHeight(Text), $FF00FF)
	Circle(NBoxX, NBoxY, 3, $FF00FF)

	; Gedreht:
	DrawingMode(#PB_2DDrawing_Transparent)
	DrawRotatedText(GBoxX, GBoxY, Text, 45, $FFFFFF)
	DrawingMode(#PB_2DDrawing_Outlined)
	Box(50, 90, 73, 73, $FFFFFF)  ; <- Geschätzte Koordinaten zur Veranschaulichung
	Circle(50, 90, 3, $FFFFFF)
StopDrawing() 


If OpenWindow(0, 0, 0, 200, 200, "2DDrawing Example", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
	ImageGadget(0, 0, 0, 200, 200, ImageID(0))

	Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf
Ich möchte bei DrawRotatedText() die "Bounding-Box"-Koordinaten herausfinden und die Funktion am liebsten auch darüber steuern, sodass nicht um X/Y herum gedreht wird, sondern innerhalb der "Bounding-Box".

Kann mir jemand dabei auf die Sprünge helfen?
"Menschenskinder, das Niveau dieses Forums singt schon wieder!" — GronkhLP ||| "ich hogffe ihr könnt den fehle endecken" — Marvin133 ||| "Ideoten gibts ..." — computerfreak ||| "Jup, danke. Gruss" — funkheld
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7031
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: "Bounding-Box" von DrawRotatedText() ?

Beitrag von STARGÅTE »

Ist nicht ganz auf den Pixel (weil DrawText die Font irgendwie dicker macht bei Rotate) genau aber funktioniert:

Code: Alles auswählen

Text.s = "Hello World!"

NBoxX = 50 : NBoxY = 50
GBoxX = 150 : GBoxY = 250  ;

Procedure.i RotatedTextX(Text.s, Angle.f)
  Protected x
  If Cos(Radian(Angle)) < 0
    x + Cos(Radian(Angle))*TextWidth(Text)
  EndIf
  If Sin(Radian(Angle)) < 0
    x + Sin(Radian(Angle))*TextHeight(Text)
  EndIf
  ProcedureReturn x
EndProcedure
Procedure.i RotatedTextY(Text.s, Angle.f)
  Protected y
  If Sin(Radian(Angle)) > 0
    y - Sin(Radian(Angle))*TextWidth(Text)
  EndIf
  If Cos(Radian(Angle)) < 0
    y + Cos(Radian(Angle))*TextHeight(Text)
  EndIf
 ProcedureReturn y
EndProcedure
Procedure.i RotatedTextWidth(Text.s, Angle.f)
  ProcedureReturn Abs(Cos(Radian(Angle))*TextWidth(Text))+Abs(Sin(Radian(Angle))*TextHeight(Text))
EndProcedure
Procedure.i RotatedTextHeight(Text.s, Angle.f)
  ProcedureReturn Abs(Sin(Radian(Angle))*TextWidth(Text))+Abs(Cos(Radian(Angle))*TextHeight(Text))
EndProcedure


CreateImage(0, 400, 400)
StartDrawing(ImageOutput(0))
   ; Normal:
   DrawingMode(#PB_2DDrawing_Transparent)
   DrawText(NBoxX, NBoxY, Text, $FF00FF)
   DrawingMode(#PB_2DDrawing_Outlined)
   Box(NBoxX, NBoxY, TextWidth(Text), TextHeight(Text), $FF00FF)
   Circle(NBoxX, NBoxY, 3, $FF00FF)

   angle = 45
   ; Gedreht:
   DrawingMode(#PB_2DDrawing_Transparent)
   DrawRotatedText(GBoxX, GBoxY, Text, angle, $FFFFFF)
   DrawingMode(#PB_2DDrawing_Outlined)
   GBoxX + RotatedTextX(Text, angle)
   GBoxY + RotatedTextY(Text, angle)
   Box(GBoxX, GBoxY, RotatedTextWidth(Text, angle), RotatedTextHeight(Text, angle), $FFFFFF)  ; <- Geschätzte Koordinaten zur Veranschaulichung
   Circle(GBoxX, GBoxY, 3, $FFFFFF)
StopDrawing() 


If OpenWindow(0, 0, 0, 400, 400, "2DDrawing Example", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
   ImageGadget(0, 0, 0, 400, 400, ImageID(0))

   Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf 
RotatedTextX und RotatedTextY geben die (mögliche) Verschiebung an, wo die linke obere Ecke wäre
und RotatedTextWidth und RotatedTextHeight die gesamt ausdehnung.

Wie gesagt, die Darstellung von DrawText ist irgendwie ungenau, deswgene passt es nicht ganz.
Die Breite eines Textes ist nicht gleich der Höhe wenn er um 90° gedreht ist.
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
c4s
Beiträge: 1235
Registriert: 19.09.2007 22:18

Re: "Bounding-Box" von DrawRotatedText() ?

Beitrag von c4s »

Danke, ich werde mich damit mal auseinandersetzen und in mein kleines Projekt einbauen, dass ich demnächst hier veröffentlichen will.
"Menschenskinder, das Niveau dieses Forums singt schon wieder!" — GronkhLP ||| "ich hogffe ihr könnt den fehle endecken" — Marvin133 ||| "Ideoten gibts ..." — computerfreak ||| "Jup, danke. Gruss" — funkheld
c4s
Beiträge: 1235
Registriert: 19.09.2007 22:18

Re: "Bounding-Box" von DrawRotatedText() ?

Beitrag von c4s »

Leider verstehe ich das immer noch nicht so ganz... Wie kann ich das Beispiel so abändern, dass der rechte Text innerhalb der Box gezeichnet wird?
Ich möchte erreichen, dass DrawRotatedText() nicht um die X/Y-Koordinaten herum zeichnet, sondern wie bei DrawText() (bzw. Winkel=0) immer rechts unten von der gewünschten Position ist.

Ich habe das Beispiel etwas verbessert:

Code: Alles auswählen

EnableExplicit

Enumeration 
	#Window
	#ImageGadget
	#Image
	#Timer
EndEnumeration

Global Width, Height
Global Text.s, TextFontID
Global NBoxX, NBoxY, GBoxX, GBoxY, GAngle.f


Procedure RotatedTextX(Text.s, Angle.f)
	Protected Result

	If Cos(Radian(Angle)) < 0
		Result + (Cos(Radian(Angle)) * TextWidth(Text))
	EndIf

	If Sin(Radian(Angle)) < 0
		Result + (Sin(Radian(Angle)) * TextHeight(Text))
	EndIf

	ProcedureReturn Result
EndProcedure

Procedure RotatedTextY(Text.s, Angle.f)
	Protected Result

	If Sin(Radian(Angle)) > 0
		Result - (Sin(Radian(Angle)) * TextWidth(Text))
	EndIf

	If Cos(Radian(Angle)) < 0
		Result + (Cos(Radian(Angle)) * TextHeight(Text))
	EndIf

	ProcedureReturn Result
EndProcedure

Procedure RotatedTextWidth(Text.s, Angle.f)
	ProcedureReturn Abs(Cos(Radian(Angle)) * TextWidth(Text)) + Abs(Sin(Radian(Angle)) * TextHeight(Text))
EndProcedure

Procedure RotatedTextHeight(Text.s, Angle.f)
	ProcedureReturn Abs(Sin(Radian(Angle)) * TextWidth(Text)) + Abs(Cos(Radian(Angle)) * TextHeight(Text))
EndProcedure

Procedure CreateTestImage()
	Protected X, Y, W, H

	CreateImage(#Image, Width, Height)


	StartDrawing(ImageOutput(#Image))
		DrawingFont(TextFontID)

		Box(0, 0, Width, Height, $000000)

		; Normal:
		X = NBoxX
		Y = NBoxY
		W = TextWidth(Text)
		H = TextHeight(Text)
		DrawingMode(#PB_2DDrawing_Transparent)
		DrawText(X, Y, Text, $FF00FF)
		DrawingMode(#PB_2DDrawing_Outlined)
		Box(X - 1, Y - 1, W + 2, H + 2, $800080)
		Circle(X, Y, 3, $800080)

		; Gedreht:
		X = GBoxX ;+ RotatedTextX(Text, GAngle)
		Y = GBoxY ;+ RotatedTextY(Text, GAngle)
		W = RotatedTextWidth(Text, GAngle)
		H = RotatedTextHeight(Text, GAngle)
		DrawingMode(#PB_2DDrawing_Transparent)
		DrawRotatedText(GBoxX, GBoxY, Text, GAngle, $FFFFFF) ;DrawRotatedText(X, Y, Text, GAngle, $FFFFFF)
		DrawingMode(#PB_2DDrawing_Outlined)
		Box(X - 1, Y - 1, W + 2, H + 2, $808080)
		Circle(X, Y, 3, $808080)
	StopDrawing()
EndProcedure



Width = 500 : Height = 200

Text = "| test |"
TextFontID = FontID(LoadFont(#PB_Any, "Arial", 20, #PB_Font_Bold | #PB_Font_HighQuality | #PB_Font_Italic | #PB_Font_StrikeOut))

NBoxX = 50 : NBoxY = 100
GBoxX = 300 : GBoxY = 100 : GAngle = 45


If OpenWindow(#Window, 0, 0, Width + 20, Height + 20, "DrawRotatedText Test", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
	ImageGadget(#ImageGadget, 10, 10, Width, Height, 0)

	AddWindowTimer(#Window, #Timer, 50)

	Repeat
		Select WaitWindowEvent()
			Case #PB_Event_Timer
				If EventTimer() = #Timer
					GAngle + 4  ; Text drehen
					CreateTestImage()
					SetGadgetState(#ImageGadget, ImageID(#Image))
				EndIf
			Case #PB_Event_CloseWindow
				Break
		EndSelect
	ForEver
EndIf
"Menschenskinder, das Niveau dieses Forums singt schon wieder!" — GronkhLP ||| "ich hogffe ihr könnt den fehle endecken" — Marvin133 ||| "Ideoten gibts ..." — computerfreak ||| "Jup, danke. Gruss" — funkheld
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7031
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: "Bounding-Box" von DrawRotatedText() ?

Beitrag von STARGÅTE »

Ist ja fast richtig, aber du hast in der Prozedur X und GBoxX verdreht:

Denn die Box soll ja immer bei GBoxX sein, und der Text dann verschoben um meine Prozedur.

Code: Alles auswählen

EnableExplicit

Enumeration 
   #Window
   #ImageGadget
   #Image
   #Timer
EndEnumeration

Global Width, Height
Global Text.s, TextFontID
Global NBoxX, NBoxY, GBoxX, GBoxY, GAngle.f


Procedure RotatedTextX(Text.s, Angle.f)
   Protected Result

   If Cos(Radian(Angle)) < 0
      Result + (Cos(Radian(Angle)) * TextWidth(Text))
   EndIf

   If Sin(Radian(Angle)) < 0
      Result + (Sin(Radian(Angle)) * TextHeight(Text))
   EndIf

   ProcedureReturn Result
EndProcedure

Procedure RotatedTextY(Text.s, Angle.f)
   Protected Result

   If Sin(Radian(Angle)) > 0
      Result - (Sin(Radian(Angle)) * TextWidth(Text))
   EndIf

   If Cos(Radian(Angle)) < 0
      Result + (Cos(Radian(Angle)) * TextHeight(Text))
   EndIf

   ProcedureReturn Result
EndProcedure

Procedure RotatedTextWidth(Text.s, Angle.f)
   ProcedureReturn Abs(Cos(Radian(Angle)) * TextWidth(Text)) + Abs(Sin(Radian(Angle)) * TextHeight(Text))
EndProcedure

Procedure RotatedTextHeight(Text.s, Angle.f)
   ProcedureReturn Abs(Sin(Radian(Angle)) * TextWidth(Text)) + Abs(Cos(Radian(Angle)) * TextHeight(Text))
EndProcedure

Procedure CreateTestImage()
   Protected X, Y, W, H

   CreateImage(#Image, Width, Height)


   StartDrawing(ImageOutput(#Image))
      DrawingFont(TextFontID)

      Box(0, 0, Width, Height, $000000)

      ; Normal:
      X = NBoxX
      Y = NBoxY
      W = TextWidth(Text)
      H = TextHeight(Text)
      DrawingMode(#PB_2DDrawing_Transparent)
      DrawText(X, Y, Text, $FF00FF)
      DrawingMode(#PB_2DDrawing_Outlined)
      Box(X - 1, Y - 1, W + 2, H + 2, $800080)
      Circle(X, Y, 3, $800080)

      ; Gedreht:
      X = GBoxX - RotatedTextX(Text, GAngle)
      Y = GBoxY - RotatedTextY(Text, GAngle)
      W = RotatedTextWidth(Text, GAngle)
      H = RotatedTextHeight(Text, GAngle)
      DrawingMode(#PB_2DDrawing_Transparent)
      DrawRotatedText(X, Y, Text, GAngle, $FFFFFF) ;DrawRotatedText(X, Y, Text, GAngle, $FFFFFF)
      DrawingMode(#PB_2DDrawing_Outlined)
      Box(GBoxX - 1, GBoxY - 1, W + 2, H + 2, $808080)
      Circle(GBoxX, GBoxY, 3, $808080)
   StopDrawing()
EndProcedure



Width = 500 : Height = 200

Text = "| test |"
TextFontID = FontID(LoadFont(#PB_Any, "Arial", 20, #PB_Font_Bold | #PB_Font_HighQuality | #PB_Font_Italic | #PB_Font_StrikeOut))

NBoxX = 50 : NBoxY = 100
GBoxX = 300 : GBoxY = 100 : GAngle = 45


If OpenWindow(#Window, 0, 0, Width + 20, Height + 20, "DrawRotatedText Test", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
   ImageGadget(#ImageGadget, 10, 10, Width, Height, 0)

   AddWindowTimer(#Window, #Timer, 50)

   Repeat
      Select WaitWindowEvent()
         Case #PB_Event_Timer
            If EventTimer() = #Timer
               GAngle + 4  ; Text drehen
               CreateTestImage()
               SetGadgetState(#ImageGadget, ImageID(#Image))
            EndIf
         Case #PB_Event_CloseWindow
            Break
      EndSelect
   ForEver
EndIf

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
c4s
Beiträge: 1235
Registriert: 19.09.2007 22:18

Re: "Bounding-Box" von DrawRotatedText() ?

Beitrag von c4s »

Danke STARGÅTE!
Du kennst das sicherlich: Manchmal ist die Lösung so offensichtlich und einfach, dass man sie einfach nicht bemerkt - Passiert mir leider viel zu häufig. :cry:
"Menschenskinder, das Niveau dieses Forums singt schon wieder!" — GronkhLP ||| "ich hogffe ihr könnt den fehle endecken" — Marvin133 ||| "Ideoten gibts ..." — computerfreak ||| "Jup, danke. Gruss" — funkheld
c4s
Beiträge: 1235
Registriert: 19.09.2007 22:18

Re: "Bounding-Box" von DrawRotatedText() ?

Beitrag von c4s »

Leider komme ich mit der Materie überhaupt nicht zurecht. Langes probieren hat nicht geholfen:
Ziel sind zwei (oder mehrere) Zeilen gedrehter Text, die immer untereinander sind. Ich habe dabei X1/Y1 des ersten Textes und X2/Y2 des Zweiten. Nun möchte ich diese beiden Positionen in das "DrawRotatedText()-System" umwandeln, sodass bei Winkel=0 dasselbe wie bei DrawText() herauskommen würde und im anderen Fall eben die korrekte Drehung gezeigt wird.

Ich hoffe es ist verständlich was ich meine. Kann mir jemand helfen?
"Menschenskinder, das Niveau dieses Forums singt schon wieder!" — GronkhLP ||| "ich hogffe ihr könnt den fehle endecken" — Marvin133 ||| "Ideoten gibts ..." — computerfreak ||| "Jup, danke. Gruss" — funkheld
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7031
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: "Bounding-Box" von DrawRotatedText() ?

Beitrag von STARGÅTE »

Es läuft eigentlich immer aufs selbe hinaus:
RotationsMatrix:

Code: Alles auswählen

NeuX = Cos(Winkel)*x - Sin(Winkel)*y
NeuY = Sin(Winkel)*x + Cos(Winkel)*y
Du übergibst also dort dein x,y (also die Differenz zwischen den beiden Texten) an diese Gleichung
und bekommst die neuen relativkoordinaten.


Im Beispiel habe ich das Vorzeichen von Sin() verändert, da DrawRotatedText() anscheind "andersrum" dreht, (als zB RotateSprite3D)

Code: Alles auswählen

CreateImage(0, 400, 400)
StartDrawing(ImageOutput(0))
  X = 200
  Y = 200
  Angle = 15
  dx = 0
  dy = 0
  Winkel.f = Radian(Angle)
  For Zeile = 1 To 10
    Neudx = Cos(Winkel)*dx + Sin(Winkel)*dy
    Neudy = -Sin(Winkel)*dx + Cos(Winkel)*dy
    DrawRotatedText(X+Neudx, Y+Neudy, "Zeile "+Str(Zeile), Angle, $FFFFFF)
    dx + 0;TextWidth("Z")
    dy + TextHeight("Z")
  Next  
StopDrawing() 

If OpenWindow(0, 0, 0, 400, 400, "2DDrawing Example", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  ImageGadget(0, 0, 0, 400, 400, ImageID(0))
  Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf 
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
c4s
Beiträge: 1235
Registriert: 19.09.2007 22:18

Re: "Bounding-Box" von DrawRotatedText() ?

Beitrag von c4s »

Entschuldigung, wenn ich mich zu doof anstelle, aber bitte nochmal erklären. :wink:

Beide (oder auch mehrere) gedrehte Textzeilen sollen sich in dem Rechteck drehen. Momentan ist es so, dass nur die erste mit Sicherheit immer im Rechteck ist. (Was müsste ich außerdem machen, wenn ich bereits feste Werte für die einzelnen Zeilen habe?)
Zur Veranschaulichung habe ich es nochmal in mein Beispiel eingefügt:

Code: Alles auswählen

;EnableExplicit

Enumeration
	#Window
	#ImageGadget
	#Image
	#Timer
EndEnumeration

Global Width, Height
Global Text.s, TextFontID
Global NBoxX, NBoxY, GBoxX, GBoxY, GAngle.f


Procedure RotatedTextX(Text.s, Angle.f)
	Protected Result

	If Cos(Radian(Angle)) < 0
		Result + (Cos(Radian(Angle)) * TextWidth(Text))
	EndIf

	If Sin(Radian(Angle)) < 0
		Result + (Sin(Radian(Angle)) * TextHeight(Text))
	EndIf

	ProcedureReturn Result
EndProcedure

Procedure RotatedTextY(Text.s, Angle.f)
	Protected Result

	If Sin(Radian(Angle)) > 0
		Result - (Sin(Radian(Angle)) * TextWidth(Text))
	EndIf

	If Cos(Radian(Angle)) < 0
		Result + (Cos(Radian(Angle)) * TextHeight(Text))
	EndIf

	ProcedureReturn Result
EndProcedure

Procedure RotatedTextWidth(Text.s, Angle.f)
	ProcedureReturn Abs(Cos(Radian(Angle)) * TextWidth(Text)) + Abs(Sin(Radian(Angle)) * TextHeight(Text))
EndProcedure

Procedure RotatedTextHeight(Text.s, Angle.f)
	ProcedureReturn Abs(Sin(Radian(Angle)) * TextWidth(Text)) + Abs(Cos(Radian(Angle)) * TextHeight(Text))
EndProcedure

Procedure CreateTestImage()
	Protected X, Y, W, H
	Protected X2, Y2
	Protected RadSin.f, RadCos.f

	CreateImage(#Image, Width, Height)


	StartDrawing(ImageOutput(#Image))
		DrawingFont(TextFontID)

		Box(0, 0, Width, Height, $000000)

		DrawingMode(#PB_2DDrawing_Transparent | #PB_2DDrawing_Outlined)
	
		; Normal Gedreht:
		X = NBoxX - RotatedTextX(Text, GAngle)
		Y = NBoxY - RotatedTextY(Text, GAngle)
		W = RotatedTextWidth(Text, GAngle)
		H = RotatedTextHeight(Text, GAngle)

		DrawRotatedText(X, Y, Text, GAngle, $FF00FF)
		Box(NBoxX - 1, NBoxY - 1, W + 2, H + 2, $800080)
		Circle(NBoxX, NBoxY, 3, $800080)


		RadSin = Sin(Radian(GAngle))
		RadCos = Cos(Radian(GAngle))

		; Gedreht Kombi:
		X = GBoxX
		Y = GBoxY
		W = Abs(RadCos * TextWidth(Text)) + Abs(RadSin * (TextHeight(Text)+40))
		H = Abs(RadSin * TextWidth(Text)) + Abs(RadCos * (TextHeight(Text)+40))

		DrawRotatedText(X - RotatedTextX(Text, GAngle), Y - RotatedTextY(Text, GAngle), Text, GAngle, $FFFFFF)

		; Gedreht Kombi Nr. 2:
		X2 = GBoxX + (RadCos*0 + RadSin*40)
		Y2 = GBoxY + (-RadSin*0 + RadCos*40)
		DrawRotatedText(X2 - RotatedTextX(Text, GAngle), Y2 - RotatedTextY(Text, GAngle), Text, GAngle, $FFFFFF)

		Box(GBoxX - 1, GBoxY - 1, W + 2, H + 2, $808080)
		Circle(GBoxX, GBoxY, 3, $808080)
	StopDrawing()
EndProcedure



Width = 500 : Height = 200

Text = "| test |"
TextFontID = FontID(LoadFont(#PB_Any, "Arial", 20, #PB_Font_Bold | #PB_Font_HighQuality | #PB_Font_Italic | #PB_Font_StrikeOut))

NBoxX = 50 : NBoxY = 50
GBoxX = 300 : GBoxY = 50 : GAngle = 45


If OpenWindow(#Window, 0, 0, Width + 20, Height + 20, "DrawRotatedText Test", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
	ImageGadget(#ImageGadget, 10, 10, Width, Height, 0)

	AddWindowTimer(#Window, #Timer, 50)

	Repeat
		Select WaitWindowEvent()
			Case #PB_Event_Timer
				If EventTimer() = #Timer
					GAngle + 4  ; Text drehen
					CreateTestImage()
					SetGadgetState(#ImageGadget, ImageID(#Image))
				EndIf
			Case #PB_Event_CloseWindow
				Break
		EndSelect
	ForEver
EndIf
"Menschenskinder, das Niveau dieses Forums singt schon wieder!" — GronkhLP ||| "ich hogffe ihr könnt den fehle endecken" — Marvin133 ||| "Ideoten gibts ..." — computerfreak ||| "Jup, danke. Gruss" — funkheld
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7031
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: "Bounding-Box" von DrawRotatedText() ?

Beitrag von STARGÅTE »

Jo dann brauchst du für den Fall n abänderung meiner Prozeduren:

Ohne siehts dann so aus:

Code: Alles auswählen

;EnableExplicit

Enumeration
   #Window
   #ImageGadget
   #Image
   #Timer
EndEnumeration

Global Width, Height
Global Text.s, TextFontID
Global NBoxX, NBoxY, GBoxX, GBoxY, GAngle.f


Procedure RotatedTextX(Text.s, Angle.f)
   Protected Result

   If Cos(Radian(Angle)) < 0
      Result + (Cos(Radian(Angle)) * TextWidth(Text))
   EndIf

   If Sin(Radian(Angle)) < 0
      Result + (Sin(Radian(Angle)) * TextHeight(Text))
   EndIf

   ProcedureReturn Result
EndProcedure

Procedure RotatedTextY(Text.s, Angle.f)
   Protected Result

   If Sin(Radian(Angle)) > 0
      Result - (Sin(Radian(Angle)) * TextWidth(Text))
   EndIf

   If Cos(Radian(Angle)) < 0
      Result + (Cos(Radian(Angle)) * TextHeight(Text))
   EndIf

   ProcedureReturn Result
EndProcedure

Procedure RotatedTextWidth(Text.s, Angle.f)
   ProcedureReturn Abs(Cos(Radian(Angle)) * TextWidth(Text)) + Abs(Sin(Radian(Angle)) * TextHeight(Text))
EndProcedure

Procedure RotatedTextHeight(Text.s, Angle.f)
   ProcedureReturn Abs(Sin(Radian(Angle)) * TextWidth(Text)) + Abs(Cos(Radian(Angle)) * TextHeight(Text))
EndProcedure

Procedure CreateTestImage()
   Protected X, Y, W, H
   Protected X2, Y2
   Protected RadSin.f, RadCos.f

   CreateImage(#Image, Width, Height)


   StartDrawing(ImageOutput(#Image))
      DrawingFont(TextFontID)

      Box(0, 0, Width, Height, $000000)

      DrawingMode(#PB_2DDrawing_Transparent | #PB_2DDrawing_Outlined)
   
      ; Normal Gedreht:
      X = NBoxX - RotatedTextX(Text, GAngle)
      Y = NBoxY - RotatedTextY(Text, GAngle)
      W = RotatedTextWidth(Text, GAngle)
      H = RotatedTextHeight(Text, GAngle)

      DrawRotatedText(X, Y, Text, GAngle, $FF00FF)
      Box(NBoxX - 1, NBoxY - 1, W + 2, H + 2, $800080)
      Circle(NBoxX, NBoxY, 3, $800080)


      RadSin = Sin(Radian(GAngle))
      RadCos = Cos(Radian(GAngle))

      ; Gedreht Kombi:
      X = GBoxX
      Y = GBoxY
      W = Abs(RadCos * TextWidth(Text)) + Abs(RadSin * (TextHeight(Text)+40))
      H = Abs(RadSin * TextWidth(Text)) + Abs(RadCos * (TextHeight(Text)+40))

      If RadCos < 0
        X - RadCos * TextWidth(Text)
      EndIf
      If RadSin < 0
        X - RadSin * (TextHeight(Text)+40)
      EndIf
      If RadSin > 0
        Y + RadSin * TextWidth(Text)
      EndIf
      If RadCos < 0
        Y - RadCos * (TextHeight(Text)+40)
      EndIf

      DrawRotatedText(X, Y, Text, GAngle, $FFFFFF)

      ; Gedreht Kombi Nr. 2:
      X + (RadCos*0 + RadSin*40)
      Y + (-RadSin*0 + RadCos*40)
      DrawRotatedText(X, Y, Text, GAngle, $FFFFFF)

      Box(GBoxX - 1, GBoxY - 1, W + 2, H + 2, $808080)
      Circle(GBoxX, GBoxY, 3, $808080)
   StopDrawing()
EndProcedure



Width = 500 : Height = 200

Text = "| test |"
TextFontID = FontID(LoadFont(#PB_Any, "Arial", 20, #PB_Font_Bold | #PB_Font_HighQuality | #PB_Font_Italic | #PB_Font_StrikeOut))

NBoxX = 50 : NBoxY = 50
GBoxX = 300 : GBoxY = 50 : GAngle = 45


If OpenWindow(#Window, 0, 0, Width + 20, Height + 20, "DrawRotatedText Test", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
   ImageGadget(#ImageGadget, 10, 10, Width, Height, 0)

   AddWindowTimer(#Window, #Timer, 50)

   Repeat
      Select WaitWindowEvent()
         Case #PB_Event_Timer
            If EventTimer() = #Timer
               GAngle + 4  ; Text drehen
               CreateTestImage()
               SetGadgetState(#ImageGadget, ImageID(#Image))
            EndIf
         Case #PB_Event_CloseWindow
            Break
      EndSelect
   ForEver
EndIf 
Breite und Höhe der Box ergeben sich, wie du richtig erkannt hast eben aus der neuen Mehrzeiligen Höhe.
Das gilt dnan auch für die Verschiebungen.
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
Antworten