# Exakte Position auf Kugel mit Maus picken , Java3d



## Miller (12. Feb 2007)

Hi,
Ich habe ein grobes Gitternetz von einer Kugel um den Nullpunkt gezeichnet. Ich möchte gerne sowas wie ein Mauszeiger erstellen nur das dieser sich nicht auf den angenäherten Flächen, die man ja durch das grobe Gitternetz erstellen kann, bewegt sonder exakt auf der Kugeloberfläche. Kann man irgentwie eine sozusagen "perfekte" Kugel erstellen diese aber nicht Zeichnen lassen, so dass diese nicht allzu viele Ressourcen frist, und dann da wie im Thread  voher beschrieben eine Intersection Point bestimmen ? 
Also eigentlich geht es nur um die Unsichtbare, nicht Ressourcen fressende Kugel, aber wenn mir einer das nochmal mit dem Intersection Point und PickCanvas erklärt, da ich dazu nicht wirklich etwas, was für mich verständlich ist, finde, erklärt, bin ich darum nicht böse  


MFG


----------



## Miller (13. Feb 2007)

Hi,
habe gerade Hier gefunden wie man den schnittpunkt einer kugel mit einer Geraden berechnet.  
Da mir jetzt nur noch die Gerade vom Auge durch die Maus fehlt, stellt sich die Frage wie bekomm ich die von java3d ? 
Wie gesagt wäre nicht böse um eine Ausfürlichere variante, denn ich such mich halb tod nach einem Beispiel oder einer Erklärung 
wie man die Koordinaten des Punktes bekommt wenn man mit der mouse drauf klick! 


MFG Miller


----------



## Miller (14. Feb 2007)

Moin,
Keiner eine Ahnung wie man die Gerade bekommt/berechnet ?

MFG Miller


----------



## Illuvatar (14. Feb 2007)

Vielleicht hilft dir das weiter. Code (von der Seite kopiert):


```
private PickRay createPickRay(Canvas3D canvas, int x, int y)
{
  Point3d eye_pos = new Point3d();
  Point3d mouse_pos = new Point3d();

  canvas.getCenterEyeInImagePlate(eye_pos);
  canvas.getPixelLocationInImagePlate(x, y, mouse_pos);

  Transform3D motion = new Transform3D();
  canvas.getImagePlateToVworld(motion);
  motion.transform(eye_pos);
  motion.transform(mouse_pos);

  Vector3d direction = new Vector3d(mouse_pos);
  direction.sub(eye_pos);

  return new PickRay(eye_pos, direction);
}
```


----------



## Miller (16. Feb 2007)

Hi,
Danke! funktioniert super leider hab ich jetzt noch ein anderes Problem. Meine Funktion den Schnittpunkt auszurechnen sieht so aus:

```
private Point3d rayHitSphere(Vector3d o,Vector3d d,Vector3d m,double r){
// m = mittelpunkt der Kugel, r = radius der Kugel
// o = ursprung der Geraden
// d = direction der Gerade	
	
                d.normalize();
		
	double a = 2*(d.x*(o.x-m.x)+d.y*(o.y-m.y)+d.z*(o.z-m.z));
	double b = ((o.x-m.x)*(o.x-m.x))+
		((o.y-m.y)*(o.y-m.y))+
		((o.z-m.z)*(o.z-m.z))-(r*r);
		
		
	double s = ((-1*a)/2)-Math.sqrt(((a*a)/4)-b);
	if(Double.isNaN(s))
		return new Point3d(0,0,0);
		
		
	o.add(new Vector3d(d.x*s,d.y*s,d.z*s));
		
	return new Point3d(o.x,o.y,o.z);
}
```
Hab den code von der Seite die ich oben erwähnt habe.
Da ich aber jetzt die Kugel Rotiere und sich die "virtuelle" Kugel nicht mitdreht. Ist der Schnittpunkt immer auf der Gleichen seite der Kugel.
Wie kann man die Direction anpassen ?
Oder das Problem wäre auch glaub dadurch gelöst wenn ich die Kamera um die Kugel Dreh und nicht die Kugel selber. Da ich nur dieses ein Object habe ist das in diesem fall egal. 

MFG Miller


----------



## Illuvatar (16. Feb 2007)

Also die zweite Methode, dass du die Kamera um die Kugel drehst, ist eindeutig das einfachste, denke ich. Ansonsten könntest du dir vielleicht mit getLocalToVWorld (oder so ähnlich) etwas basteln, um das umzurechnen, wo der Punkt denn jetzt auf der eigentlichen Kugel liegt.

Wenn es eine ganz simple Rotation ist, sollte es aber vielleicht auch mit Winkel + Winkelfunktionen gehen.


----------



## Miller (16. Feb 2007)

Hi, 
hab mich dafür entschieden die Camera zu drehen.
Aber da ich recht neu bin in java3D hab ich keine Ahnung wie. Und Google & Co. haben auch nichts genaues ausgespuckt.
Kann mir evtl einer ein guten Link zu dem Thema geben oder es erklären am besten mit ein paar zeilen Code.
Außerdem müsste ich auch noch Zoomen also alles was ich bisher mit MouseRotate und MouseZoom gemacht habe.

MFG Miller


----------



## Illuvatar (17. Feb 2007)

Ich denke, das sollte alles recht einfach mit einem OrbitBehavior zu machen sein.


```
OrbitBehavior orbit = new OrbitBehavior(c3d);  //OrbitBehavior liegt in dem Paket com.sun.j3d.utils.behaviors.vp 
      orbit.setSchedulingBounds (new BoundingSphere ()); 
      simpleU.getViewingPlatform().setViewPlatformBehavior (orbit);
```

Siehe hier


----------



## Miller (17. Feb 2007)

Hi, danke!
Leider funktioniert das nicht wenn man die Kamera dreht. Die Effekte sind wirklich komisch.
Deshalb möchte ich gerne nun den Punkt im Abstand des Radiuses um den Ursprung drehen.
Zur Funktion getLocalToVWorld hab ich nichts brauchbares Gefunden.
Wie Bekomme ich denn die Momentate Rotation eines Objects und wie lass ich nun einen Punkt genauso viel Rotieren ?


MFG Miller


----------



## Miller (17. Feb 2007)

Hi, das ist mir jetzt unangenehm, neben meiner Rechtschreibung ^^.
Bei der Methode mit der Camera müsste ich einfach die Kugel und 90 Grad um die X Achse drehen damit die Koordianten alle wieder stimmen. Außerdem ist es irgentwie Ruckel freier die Kamera zu drehen als die Kugel.
Aber leider bekomme ich es nicht hin einfach die Kugel um 90 Grad gedreht anzuzeigen.
Hab eine TransformGroup erstellt und da dann mit einer Instanz von Transform3D initialisiert, bei der Ich voher die Methode rotX(90) aufgerufen habe. Aber selbst wenn ich 90 Grad in Bogenmaß oder sonstwie aufrufe es Passiert nichts.
Am ende Füge ich die TransformGroup der BranchGroup hinzu, aber ohne ergebnis. Nichts dreht sich.
Und wieder einmal hab ich nichts gefunden , und wenn dann waren das irgentwelche Interpolatoren für Animationen oder so.
Wie drehe ich denn jetzt einfach die Kugel quasie "per Hand"?

MFG


----------



## Illuvatar (17. Feb 2007)

Das ist theoretisch die korrekte Methode. Zeig mal deinen Code (ausschnittsweise), dann kann man dir vielleicht eher helfen...


----------



## Miller (18. Feb 2007)

Hi, Danke !!!
Hier der Code:

```
BranchGroup objRoot = new BranchGroup();
		
        TransformGroup objRotate = null;
        Transform3D transform = new Transform3D();
        

        transform.setTranslation(new Vector3f(0.0f, 0.0f, 0.0f));
        transform.rotX(90);
        objRotate = new TransformGroup(transform);
        objRotate.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
        objRotate.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
        objRoot.addChild(objRotate);
        objRoot.addChild(scene); // Scene ist eine BranchGroup...baer die wird mitgedreht oder wenn
                                            // der parrent Node(oder wie auch immer) gedreht wird oder ?
        objRoot.compile();
```


MFG Miller


----------



## merlin2 (22. Feb 2007)

Muss es nicht heißen:

```
rotX(Math.toRadians(90));
```


----------



## Illuvatar (22. Feb 2007)

Sorry, hatte deine Antwort damals übersehen.

Also 1.: merlin2 hat Recht, aber das hast du ja schon probiert, wenn ich dich recht verstehe?

2.: Der Code kommt mir richtig vor. Nur so am Rande: Wofür setzt du die Capabilities in Zeilen 11 und 12? Mit der TransformGroup sollte ja eigentlich weiter nichts passieren?


----------



## Miller (23. Feb 2007)

Hi, thx
hab nun die BranchGroup scene dem objRotate hinzugefügt anstatt der objRoot. Nun funktionierts. Ich glaub ich mal damit rumexperimentiert während der laufzeit etwas hinzuzufügen, "damals" hab ich dann überhalt die Capabilities  gesetzt., weil ich kein plan hatte ^^
Hab nun erstmal alles am laufen so wir ich mir das vorgestellt haben thx für die viele HIlfe!

MFG Miller


----------

