VisClient/org/hfbk/vis/visnode/VisBalistic.java

Go to the documentation of this file.
00001 package org.hfbk.vis.visnode;
00002 
00003 import org.dronus.gl.GLSphereRenderer;
00004 import org.dronus.graph.Node;
00005 import org.lwjgl.opengl.GL11;
00006 import org.lwjgl.util.vector.Vector3f;
00007 
00016 class VisBalistic extends VisNode{
00017         
00018         public Vector3f target=new Vector3f(50,-20,0);
00019 
00020         VisBalistic(Node node, Vector3f pos) {
00021                 super(node, pos);
00022                 
00023                 radius=Float.MAX_VALUE;
00024         }
00025         
00026         float heading; 
00027         float elevation;
00028         
00029         float G=9.81f, v0=20, y0; 
00030         
00035         double wurfweite (double a){
00036                 double s=Math.sin(a);
00037                 double r= v0*Math.cos(a)*( v0*s + Math.sqrt(v0*v0*s*s+2*G*y0 )) / G;
00038                 return r;
00039         }
00040 
00048         float invWurfweite(double X){
00049                 double  d=1E-12f,//Schrittweite zum schätzen der Ableitung
00050                                 e=1E-6f; //erlaubte Ungenauigkeit
00051                 double  a=0, //Winkel (Startwert ist ~40 Grad.)
00052                                 f;        //Funktionswert (ist-soll) zum aktuellen Winkel
00053                 int i=0;        //Iterationszähler
00054                 
00055                 /*
00056                  * Das Newtonverfahren
00057                  * Wir ziehen den Sollwert X von der Wurfweite ab und erhalten 
00058                  * damit eine Funktion f, die 0 werden muss. Das leistet das Newtonverfahren: In jedenm
00059                  * Schritt wird eine Tangente an die Funktion angelegt, und deren Schnittpunkt mit der
00060                  * x-Achse bestimmt. Von dort aus geht es dann weiter.
00061                  * Das Verfahren konvergiert sehr schnell, wenn es denn konvergiert; 
00062                  * wenn man Pech hat osziliert es zwischen mehreren Nullstellen oder schaukelt sich auf.
00063                  */
00064                 do{ //je ein Newtonschritt:
00065                         if (i++>10) 
00066                                 return Float.NaN;
00067                         double df=0;
00068                         f=  wurfweite(a)-X;                                     //Funktionswert ist - soll
00069                         df=(wurfweite(a)-wurfweite(a-d))/d;     //Ableitung von ist - soll
00070                 
00071                         //System.out.println(f+" "+df+" "+a);
00072                         
00073                         a=a-f/df;       //neues a ist jetzt Schnitt der Tangente durch a mit der x-Achse
00074                         
00075                         //      System.out.println("f:"+f+" da:"+a);
00076                 }while(Math.abs(f)>e); //Toleranz erreicht?
00077                 
00078                 return (float)a;
00079         }
00080         
00081         double bestAngle(double y){
00082                 return Math.asin(v0/Math.sqrt(2*v0*v0+2*G*y));
00083         }
00084         
00085         void renderSelf() {
00086                 
00087                 
00088                 GL11.glDisable(GL11.GL_TEXTURE_2D);
00089                 GLSphereRenderer.renderSphere(1);
00090                 
00091                 if (target!=null)
00092                         y0=-target.y;
00093                 
00094                 
00095 //                      Zeichne Reichweitenkreise
00096                 drawRanges();
00097 
00098                 //letzter wert für r ist fast maximale reichweite
00099                 
00100                 GL11.glColor3f(1,1,1);
00101                 
00102                 if (target==null)       return;
00103                 
00104                 Vector3f v=new Vector3f(target); //Abwurfvektor: Richtung...
00105                 v.y=0;
00106                 float wurfweite=v.length();
00107                 heading=(float) (Math.atan(v.z/v.x)+(v.x<0?Math.PI:0));
00108                 
00109                 //if (wurfweite>r) //in Reichweite?
00110                         //return;
00111                 
00112                 v.normalise();  
00113                 elevation=invWurfweite(wurfweite);  //Abwurfwinkel berechnen
00114                 
00115                 //System.out.println(heading+" "+elevation);
00116                 
00117                 float s=(float)Math.sin(elevation), c=(float)Math.cos(elevation);
00118                 v.x*=c; v.z*=c; v.y=s;  //Winkel einstellen
00119                 
00120                 v.scale(v0);
00121                 
00122 //                      Zeichne Wurfbahn
00123                 GL11.glBegin(GL11.GL_LINE_STRIP);
00124                 Vector3f p=new Vector3f(); //Aktuelle Position
00125                 
00126                 while(p.y>-y0){ 
00127                         float dt = .001f; //Schrittweite (in Sekunden)
00128                         
00129                         GL11.glVertex3f(p.x,p.y,p.z);           
00130                         
00131                         Vector3f dp=new Vector3f(v);
00132                         dp.scale(dt);   //Strecke=Geschwindigkeit*Zeit  
00133                         
00134                         Vector3f.add(p,dp,p);   //Position aktualisieren
00135                         v.y+=-G*dt;                             //Bewegungsvektor aktualisieren
00136                 }
00137                 GL11.glEnd();
00138                         
00139         }
00140 
00141         float drawRanges() {
00142                 float r=0;
00143                 GL11.glColor4f(1,1,1,.3f);
00144                 for (float y=-100; y<y0; y+=3){
00145                         r=(float)wurfweite(bestAngle(y));  //Reichweite
00146                         if (r!=Float.NaN){
00147                                 GL11.glBegin(GL11.GL_LINE_STRIP);
00148                                 for (float i=0; i<2*Math.PI; i+=.01f)
00149                                         GL11.glVertex3f((float)Math.cos(i)*r, -y, (float)Math.sin(i)*r);                
00150                                 GL11.glEnd();
00151                         }
00152                 }
00153                 return r;
00154         }               
00155 }

Generated on Tue Apr 7 17:57:21 2009 for visclient by  doxygen 1.5.1