2013-03-03 4 views
0

Donc j'écris ce système de particules simple/programme 3D mais je ne peux pas obtenir la projection pour fonctionner. Je ne connais pas grand-chose à ce sujet, alors j'ai lu sur Wikipédia et j'ai pensé que la projection de perspectives pourrait être utile. J'utilise cette formule http://en.wikipedia.org/wiki/3D_projection#Perspective_projectionGraphiques 3D en Java. projection

Mon Canevas ne montre rien alors je pense que la projection est fausse. J'avais un cube avec des arêtes (200, 200, 200) et (300, 300, 300) mais il n'apparaissait pas sur l'écran. Je pensais peut-être que je choisis la mauvaise valeur pour la rotation de la caméra ou quelque chose alors j'ai essayé de tracer beaucoup de points allant de -100 à 100 dans tous les axes x, y et z et avec 10 unités d'intervalle. Puis j'ai placé la caméra dans (0,0,0) et j'ai pensé que je verrais quelque chose, mais je ne le vois pas. Il projette tout à NaN ou (0,0). Je ne comprends vraiment pas ce que je devrais choisir pour la valeur.

Voici le code. J'ai laissé de côté le dessin et d'autres choses et j'ai essayé de me concentrer sur la projection.

package org.gcs.kinetic; 

import java.awt.Color; 
import java.util.ArrayList; 

public class StillParticle extends Particle{ 
    Color getColor(){ 
     return Color.YELLOW; 
    } 

    @Override 
    public void iterate(){ 

    } 

    public static ArrayList<Particle> getCube(){ 
     ArrayList<Particle> result = new ArrayList<Particle>(); 
     StillParticle p; 
     for(int i = -100; i < 100; i+=10){ 
      for(int j = -100; j < 100; j+=10){ 
       for(int k = -100; k < 100; k+=10){ 
        p = new StillParticle(); 
        p.setColor(Color.YELLOW); 
        p.setPosition(i, j, k); 
        p.setR(2); 
        result.add(p); 
       } 
      } 
     } 
     return result; 
    } 

} 

et

package org.gcs.kinetic; 

public class Camera { 
    Vector3D c; 
    Vector3D o; 
    Vector3D e; 

    public Camera(Vector3D c, Vector3D o, Vector3D e) { 
     this.c=c; 
     this.o=o; 
     this.e=e; 
    } 

    double[] project(Vector3D a){ 
     double dx = cos(o.y)*(sin(o.z)*(a.y-c.y)+cos(o.z)*(a.x-c.x))-sin(o.y)*(a.z-c.z); 
     double dy = sin(o.x)*(cos(o.y)*(a.z-c.z)+sin(o.y)*(sin(o.z)*(a.y-c.y)+cos(o.z)*(a.x-c.x)))+cos(o.x)*(cos(o.z)*(a.y-c.y)-sin(o.z)*(a.x-c.x)); 
     double dz = cos(o.x)*(cos(o.y)*(a.z-c.z)+sin(o.y)*(sin(o.z)*(a.y-c.y)+cos(o.z)*(a.x-c.x)))-sin(o.x)*(cos(o.z)*(a.y-c.y)-sin(o.z)*(a.x-c.x)); 
     double[] result = new double[2]; 
     System.out.println(dx + ", "+ dy+ ", " + dz); 
     result[0] = (dx-e.x)*(e.z/dz); 
     result[1] = (dy-e.y)*(e.z/dz); 
     System.out.println(a+ " projected to " + result[0]+ "," + result[1]); 
     return result; 
    } 

    double cos(double x){ 
     return Math.cos(x); 
    } 
    double sin(double x){ 
     return Math.sin(x); 
    } 
} 

et

/** Free for non-military use */ 
package org.gcs.kinetic; 

import java.awt.*; 

/** 
* A Particle is assumed to be spherical. The particle's mass 
* is assumed to be proportional to r^3. Vector p is the center 
* of the particle's enclosing square, and Vector v contains 
* the particle's velocity components. 
* 
*/ 
class Particle extends Object { 

    private double radius = 0; 
    private double mass = 0; 
    protected int age = 0; 
    int MAXAGE = 60; 
    private Color color = new Color(0, true); 
    private Image image = null; 
    private Vector3D p = new Vector3D(); 
    private Vector3D v = new Vector3D(); 
    private Vector3D a = new Vector3D(0.0,0.1,0.0); 
    public static Ensemble world; 

    /** 
    * Construct a dimensionless, massless, invisible, 
    * stationary particle at the origin. 
    */ 
    public Particle() { 
    } 

    /** Return a new Vector with this particle's position. */ 
    public Vector3D getPosition() { 
     return new Vector3D(p); 
    } 

    /** Return the given Vector set to this particle's position. */ 
    public Vector3D getPosition(Vector3D p) { 
     p.x = this.p.x; p.y = this.p.y; p.z=this.p.z; 
     return p; 
    } 

    public double getX() { 
     return this.p.x; 
    } 

    public double getY() { 
     return this.p.y; 
    } 

    public double getZ() { 
     return this.p.z; 
    } 

    public void setPosition(Vector3D p) { 
     this.p.x = p.x; 
     this.p.y = p.y; 
     this.p.z = p.z; 
    } 

    public void setPosition(double x, double y, double z) { 
     this.p.x = x; 
     this.p.y = y; 
     this.p.z = z; 
    } 

    public Vector3D getVelocity() { 
     return new Vector3D(v); 
    } 

    public Vector3D getVelocity(Vector3D v) { 
     v.x = this.v.x; v.y = this.v.y;v.z = this.v.z; 
     return v; 
    } 

    public double getVx() { return this.v.x; } 
    public double getVy() { return this.v.y; } 
    public double getVz() { return this.v.z; } 

    public double getVNorm() { 
     return v.norm(); 
    } 

    public void setVelocity(Vector3D v) { 
     this.v.x = v.x; this.v.y = v.y; this.v.z = v.z; 
    } 

    public void setVelocity(double vx, double vy, double vz) { 
     this.v.x = vx; this.v.y = vy; this.v.z=vz; 
    } 

    /** Set this particle's radius and imputed mass. */ 
    public void setR(double radius) { 
     this.radius = radius; 
     this.mass = radius * radius * radius; 
    } 

    public double getR() { return this.radius; } 

    public double getM() { return this.mass; } 

    Color getColor() { 
     double factor = age/(double)MAXAGE; 
     int red = (int) ((1-factor)*color.getRed()); 
     int green = (int) ((1-factor)*color.getGreen()); 
     int blue = (int) ((1-factor)*color.getBlue()); 
     return new Color(red, green, blue); 
    } 

    public void setColor(Color color) { this.color = color; } 

    public Image getImage() { return image; } 

    public void setImage(Image image) { this.image = image; } 

    public void iterate() { 
     age++; 
     updatePos(); 
     updateVelocity(); 
     //updateAcceleration(); 
     if(age==MAXAGE) 
      world.removedParticles.add(this); 
    } 

    protected void updatePos() { 
     p.x += v.x; 
     p.y += v.y; 
     p.z += v.z; 
    } 

    protected void updateVelocity() { 
     v.x += a.x; 
     v.y += a.y; 
     v.z += a.z; 
    } 

    private void updateAcceleration() { 

    } 
} 

et

/** Free for non-military use */ 
package org.gcs.kinetic; 

/** 
* Vector represents a 3D-Vector 
* 
* @see Particle 
* @see Ensemble 
*/ 
class Vector3D extends Object { 

    /** The Vector's x and y component. */ 
    public double x; 
    public double y; 
    public double z; 

    /** Construct a null Vector, <0, 0, 0> by default. */ 
    public Vector3D() { 
    } 

    /** 
    * Construct a new Vector from two doubles. 
    * @param x the x component 
    * @param y the y component 
    * @param z the z component 
    */ 
    public Vector3D(double x, double y, double z) { 
     this.x = x; this.y = y; this.z = z; 
    } 

    /** 
    * Construct a new Vector from two integers. 
    * @param x the x component 
    * @param y the y component 
    * @param z the z component 
    */ 
    public Vector3D(int x, int y, int z) { 
     this.x = x; this.y = y; this.z = z; 
    } 

    /** 
    * Construct a new Vector from an existing one. 
    * @param v the source Vector 
    */ 

    public Vector3D(Vector3D v) { 
     this.x = v.x; this.y = v.y; this.z = v.z; 
    } 

    /** Set the components of this Vector. 
    * @param x the x component 
    * @param y the y component 
    * @param z the z component 
    * @return this Vector. 
    */ 
    public Vector3D set(double x, double y, double z) { 
     this.x = x; this.y = y; this.z = z; 
     return this; 
    } 

    /** 
    * Set the coordinates of this Vector3D to those of v. 
    * @param v the source Vector3D 
    * @return this Vector3D. 
    */ 
    public Vector3D set(Vector3D v) { 
     this.x = v.x; this.y = v.y; this.z = v.z; 
     return this; 
    } 

    /** 
    * Return the length of this Vector. 
    * @return the length of this Vector 
    */ 
    public double norm() { 
     return Math.sqrt(x*x + y*y + z*z); 
    } 

    /** 
    * Add the given Vector to this Vector; return this Vector. 
    * @param v the given Vector 
    * @return the sum 
    */ 
    public Vector3D add(Vector3D v) { 
     this.x += v.x; 
     this.y += v.y; 
     this.z += v.z; 
     return this; 
    } 

    /** 
    * Subtract the given Vector from this Vector; return this Vector. 
    * @param v the given Vector 
    * @return the difference 
    */ 
    public Vector3D subtract(Vector3D v) { 
     this.x -= v.x; 
     this.y -= v.y; 
     this.z -= v.z; 
     return this; 
    } 

    /** 
    * Multiply the given Vector by this Vector; return the scalar product. 
    * @param v the given Vector 
    * @return the scalar (dot) product 
    */ 
    public double dot(Vector3D v) { 
     return (this.x * v.x) + (this.y * v.y) + (this.z*v.z); 
    } 

    /** 
    * Scale this Vector by the given scale factor. 
    * @param s the scale factor 
    * @return the this Vector, scaled by s 
    */ 
    public Vector3D scale(double s) { 
     this.x *= s; this.y *= s; this.z *=s; 
     return this; 
    } 

    /** 
    * Scale this Vector by 1/norm(); return this Vector. 
    * The result is a unit Vector parallel to the original. 
    * This is equivalent to this.scale(1/this.norm()), 
    * with a check for division by zero. 
    * @return the this Vector, scaled to unit length 
    */ 
    public Vector3D unitVector() { 
     double d = norm(); 
     if (d != 0) { this.x /= d; this.y /= d; this.z /= d;} 
     return this; 
    } 

    /** Return this Vector's String representation. */ 
    public String toString() { 
     return "<" + this.x + ", " + this.y +", "+ this.z + ">"; 
    } 
} 

Répondre

0

Votre formule de projection 3D devrait être:

proj.x = x * factor/(z + factor) + center.x 
proj.y = y * factor/(z + factor) + center.y 

où le facteur est un nombre de choix personnel (je choisis 250) et le centre est le point de fuite.

Exemple:

  • Si z est infini, proj = centre.
  • Si z vaut 0, proj sera inchangé.

Note:

x et y sont par rapport à la caméra, pour cela, vous soustrayez la position de la caméra de leur position réelle (u doivent également appliquer des rotations je pense).