承接上一例線框立方體,改用 fillPolygon 繪製實心面,並引入背面消隱演算法:計算面在投影平面上的有向面積 (Cross Product Z 分量),若為正則為前向面才繪製。實現簡易的 3D 實體渲染。
import java.awt.*;
import javax.swing.*;
public class Gr3d4a extends Gr3d1m {
public static void main(String[] args) { new Gr3d4a(); }
public Gr3d4a() {
setTitle("3D Solid Cube");
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
addMouseListener(this); addMouseMotionListener(this);
setBackground(new Color(128, 128, 255));
setSize(350, 350);
setVisible(true);
}
@Override
public void drawFace(Graphics g, double[] x, double[] y, double[] z,
int cx, int cy, Color c) {
double radX = Math.toRadians(angX), radY = Math.toRadians(angY);
double sinX = Math.sin(radX), cosX = Math.cos(radX);
double sinY = Math.sin(radY), cosY = Math.cos(radY);
int n = x.length;
double[] xw = new double[n], yw = new double[n];
int[] xs = new int[n], ys = new int[n];
for (int i = 0; i < n; i++) {
double x1 = x[i]*cosY + z[i]*sinY;
double z1 = -x[i]*sinY + z[i]*cosY;
double y1 = y[i]*cosX - z1*sinX;
xs[i] = cx + (int)Math.round(x1);
ys[i] = cy - (int)Math.round(y1);
xw[i] = x1; yw[i] = y1;
}
// 背面消隱:計算投影平面上的有向面積
if (calcArea(xw, yw) > 0) {
g.setColor(c);
g.fillPolygon(xs, ys, n);
}
}
// 計算多邊形有向面積 (僅適用凸多邊形,此處為四邊形)
double calcArea(double[] x, double[] y) {
return x[0]*(y[1]-y[2]) + x[1]*(y[2]-y[0]) + x[2]*(y[0]-y[1]);
}
}
演算法說明:
延伸應用:可進一步加入光照模型 (Gouraud/Phong)、材質貼圖,構建簡易 3D 引擎。