Sphere durch 3 radien bestimmen

Übersicht BlitzMax, BlitzMax NG Allgemein

Neue Antwort erstellen

 

PhillipK

Betreff: Sphere durch 3 radien bestimmen

BeitragSa, Nov 03, 2012 13:35
Antworten mit Zitat
Benutzer-Profile anzeigen
Huhu!

Ich habe zurzeit wieder meine sucht nach minecraft gefunden, und dachte mir, es ist doch öde, alles selbst zu machen Smile
Darum hab ich kurzerhand ein mc-plugin gebastelt, welches mit ein eigenes Dateiformat lädt, welches ich nun mit Blitzmax zu füllen gedenke.
Warum? Java suckt, blitzmax rockt.

Ein paar simple Grundformen, sowie eine 3d Bezierkurve konnte ich bereits einspeisen. Aber an einer sache verzweifel ich ganz massiv:
Eine Sphere, welche durch 3 statt einem Radius beeinflusst wird.
Mein ansatz war, mir das ganze als 3 eigene Flächen vorzustellen (x+y, x+z, y+z) und je einen Abstandscheck zur mitte zu machen. Das ganze war per Pythagoras gelöst.
Am ende kam etwas undefinierbares zustande, eine art würfel mit ausgebeulten flächen..

Da ich nie etwas vergleichbares in der Schule hatte, bin ich nun ein wenig aufgeschmissen... Wikipedia lässt mich auch im stich =)

Darum nun meine frage:
Wie bestimme ich die randpunkte eines "3d ovals" (beeinflusst durch 3 Radien)?
3d Sphere (1 radius) klappt recht gut, ist ja auch nicht weiter schwer =D
Ich meine damit sowas http://de.wikipedia.org/w/inde...0304171907 als Volumetrische figur.

Hier meine beiden helferlein (hihi, simpler Pythagoras!)
BlitzMax: [AUSKLAPPEN]
Function Pythagoras:Double(x1:Double, y1:Double, x2:Double, y2:Double)
Return Sqr(((x2 - x1) * (x2 - x1)) + ((y2 - y1) * (y2 - y1)))
End Function
Function Pythagoras3d:Double(x1:Double, y1:Double, z1:Double, x2:Double, y2:Double, z2:Double)
Return Sqr(((x2 - x1) * (x2 - x1)) + ((y2 - y1) * (y2 - y1)) + ((z2 - z1) * (z2 - z1)))
End Function


Sowie die sphere:
(ansätze waren vorhanden, aber nie ausgearbeitet... r1,r2,r3 stellt die gewünschten radien dar.)
BlitzMax: [AUSKLAPPEN]
	Method debugSphere:Int(_id:Byte, _data:Byte, r1:Float, r2:Float = 0, r3:Float = 0)
If r2 = 0 Then r2 = r1
If r3 = 0 Then r3 = r1


Local cx:Float = w / 2.0
Local cY:Float = h / 2.0
Local cz:Float = d / 2.0


For Local x:Int = 0 Until w
For Local y:Int = 0 Until h
For Local z:Int = 0 Until d
If (Pythagoras3d(cx, cY, cz, x, y, z) <= r1) Then
ids[x][y][z] = _id
data[x][y][z] = _data
End If
Next
Next
Next
End Method

-> Das ganze geht einen array durch und überprüft jeden punkt, ob er "innerhalb" der gewünschten Sphere liegt (pythagoras). Ergebnis top, auch als voxeldarstellung. Aber die deformierbarkeit ist nicht vorhanden, da ich keine ahnung habe, wie ich einen zusammenhand zwischen Cx,cy,cz & x,y,z sowie den radien r1,r2,r3 knüpfe.

Irgendwelche ideen? Smile (idee reicht mir! Selbst erarbeiten bringt das wissen Smile )
 

Boris1993

BeitragDi, Nov 06, 2012 19:18
Antworten mit Zitat
Benutzer-Profile anzeigen
wie soll denn die kreisform später aussehen? schalenartig? Very Happy
meine Idee wäre jedem Radius einen Vektor zuzuweisen vec_r1 = [1, 0, 0], vec_r2 = [0, 1, 0]...
und dann je nach koordinate iwie einen mischradius aus den drei rausbekommen mit den vektoren multiplizieren oder so in der art Smile
übrigens eine coole idee ein minecraft plugin mit bmax zu schreiben
 

PhillipK

BeitragDi, Nov 06, 2012 20:05
Antworten mit Zitat
Benutzer-Profile anzeigen
Hihi, nein versteh mich nicht falsch. Das MC plugin ist schön oldskool in Java geschrieben. Diehnt eigentlich nur als vermittler zwischen BMX und JAVA.
Plan ist eher, eine art Pattern-Editor zu schreiben.

Das ganze hat seit meiner frage schon deutlich mehr gesicht bekommen, aber das ist ein anderes Thema.

Das mit der Vektormultiplikation klingt irgendwie auch sinnig..
Mal schaun, wie wär das dann?

Von mittelpunkt einen vektor zum koordinaten paar ziehen. Dieser gibt die "richtung" an, und auf länge 1 gebracht, enthält dieser die wunsch-anteile an den radien-päärchen.. Somit kann ich die teilradien errechnen und addieren.
Okay, im kopf klingts sinnig, aber ich hab keine ahnung, was ich da laber ~.~

Aber eine idee ist entstanden, danke!

Weitere ideen?

Mal kurz pseudocode zur idee im kopf:

BlitzMax: [AUSKLAPPEN]

Function CheckPoint:Int(pos:Vector3, center:Vector3, radien:Vector3)
'vektor3 ist eine klasse, die ich aus dem Codearchiv geklaubt und erweitert habe.
'center zeigt auf den mittelpunkt der zu zeichnenden Sphere
'radien enthält die ausdehnungen der sphere in richtung x,y,z

Local dir:Vector3 = Vector3.Subtract(center,pos)
'dir ist die richtung vom Zentrum zur Koordinate.

dir = Vector3.Divide(dir, dir.absolute())
'dir ist nun normalisiert, bzw auf länge 1 gebracht

´ Local total:Float = ((dir.x*radien.x) + (dir.y*radien.y) + (dir.z * radien)) '/3.0 <- eventuell durch drei teilen?
'Idee ist, das total nun der "mischradius" ist, von dem Boris1993 gesprochen hat.
'So vom kopf her könnte das funktionieren...

Return Pythagoras3D(pos.x,pos.y,pos.z, center.x,center.y,center.z) <= total
End Function


-> Wenn ich obenstehenden pseudocode pro koordinate aufrufe, würde das klappen? Die funktion soll mir 1 zurückgeben, wenn die koordinate "innerhalb" der gewünschten sphere liegt.
Center ist bekannt, normalerweise width/2, height/2, depth /2.
Position würde ich anhand von 3 verschachtelten forschleifen (x,y,z) rausfinden. Radien wird anfangs definiert.. Hm =)

Ich kann es leider grade nicht ausprobieren, da ich meinen visualisierer zerschossen habe -.- Muss das erstmal flicken, bevor ich das ganze "schön easy" testen kann Sad
 

Boris1993

BeitragMi, Nov 07, 2012 21:15
Antworten mit Zitat
Benutzer-Profile anzeigen
Das ist bei mir immer genauso^^ Erstmal entsteht diese Idee und man hat eine Bildliche Vorstellung davon im Kopf und denkt sich nichts leichter als das. Dann will man anfangen aber hat keinen Plan wie Very Happy
Am besten ist es dann immer erstmal ganz klein anzufangen zum beispiel erstmal in 2d, weil mans sich leichter vorstellen kann. Wenn man nur genug geduld für eine Idee hat und klein anfängt dann kann man Sachen hinbekommen bei denen man voher nie gedacht hätte das man das hinbekommt.

Teste dochmal deine Methode an einem schnell geschriebenen Visualizer aus. Ich mach sowas immer mit GL_Points um mir mal zu veranschaulichen wie das aussehen würde.

ZEVS

BeitragMi, Nov 07, 2012 21:32
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich würde das wie folgt lösen:
Bei einer Ellipse, wie du sie im ersten Post verlinkt hast, lässt sich jeder Punkte P wie folgt schreiben:
Code: [AUSKLAPPEN]
P(b*sin(a) | h*cos(a)) (für einen Winkel a und b/h als Breite/Höhe der Ellipse)

(Beweise sind hier nicht so mein Ding). D.h., für jeden relevanten Z-Wert musst du nur noch den Winkel a in geeigneter Weise iterieren und die bekommst eine Ellipse für die X/Y-Werte hier, bei der die Punkte gleichmäßig verteilt sind. Wenn du die Z-Werte nun auch Sinusförmig iterierst, solltest du am Ende auf ein 3D-Oval kommen. Pseudocode:
Code: [AUSKLAPPEN]
Schleife: alpha = 0 -> 180° / Pi (je nach Bogen/Gradmaß)
   z = cos(alpha)*Tiefe
   Schleife: beta: 0 -> 360° / 2Pi
      x = sin(beta)*Breite
      y = cos(beta)*Höhe
      [Voxel erstellen]

Ich hoffe mal, dass die Sache so gleichverteilt wird, wie ich mir das vorstelle. Bezüglich der Schrittweiten kann ich auch keine Formeln liefern.

ZEVS

EDIT: Mir ist noch eine Lösung eingefallen, die wohl eher passt:
Ein von dir gewünschtes Objekt erhält man in B3D wohl einfach dadurch, dass man eine Kugel mit CreateSphere erstellt und mit ScaleEntity/ScaleMesh verzerrt. Hierbei werden alle Koordinaten mit der Länge des Radius multipliziert. Wenn du diesen Vorgang rückgängig machen willst, musst du die Koordinaten durch den Radius dividieren:
Der Voxel ist im Objekt, wenn gilt: Pythagoras3D(x/b, y/h, z/t) <= 1 (x,y,z: Vektor zur Mitte, b,h,t: Radien)

Neue Antwort erstellen


Übersicht BlitzMax, BlitzMax NG Allgemein

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group