java中的3d图形。投影

java中的3d图形。投影,3d,projection,3d,Projection,所以我正在写这个简单的粒子系统/3D程序,但是我无法让投影工作。我对这些东西了解不多,所以我在维基百科上读到了,我认为透视投影可能有用。我用的是这个公式 我的画布没有显示任何东西,所以我认为投影是错误的。我有一个边沿分别为(200200200200)和(300300300)的立方体,但它没有显示在屏幕上。我想可能是我选择了错误的相机旋转值,所以我试着在x、y和z轴上绘制了很多从-100到100的点,间隔为10个单位。然后我把相机放在(0,0,0)里,我想我会看到一些东西,但我没有。它将所有内容

所以我正在写这个简单的粒子系统/3D程序,但是我无法让投影工作。我对这些东西了解不多,所以我在维基百科上读到了,我认为透视投影可能有用。我用的是这个公式

我的画布没有显示任何东西,所以我认为投影是错误的。我有一个边沿分别为(200200200200)和(300300300)的立方体,但它没有显示在屏幕上。我想可能是我选择了错误的相机旋转值,所以我试着在x、y和z轴上绘制了很多从-100到100的点,间隔为10个单位。然后我把相机放在(0,0,0)里,我想我会看到一些东西,但我没有。它将所有内容投影到NaN或(0,0)。我真的不明白我应该为e值选择什么

这是密码。我忽略了绘画和其他东西,试着专注于投影

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;
    }

}

/**非军事用途免费*/
包org.gcs.kinetic;
/**
*矢量表示三维矢量
*
*@见粒子
*@see合奏团
*/
类Vector3D扩展对象{
/**向量的x和y分量*/
公共双x;
公共双y;
公共双z;
/**默认情况下,构造一个空向量*/
公共向量3D(){
}
/**
*从两个双精度向量构造一个新向量。
*@param x x x组件
*@param y是y组件
*@param z是z组件
*/
公共矢量3D(双x、双y、双z){
这个.x=x;这个.y=y;这个.z=z;
}
/**
*从两个整数构造一个新向量。
*@param x x x组件
*@param y是y组件
*@param z是z组件
*/
公共向量3D(整数x,整数y,整数z){
这个.x=x;这个.y=y;这个.z=z;
}
/**
*从现有向量构造新向量。
*@param v源向量
*/
公共矢量3D(矢量3D v){
这个.x=v.x;这个.y=v.y;这个.z=v.z;
}
/**设置此向量的分量。
*@param x x x组件
*@param y是y组件
*@param z是z组件
*@返回这个向量。
*/
公共矢量3D集(双x、双y、双z){
这个.x=x;这个.y=y;这个.z=z;
归还这个;
}
/**
*将此矢量3D的坐标设置为v的坐标。
*@param v源向量3d
*@返回此矢量3D。
*/
公共矢量3D集(矢量3D v){
这个.x=v.x;这个.y=v.y;这个.z=v.z;
归还这个;
}
/**
*返回此向量的长度。
*@返回此向量的长度
*/
公共双范数(){
返回Math.sqrt(x*x+y*y+z*z);
}
/**
*将给定向量添加到此向量;返回此向量。
*@param v给定向量
*@退还金额
*/
公共矢量3D添加(矢量3D v){
这个.x+=v.x;
这个.y+=v.y;
这个.z+=v.z;
归还这个;
}
/**
*从该向量中减去给定向量;返回该向量。
*@param v给定向量
*@返回差异
*/
公共矢量3D减法(矢量3D v){
这个.x-=v.x;
这个.y-=v.y;
这个.z-=v.z;
归还这个;
}
/**
*将给定向量乘以该向量;返回标量积。
*@param v给定向量
*@返回标量(点)积
*/
公共双点(矢量3D v){
返回(this.x*v.x)+(this.y*v.y)+(this.z*v.z);
}
/**
*按给定的比例因子缩放此向量。
*@param是比例因子
*@返回该向量,按s缩放
*/
公共矢量3D比例(双s){
这个.x*=s;这个.y*=s;这个.z*=s;
归还这个;
}
/**
*按1/norm()缩放此向量;返回此向量。
*结果是一个与原始向量平行的单位向量。
*这相当于这个.scale(1/This.norm()),
*检查是否被零除。
*@返回此向量的值,按单位长度缩放
*/
公共向量3D unitVector(){
双d=范数();
如果(d!=0){this.x/=d;this.y/=d;this.z/=d;}
归还这个;
}
/**返回此向量的字符串表示形式*/
公共字符串toString(){
返回“”;
}
}

您的3d投影公式应为:

proj.x = x * factor / (z + factor) + center.x
proj.y = y * factor / (z + factor) + center.y
其中,因子是一些个人选择(我选择250),中心是消失点

例如:

  • 如果z为无穷大,则proj=中心
  • 如果z为0,项目将保持不变
注:

x和y是相对于相机的,因此你从它们的真实位置减去相机的位置(我认为u也必须应用旋转)

    /** 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() {

    }
}
/** 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 + ">";
    }
}
proj.x = x * factor / (z + factor) + center.x
proj.y = y * factor / (z + factor) + center.y