欧美三区_成人在线免费观看视频_欧美极品少妇xxxxⅹ免费视频_a级毛片免费播放_鲁一鲁中文字幕久久_亚洲一级特黄

java 游戲編程 (九)

系統(tǒng) 2053 0
本篇主要對(duì)java處理三維圖形基本的知識(shí)做一下復(fù)習(xí)。有些地方上篇沒(méi)仔細(xì)討論。
涉及到上一篇的所有類,做一下規(guī)整,還有新的類應(yīng)用描述。
1.Vector3D
這個(gè)類描述三維向量。三維向量就是(x,y,z)一個(gè)空間點(diǎn),或從(0,0,0)到(x,y,z)的向量。
提供了向量加 向量減 向量乘 和向量除
還有返回了向量的長(zhǎng)度? 空間直線的長(zhǎng)度計(jì)算公式:根號(hào)下(x+-x1)的平方+(y+-y1)+(z+-z1)的平方
區(qū)長(zhǎng)度方法為
        
public float length() {
        return (float)Math.sqrt(x*x + y*y + z*z);
    }

  

旋轉(zhuǎn),比如沿x軸旋轉(zhuǎn)
    
    public void rotateX(float cosAngle, float sinAngle) {
        float newY = y*cosAngle - z*sinAngle;
        float newZ = y*sinAngle + z*cosAngle;
        y = newY;
        z = newZ;
    }

  

因?yàn)檠豿軸旋轉(zhuǎn),x的值忽略,重新對(duì)y,z賦值。
這里的形參是預(yù)先計(jì)算出來(lái)的值。
至于這個(gè) float newY = y*cosAngle - z*sinAngle公式做如下解釋
java 游戲編程 (九)
這個(gè)圖畫(huà)的很不好,
一個(gè)點(diǎn)旋轉(zhuǎn)到另一個(gè)點(diǎn)
x=rcosb
y=rsinb
轉(zhuǎn)過(guò)角a后,x1=rcos(a+b) y1=rsin(a+b);
得到 x1=rcosbcosa-rsinbsina? 1=rsinbcosa+rsinacosb
最后
x1=xcosb-ysinb
y1=xsinb+ycosb
沿著其他軸轉(zhuǎn)一樣。
所以又了以上rotateX的計(jì)算方法。
2.ViewWindow
這個(gè)類具備了視圖窗口的功能,并且提供投影。
再議3D的數(shù)學(xué):
3D圖形的生成就是? 三維圖形到鏡頭的連接線或向量,這些連接線經(jīng)過(guò)視圖窗口,在視圖窗口成像。鏡頭離試圖窗口越近,成像效果越大,這是三角問(wèn)題。這個(gè)角度可以看做鏡頭到試圖窗口的法線向量與連線的夾角。這個(gè)成像與屏幕坐標(biāo)不一致,還要換算為屏幕坐標(biāo)。
來(lái)看一下。
    
    public void project(Vector3D v) {
       //投影到視圖窗口
        v.x = distanceToCamera * v.x / -v.z;
        v.y = distanceToCamera * v.y / -v.z;
       //轉(zhuǎn)換為屏幕坐標(biāo)
        v.x = convertFromViewXToScreenX(v.x);
        v.y = convertFromViewYToScreenY(v.y);
    }

  

這里形參 v 是具體的三維物體
改變其x和y的值,是通過(guò)三角函數(shù)等比例關(guān)系進(jìn)行計(jì)算
distanceToCamera是視圖窗口到鏡頭的法線長(zhǎng)度
經(jīng)過(guò)重新復(fù)制的v.x和v.y然后換算為屏幕坐標(biāo)。
convertFromViewXToScreenX方法見(jiàn)上以篇
z是深度坐標(biāo),忽略計(jì)算。

多邊形問(wèn)題
多邊形就是一堆頂點(diǎn)
3.Polygon3D
這個(gè)類將多邊形表示成一堆頂點(diǎn)。通過(guò)Vector3D[] 存放
看看其中幾個(gè)方法
    
   public Polygon3D(Vector3D[] vertices) {
        this.v = vertices;
        numVertices = vertices.length;
        calcNormal();
    }
   public Vector3D calcNormal() {
        if (normal == null) {
            normal = new Vector3D();
        }
        temp1.setTo(v[2]);
        temp1.subtract(v[1]);
        temp2.setTo(v[0]);
        temp2.subtract(v[1]);
        normal.setToCrossProduct(temp1, temp2);
        normal.normalize();
        return normal;
    }

  

這是計(jì)算法線。法線的計(jì)算是通過(guò)求兩個(gè)向量的交積得到。至于向量交積的計(jì)算網(wǎng)上有。
法線有方向,方向是通過(guò)求點(diǎn)積得到。
為什么需要法線向量?
通過(guò)法線向量(帶方向的)與鏡頭與視圖窗口垂直線 的夾角來(lái)判斷三維物體是否正對(duì)鏡頭
如果是銳角表示正對(duì),否則是背對(duì)。
        
    public boolean isFacing(Vector3D u) {
        temp1.setTo(u);
        temp1.subtract(v[0]);
        return (normal.getDotProduct(temp1) >= 0);
    }

  


    
    public void ensureCapacity(int length) {
        if (v.length < length) {
            Vector3D[] newV = new Vector3D[length];
            System.arraycopy(v,0,newV,0,v.length);
            for (int i=v.length; i<newV.length; i++) {
                newV[i] = new Vector3D();
            }
            v = newV;
        }
    }


  

因?yàn)槌醮芜\(yùn)行數(shù)組初始化長(zhǎng)度不夠,會(huì)引起數(shù)組越界,這個(gè)方法保證多邊形的容量可以容納多邊形頂點(diǎn)個(gè)數(shù)

    
    public void project(ViewWindow view) {
        for (int i=0; i<numVertices; i++) {
            view.project(v[i]);
        }
    }

  

將多邊形投影到視圖窗口。

4.Transform3D
這個(gè)類主要表示旋轉(zhuǎn)和平移,提供了三角函數(shù)算法。通過(guò)這個(gè)類計(jì)算旋轉(zhuǎn)角度后的三角函數(shù)值,并調(diào)用Vector3D的旋轉(zhuǎn)方法。
還有一個(gè)成員Vector3D location,代表了它作用于的Vector3D.

5.My3DTest1
這個(gè)類的事件監(jiān)聽(tīng)就不再做解釋了。
定義了幾個(gè)成員
    
    private Transform3D myTransform = new Transform3D(0,0,-500);
    private Polygon3D transformedPolygon = new Polygon3D();
    private ViewWindow viewWindow;

  

下面會(huì)提到。
    
    public void update(long elapsedTime) {
        if (exit.isPressed()) {
            stop();
            return;
        }
        elapsedTime = Math.min(elapsedTime, 100);

        treeTransform.rotateAngleY(0.002f*elapsedTime);

        if (zoomIn.isPressed()) {
            treeTransform.getLocation().z += 0.5f*elapsedTime;
        }
        if (zoomOut.isPressed()) {
            treeTransform.getLocation().z -= 0.5f*elapsedTime;
        }
    }

  


這里是沿y軸旋轉(zhuǎn)
treeTransform.rotateAngleY(0.002f*elapsedTime);
經(jīng)過(guò)計(jì)算得到了cosAngleY 和 sinAngleY兩個(gè)三角函數(shù)值
看關(guān)鍵的draw方法中的
trandformAndDraw(g, p);
    
 private void trandformAndDraw(Graphics2D g,
    		Polygon3D poly)
    {
        transformedPolygon.setTo(poly);
        transformedPolygon.add(myTransform);
        transformedPolygon.project(viewWindow);
        GeneralPath path = new GeneralPath();
        Vector3D v = transformedPolygon.getVertex(0);
        path.moveTo(v.x, v.y);
        for (int i=1; i<transformedPolygon.getNumVertices(); i++) {
            v = transformedPolygon.getVertex(i);
            path.lineTo(v.x, v.y);
        }
        g.setColor(Color.red);
        g.fill(path);
    }

  


??????? transformedPolygon.setTo(poly);
??????? transformedPolygon.add(myTransform);
??????? transformedPolygon.project(viewWindow);
這三句代碼很重要。
? transformedPolygon.setTo(poly);
將多邊形中的vector全都set到transformedPloygon中
transformedPolygon.add(myTransform);
這里就是進(jìn)行旋轉(zhuǎn)的功能,我進(jìn)入方法內(nèi)部說(shuō)明一下。
add方法做了兩件事情:
1.addRotation(myTransform);
    
    public void addRotation(Transform3D myTransform) {
        for (int i=0; i<numVertices; i++) {
           v[i].addRotation(myTransform);
        }
        normal.addRotation(myTransform);
    }
	public void addRotation(Transform3D myTransform) {
		// TODO Auto-generated method stub
	     rotateX(myTransform.getCosAngleX(), myTransform.getSinAngleX());
	     rotateZ(myTransform.getCosAngleZ(), myTransform.getSinAngleZ());
	     rotateY(myTransform.getCosAngleY(), myTransform.getSinAngleY());
	}

  

這里就是我前面說(shuō)道的Vector3D里面的旋轉(zhuǎn)函數(shù)方程了。經(jīng)過(guò)旋轉(zhuǎn)計(jì)算后,每一個(gè)頂點(diǎn)都會(huì)發(fā)生坐標(biāo)的轉(zhuǎn)移,也就實(shí)現(xiàn)了旋轉(zhuǎn)。
2.add(myTransform.getLocation());
    
    public void add(Vector3D u) {
       for (int i=0; i<numVertices; i++) {
           v[i].add(u);
       }
    }


  

3. transformedPolygon.project(viewWindow);
投影到視圖窗口
最后程序循環(huán)連線畫(huà)出了三維多邊形,并填充了顏色。

java 游戲編程 (九)


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號(hào)聯(lián)系: 360901061

您的支持是博主寫(xiě)作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對(duì)您有幫助就好】

您的支持是博主寫(xiě)作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長(zhǎng)會(huì)非常 感謝您的哦!??!

發(fā)表我的評(píng)論
最新評(píng)論 總共0條評(píng)論
主站蜘蛛池模板: 亚洲欧美韩国日产综合在线 | 亚洲精品不卡久久久久久 | 久久亚洲综合 | 日韩 欧美 亚洲国产 | 免费国产免费福利视频 | 天天狠狠 | 视频一区中文字幕 | 欧美在线性视频 | 中文字幕av一区二区 | 亚洲午夜精品一级在线 | 一级做a爰片性色毛片中国 日本黄色免费片 | 免费乱理伦片在线观看八戒 | 国产乱码精品一区二区三上 | 视频三区 | 一区二区三区免费视频观看 | 婷婷激情综合色五月久久竹菊影视 | 夜色成人性y | 成人小视频在线观看免费 | 午夜小视频免费 | 韩国资源视频一区二区三区 | 国产成人免费视频网站高清观看视频 | 欧美a∨一区二区三区久久黄 | 久久久久久久久久久久久久久久久久久 | 最新国产精品 | 国产高清美女一级毛片 | 亚洲天堂av在线 | www.久| 欧美艹逼| 性夜影院爽黄a爽免费视 | 一道本不卡视频 | 在线天堂中文在线资源网 | 强伦女教师视频 | 中文字幕一区二区三区四区不卡 | 国内精品99 | 中文字幕在线电影观看 | 精品久久久久久久久久 | 国产午夜免费一区二区三区 | 久久国产精品久久久久久久久久 | 日韩在线观看第一页 | 亚洲人成在线观看一区二区 | 国产成人禁片免费观看 |