Geometrisches Problem

Fragen zu Grafik- & Soundproblemen und zur Spieleprogrammierung haben hier ihren Platz.
Benutzeravatar
memdee
Beiträge: 134
Registriert: 09.09.2004 18:49
Computerausstattung: Win 7 x64
Wohnort: Wiesbaden
Kontaktdaten:

Geometrisches Problem

Beitrag von memdee »

Ahoi,

ich hätte da ein Problem, bei dem ich nicht recht weiterkomme, und zwar folgendes:

Ich habe ein gleichseitiges Dreieck, bei dem jede Ecke einen Wirtschaftssektor für eine Steuerlastverteilung repräsentiert, etwa so:
Bild
Bei einem Linksklick auf einen Punkt innerhalb des Dreiecks zeichne ich eine Box. Nun soll anhand des Abstandes zwischen dieser Box und der jeweiligen Ecke die anteilsmäßige Steuerlast errechnet werden (ist die Box also genau im Mittelpunkt, sollte sich eine Verteilung von 33/33/33 ergeben, bei einem Klick in die linke, untere Ecke eine Verteilung von 100-0-0 usw.).
Die Entfernung in Pixel zwischen Box und jeweiliger Ecke kriege ich noch hin, kein Problem. Aber wie rechne ich diese Entfernung in % der Gesamtsteuerlast um, so dass die Summe der Verteilung immer 100% ergibt? Zwischen zwei Punkten, kein Ding, aber sobald der dritte dazu kommt, übersteigt es meine bescheidene mathematische Kompetenz.
Der Code, den ich bisher habe, würde wohl nicht weiterhelfen, es kommt am Ende nur Mist raus.

Jede Anregung wird dankend angenommen.
meep?
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Re: Geometrisches Problem

Beitrag von Kaeru Gaman »

das ist wieder so ein arboretisches Problem, denke ich.

also, du addierst zuerst die drei Werte, dann hast du die Gesamtlänge die 100% repräsentiert.
das kannst du durch hundert teilen, um 1% zu bekommen, dann teilst du alle drei werte für sich durch diese 1%.
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7028
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: Geometrisches Problem

Beitrag von STARGÅTE »

Es kommt aber auf den Flächeninhalt an.

Erst mal, das Dreieck muss nicht gleichseitig sein.
100% = gesammter Flächeninhalt.
Anteil je Ecke = Flächeninhalt der gegenüberliegnden Fläche (begrenz durch Seite und der beiden verbindungslinien)

fertig.. ich schreibe mal eben n keine procedure...
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
memdee
Beiträge: 134
Registriert: 09.09.2004 18:49
Computerausstattung: Win 7 x64
Wohnort: Wiesbaden
Kontaktdaten:

Re: Geometrisches Problem

Beitrag von memdee »

Kaeru Gaman hat geschrieben:das ist wieder so ein arboretisches Problem, denke ich.
arbo-WAS? :shock:
also, du addierst zuerst die drei Werte, dann hast du die Gesamtlänge die 100% repräsentiert.
das kannst du durch hundert teilen, um 1% zu bekommen, dann teilst du alle drei werte für sich durch diese 1%.
Vielen Dank.
Damit errechne ich ja quasi den Umkehrwert des gewünschten Ergebnisses (Box bei "Landwirtschaft": 0-50-50 statt 100-0-0). Stehe auf dem Schlauch: wie kehr ich das um? Bei zwei Punkten, klar: 100 - (Länge/1%)

Ich entschuldige mich ausdrücklich für mein fehlendes mathematisches Verständnis (keine Sorge, ich habe nicht vor, beruflich zu programmieren ;) )

edit: Ah, der Flächeninhalt. Ein entfernter Bekannter...
meep?
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Re: Geometrisches Problem

Beitrag von Kaeru Gaman »

http://de.wikipedia.org/wiki/Arboretum
Ein arboretisches Problem nennt man das, wenn die Bäume den Blick auf den Wald versperren.

also
Die Entfernung in Pixel zwischen Box und jeweiliger Ecke kriege ich noch hin, kein Problem.
schrobst du obent.

nun, diese drei entfernungen addierst du, das sind deine 100%. wo ist da der Haken?

mit Flächeninhalt hat das nix zu schigge, du hast ausdrücklich definiert:
Nun soll anhand des Abstandes zwischen dieser Box und der jeweiligen Ecke die anteilsmäßige Steuerlast errechnet werden
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Benutzeravatar
memdee
Beiträge: 134
Registriert: 09.09.2004 18:49
Computerausstattung: Win 7 x64
Wohnort: Wiesbaden
Kontaktdaten:

Re: Geometrisches Problem

Beitrag von memdee »

Kaeru Gaman hat geschrieben: mit Flächeninhalt hat das nix zu schigge, du hast ausdrücklich definiert:
Nun soll anhand des Abstandes zwischen dieser Box und der jeweiligen Ecke die anteilsmäßige Steuerlast errechnet werden
Das habe ich in meinem jugendlichen Leichtsinn so dahergesagt, schätze ich :D Sorry. Die gewünschten Ergebnisse bekomme ich anhand des Abstandes offenbar nicht... :roll: Sinnvoller scheint mir da doch der Ansatz mit dem Flächeninhalt zu sein. Ich probier mal ein bisschen rum.

PS: das "arboretische Problem" merk ich mir :allright:
meep?
Christian+
Beiträge: 213
Registriert: 13.07.2008 10:05
Computerausstattung: Windows 8.1 Pro
AMD Phenom II X4 955 @ 3.2 GHz
4GB RAM
NVIDIA GeForce GTX 660

Re: Geometrisches Problem

Beitrag von Christian+ »

Ich würde auch den Abstand zu den 3 Ecken des Dreieck ermitteln und das dann ausrechnen wie viel Prozent das ausmacht da es einfacher sein dürfte wenn in der Ecke 100 sein soll dann müsste das ungefähr so funktionieren glaube ich.
(habe ich nicht getestet wäre halt mein Ansatz das Problem zu lösen)

Code: Alles auswählen

prozent1=100.0/(abstand1+abstand2+abstand3)*((abstand2+abstand3)-abstand1)
prozent2=100.0/(abstand1+abstand2+abstand3)*((abstand1+abstand3)-abstand2)
prozent3=100.0/(abstand1+abstand2+abstand3)*((abstand1+abstand2)-abstand3)
mfg Christian+
Windows 8.1 Pro 64Bit | AMD Phenom II X4 955 @ 3.2 GHz | 4GB RAM | NVIDIA GeForce GTX 660
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7028
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: Geometrisches Problem

Beitrag von STARGÅTE »

Hier ein Beispiel mit Flächeninhalt :

Code: Alles auswählen

Structure Point2D
 x.f
 y.f
EndStructure
Structure Triangle
 Point2D.Point2D[3]
 Area.f
EndStructure
Global Triangle.Triangle

Procedure TriangleArea(*Triangle.Triangle)
 With *Triangle
  Protected v0.f = Sqr(Pow(\Point2D[1]\x-\Point2D[2]\x,2)+Pow(\Point2D[1]\y-\Point2D[2]\y,2))
  Protected v1.f = Sqr(Pow(\Point2D[0]\x-\Point2D[2]\x,2)+Pow(\Point2D[0]\y-\Point2D[2]\y,2))
  Protected v2.f = Sqr(Pow(\Point2D[0]\x-\Point2D[1]\x,2)+Pow(\Point2D[0]\y-\Point2D[1]\y,2))
  Protected Gamma.f = ACos( - (v0*v0-v1*v1-v2*v2) / (2*v1*v2) )
  ProcedureReturn 0.5*v1*v2*Sin(Gamma)
 EndWith
EndProcedure

Procedure CreateTriangle(x1.f, y1.f, x2.f, y2.f, x3.f, y3.f)
 *Triangle.Triangle = AllocateMemory(SizeOf(Triangle))
 With *Triangle
  \Point2D[0]\x = x1
  \Point2D[0]\y = y1
  \Point2D[1]\x = x2
  \Point2D[1]\y = y2
  \Point2D[2]\x = x3
  \Point2D[2]\y = y3
  \Area = TriangleArea(*Triangle)
 EndWith
 ProcedureReturn *Triangle
EndProcedure

Procedure.f GetTriangleFactor(*Triangle.Triangle, x.f, y.f, Angle)
 Protected SavePoint2D.Point2D, Area.f
 With *Triangle
  SavePoint2D\x = \Point2D[Angle]\x
  SavePoint2D\y = \Point2D[Angle]\y
  \Point2D[Angle]\x = x
  \Point2D[Angle]\y = y
  Area = TriangleArea(*Triangle)
  \Point2D[Angle]\x = SavePoint2D\x
  \Point2D[Angle]\y = SavePoint2D\y
  ProcedureReturn Area / \Area
 EndWith
EndProcedure





InitSprite()

xP = 400
yP = 400

OpenWindow(0, 0, 0, xP, yP, "SCREEN", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
OpenWindowedScreen(WindowID(0), 0, 0, xP, yP, 0, 0, 0)
 
 
 *Triangle.Triangle = CreateTriangle(200+Cos(0)*150,200+Sin(0)*150, 200+Cos(#PI*2/3)*150,200+Sin(#PI*2/3)*150, 200+Cos(-#PI*2/3)*150,200+Sin(-#PI*2/3)*150)


Repeat

 Event = WindowEvent()

 ClearScreen(0)
 
 x = WindowMouseX(0)
 y = WindowMouseY(0)

 StartDrawing(ScreenOutput())
  DrawingMode(1)
  With *Triangle
   For n = 0 To 2
    LineXY(\Point2D[n]\x, \Point2D[n]\y, \Point2D[(n+1)%3]\x, \Point2D[(n+1)%3]\y, $FFFFFF)
    LineXY(\Point2D[n]\x, \Point2D[n]\y, x, y, $808080)
    DrawText(\Point2D[n]\x, \Point2D[n]\y, Str(n+1), $00FFFF)
   Next
  EndWith
  Circle(x,y,10,$0000FF)
  For n = 0 To 2
   DrawText(300,n*30, "Ecke"+Str(n+1)+" ist :"+StrF(GetTriangleFactor(*Triangle, x, y, n)*100,0)+"%", $00FF00)
  Next
 StopDrawing()

 FlipBuffers()

Until Event = #PB_Event_CloseWindow
Klar das außerhalb des Dreiecks über 100% zustande kommt, aber das kannst du ja sicher selber noch fixen
Innerhalb des Dreiecks geht alles so wie du es möchtest.
In der mitte alle 0.333 , an den ecke, die jeweilige Ecke 1.0
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
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Re: Geometrisches Problem

Beitrag von Kaeru Gaman »

memdee hat geschrieben:Die gewünschten Ergebnisse bekomme ich anhand des Abstandes offenbar nicht...
wer sagt das? Bild

hier ist mein Ansatz mal ausgeschrieben.

Code: Alles auswählen

EnableExplicit

InitSprite()
InitMouse()
InitKeyboard()

OpenScreen( 1024,768, 32, "Arboretum" )
  MouseLocate( 512, 560 )

Define Punkt1_X.l =  512
Define Punkt1_Y.l =   30
Define Punkt2_X.l =   12
Define Punkt2_Y.l =  737
Define Punkt3_X.l = 1012
Define Punkt3_Y.l =  737

Define Maus_X.l
Define Maus_Y.l

Define Abstand1_X.l
Define Abstand1_Y.l
Define Abstand1.d

Define Abstand2_X.l
Define Abstand2_Y.l
Define Abstand2.d

Define Abstand3_X.l
Define Abstand3_Y.l
Define Abstand3.d

Define EinProzent.d
Define Prozent1.d
Define Prozent2.d
Define Prozent3.d

Repeat
  ExamineKeyboard()
  ExamineMouse()
    Maus_X = MouseX()
    Maus_Y = MouseY()

  Abstand1_X = Maus_X - Punkt1_X
  Abstand1_Y = Maus_Y - Punkt1_Y
  Abstand1   = Sqr( Abstand1_X * Abstand1_X + Abstand1_Y * Abstand1_Y )

  Abstand2_X = Maus_X - Punkt2_X
  Abstand2_Y = Maus_Y - Punkt2_Y
  Abstand2   = Sqr( Abstand2_X * Abstand2_X + Abstand2_Y * Abstand2_Y )

  Abstand3_X = Maus_X - Punkt3_X
  Abstand3_Y = Maus_Y - Punkt3_Y
  Abstand3   = Sqr( Abstand3_X * Abstand3_X + Abstand3_Y * Abstand3_Y )

  EinProzent = ( Abstand1 + Abstand2 + Abstand3 ) / 100.0

  Prozent1 = Abstand1 / EinProzent
  Prozent2 = Abstand2 / EinProzent
  Prozent3 = Abstand3 / EinProzent

  ClearScreen( $201008 )
    StartDrawing( ScreenOutput() )
      LineXY( Punkt1_X, Punkt1_Y, Punkt2_X, Punkt2_Y, $2040C0 )
      LineXY( Punkt2_X, Punkt2_Y, Punkt3_X, Punkt3_Y, $2040C0 )
      LineXY( Punkt3_X, Punkt3_Y, Punkt1_X, Punkt1_Y, $2040C0 )
      LineXY( Punkt1_X, Punkt1_Y, Maus_X, Maus_Y, $C08020 )
      LineXY( Punkt2_X, Punkt2_Y, Maus_X, Maus_Y, $C08020 )
      LineXY( Punkt3_X, Punkt3_Y, Maus_X, Maus_Y, $C08020 )
    DrawingMode( #PB_2DDrawing_Transparent )
    FrontColor( $20C080 )
      DrawText(  0,  0, "Abstand1:" )
      DrawText( 10, 16, StrD(Abstand1,2) +"pix" )
      DrawText( 10, 32, StrD(Prozent1,2) +"%" )
      DrawText(  0, 48, "Abstand2:" )
      DrawText( 10, 64, StrD(Abstand2,2) +"pix" )
      DrawText( 10, 80, StrD(Prozent2,2) +"%" )
      DrawText(  0, 96, "Abstand3:" )
      DrawText( 10,112, StrD(Abstand3,2) +"pix" )
      DrawText( 10,128, StrD(Prozent3,2) +"%" )
      DrawText(  0,144, "Gesamtabstand: " + Str( Abstand1 + Abstand2 + Abstand3 ) )
      DrawText(  0,160, "Ein Prozent: " + StrD( EinProzent ) )
    StopDrawing()
  FlipBuffers()  
Until KeyboardPushed( #PB_Key_Escape )
zum mitlesen, die berechnung noch mal zitiert:
EinProzent = ( Abstand1 + Abstand2 + Abstand3 ) / 100.0

Prozent1 = Abstand1 / EinProzent
Prozent2 = Abstand2 / EinProzent
Prozent3 = Abstand3 / EinProzent
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7028
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: Geometrisches Problem

Beitrag von STARGÅTE »

jo geht auch, das ist nun aber genau das "invertierte"

Wenn man auf in eine Ecke geht, bekommt man dort 0% die beidne anderen haben 50%
Problem bei dir, du kannst einem Abzweig nie 100% geben!

Bei mir ist das durchaus möglich, und wenn man in einer ecke ist, hat diese Ecke 100%, ist man genau auf einer Seite, hat die gegenüberliegende Ecke 0%

Soll memdee was besser ist ^^
Zuletzt geändert von STARGÅTE am 27.10.2009 19:48, insgesamt 1-mal geändert.
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