国产精品久久久aaaa,日日干夜夜操天天插,亚洲乱熟女香蕉一区二区三区少妇,99精品国产高清一区二区三区,国产成人精品一区二区色戒,久久久国产精品成人免费,亚洲精品毛片久久久久,99久久婷婷国产综合精品电影,国产一区二区三区任你鲁

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

怎樣用Java制作基本的3D引擎

454398 ? 來源:網(wǎng)絡(luò)整理 ? 作者:網(wǎng)絡(luò)整理 ? 2019-12-11 16:51 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

步驟1:主類

首先要做的是被造是一個主要的階級。主類將處理向用戶顯示圖像,調(diào)用其他類以重新計算應(yīng)向播放器顯示的內(nèi)容以及更新相機的位置。

對于該類,導(dǎo)入將是:

import java.awt.Color;

import java.awt.Graphics;

import java.awt.image.BufferStrategy;

import java.awt.image.BufferedImage;

import java.awt.image.DataBufferInt;

import java.util.ArrayList;

import javax.swing.JFrame;

該類及其變量將如下所示:

public class Game extends JFrame implements Runnable{

private static final long serialVersionUID = 1L;

public int mapWidth = 15;

public int mapHeight = 15;

private Thread thread;

private boolean running;

private BufferedImage image;

public int[] pixels;

public static int[][] map =

{

{1,1,1,1,1,1,1,1,2,2,2,2,2,2,2},

{1,0,0,0,0,0,0,0,2,0,0,0,0,0,2},

{1,0,3,3,3,3,3,0,0,0,0,0,0,0,2},

{1,0,3,0,0,0,3,0,2,0,0,0,0,0,2},

{1,0,3,0,0,0,3,0,2,2,2,0,2,2,2},

{1,0,3,0,0,0,3,0,2,0,0,0,0,0,2},

{1,0,3,3,0,3,3,0,2,0,0,0,0,0,2},

{1,0,0,0,0,0,0,0,2,0,0,0,0,0,2},

{1,1,1,1,1,1,1,1,4,4,4,0,4,4,4},

{1,0,0,0,0,0,1,4,0,0,0,0,0,0,4},

{1,0,0,0,0,0,1,4,0,0,0,0,0,0,4},

{1,0,0,2,0,0,1,4,0,3,3,3,3,0,4},

{1,0,0,0,0,0,1,4,0,3,3,3,3,0,4},

{1,0,0,0,0,0,0,0,0,0,0,0,0,0,4},

{1,1,1,1,1,1,1,4,4,4,4,4,4,4,4}

};

請注意,可以將地圖重新配置為所需的內(nèi)容,我在這里只是一個樣品。地圖上的數(shù)字表示該位置的墻壁類型。 0代表空白空間,而其他任何數(shù)字則代表實心墻和隨之而來的紋理。 BufferedImage是顯示給用戶的,像素是圖像中所有像素的數(shù)組。其他變量實際上不會再次出現(xiàn),它們只是用來使圖形和程序正常工作。

構(gòu)造函數(shù)現(xiàn)在看起來像這樣:

public Game() {

thread = new Thread(this);

image = new BufferedImage(640, 480, BufferedImage.TYPE_INT_RGB);

pixels = ((DataBufferInt)image.getRaster().getDataBuffer()).getData();

setSize(640, 480);

setResizable(false);

setTitle(“3D Engine”);

setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

setBackground(Color.black);

setLocationRelativeTo(null);

setVisible(true);

start();

}

大多數(shù)只是類變量和框架的初始化。 “ pixels =“之后的代碼連接像素和圖像,以便每當(dāng)更改像素中的數(shù)據(jù)值時,向用戶顯示圖像時就會在圖像上顯示相應(yīng)的更改。

start和stop方法是簡單并用于確保程序安全地開始和結(jié)束。

private synchronized void start() {

running = true;

thread.start();

}

public synchronized void stop() {

running = false;

try {

thread.join();

} catch(InterruptedException e) {

e.printStackTrace();

}

}

Game類中需要的最后兩個方法是render和run方法。渲染方法將如下所示:

public void render() {

BufferStrategy bs = getBufferStrategy();

if(bs == null) {

createBufferStrategy(3);

return;

}

Graphics g = bs.getDrawGraphics();

g.drawImage(image, 0, 0, image.getWidth(), image.getHeight(), null);

bs.show();

}

渲染時使用緩沖策略,以使屏幕更新更加流暢。總體而言,使用緩沖策略只會幫助游戲在運行時看起來更好。為了將圖像實際繪制到屏幕上,需要從緩沖策略中獲取圖形對象并用于繪制圖像。

run方法非常重要,因為它可以處理程序不同部分的更新頻率。為此,它使用一些代碼來跟蹤何時經(jīng)過了1/60秒,以及何時更新了屏幕和攝像機。這樣可以提高程序運行的流暢度。 run方法如下所示:

public void run() {

long lastTime = System.nanoTime();

final double ns = 1000000000.0 / 60.0;//60 times per second

double delta = 0;

requestFocus();

while(running) {

long now = System.nanoTime();

delta = delta + ((now-lastTime) / ns);

lastTime = now;

while (delta 》= 1)//Make sure update is only happening 60 times a second

{

//handles all of the logic restricted time

delta--;

}

render();//displays to the screen unrestricted time

}

}

一旦所有這些方法,構(gòu)造函數(shù)和變量都在其中,那么當(dāng)前在Game類中剩下要做的唯一事情就是添加一個main方法。主要方法非常簡單,您要做的就是:

public static void main(String [] args) {

Game game = new Game();

}

現(xiàn)在,主類已完成!如果您現(xiàn)在運行該程序,則將彈出黑屏。

步驟2:紋理類

在進入查找屏幕外觀的計算之前,我將繞行并設(shè)置Texture類。紋理將應(yīng)用于環(huán)境中的各種墻壁,并將來自保存在項目文件夾中的圖像。在圖像中,我包含了在網(wǎng)上找到的4個紋理,將在該項目中使用。您可以使用任何想要的紋理。要使用這些紋理,我建議將它們放在項目文件中的文件夾中。為此,請轉(zhuǎn)到項目文件夾(在Eclipse中,它位于工作區(qū)文件夾中)。轉(zhuǎn)到項目文件夾后,創(chuàng)建一個名為“ res”或其他名稱的新文件夾。將紋理放在此文件夾中。您可以將紋理放置在其他地方,這就是我存儲紋理的地方。完成此操作后,我們就可以開始編寫代碼以使紋理可用。

該類的導(dǎo)入為:

import java.awt.image.BufferedImage;

import java.io.File;

import java.io.IOException;

import javax.imageio.ImageIO;

該類頭及其變量將看起來像這樣:

public class Texture {

public int[] pixels;

private String loc;

public final int SIZE;

數(shù)組像素用于保存紋理圖像中所有像素的數(shù)據(jù)。 Loc用于向計算機指示可以找到紋理的圖像文件的位置。 SIZE是一側(cè)的紋理大小(64x64圖像的大小為64),并且所有紋理將完全為正方形。

構(gòu)造函數(shù)將初始化loc和SIZE變量并調(diào)用a方法來將圖像數(shù)據(jù)加載到像素中。看起來像這樣:

public Texture(String location, int size) {

loc = location;

SIZE = size;

pixels = new int[SIZE * SIZE];

load();

}

現(xiàn)在,Texture類剩下的就是添加一個load方法來從圖像中獲取數(shù)據(jù)并將它們存儲在像素數(shù)據(jù)數(shù)組中。此方法將如下所示:

private void load() {

try {

BufferedImage image = ImageIO.read(new File(loc));

int w = image.getWidth();

int h = image.getHeight();

image.getRGB(0, 0, w, h, pixels, 0, w);

} catch (IOException e) {

e.printStackTrace();

}

}

load方法的工作原理是從loc指向的文件中讀取數(shù)據(jù)并將該數(shù)據(jù)寫入緩沖的圖像。然后,從緩沖的圖像中獲取每個像素的數(shù)據(jù),并將其存儲在像素中。

此時,Texture類已完成,因此我將繼續(xù)定義一些將要使用的紋理在最終程序中。為此,請將此

public static Texture wood = new Texture(“res/wood.png”, 64);

public static Texture brick = new Texture(“res/redbrick.png”, 64);

public static Texture bluestone = new Texture(“res/bluestone.png”, 64);

public static Texture stone = new Texture(“res/greystone.png”, 64);

放在“公共類Texture”行和“ public int []像素”之間。

使其余部分可以訪問這些紋理該程序讓我們繼續(xù)前進,并將其交給Game類。為此,我們將需要一個ArrayList來容納所有紋理,并且需要將紋理添加到此ArrayList中。要創(chuàng)建ArrayList,請將以下代碼行和變量放在類的頂部附近:

public ArrayList textures;

此ArrayList必須在構(gòu)造函數(shù)中初始化,并且還應(yīng)添加紋理在構(gòu)造函數(shù)中。在構(gòu)造函數(shù)中添加以下代碼:

textures = new ArrayList();

textures.add(Texture.wood);

textures.add(Texture.brick);

textures.add(Texture.bluestone);

textures.add(Texture.stone);

現(xiàn)在可以使用紋理了!

第3步:相機類

現(xiàn)在讓我們繞道而行并設(shè)置Camera類。 Camera類跟蹤玩家在2D地圖中的位置,并負(fù)責(zé)更新玩家的位置。為此,該類將實現(xiàn)KeyListener,因此將需要導(dǎo)入KeyEvent和KeyListener。

import java.awt.event.KeyEvent;

import java.awt.event.KeyListener;

需要許多變量來跟蹤攝像機的位置及其所見。因此,該類的第一個塊如下所示:

public class Camera implements KeyListener {

public double xPos, yPos, xDir, yDir, xPlane, yPlane;

public boolean left, right, forward, back;

public final double MOVE_SPEED = .08;

public final double ROTATION_SPEED = .045;

xPos和yPos是玩家在Game類中創(chuàng)建的2D地圖上的位置。 xDir和yDir是指向玩家所面對方向的向量的x和y分量。 xPlane和yPlane也是向量的x和y分量。 xPlane和yPlane定義的向量始終垂直于方向向量,并且在一側(cè)指向相機視場的最遠邊緣。另一邊最遠的邊緣就是負(fù)平面向量。方向矢量和平面矢量的組合定義了相機視場中的內(nèi)容。布爾值用于跟蹤用戶按下了哪些鍵,以便用戶可以移動相機。 MOVE_SPEED和ROTATION_SPEED指示在用戶按下相應(yīng)鍵時相機移動和旋轉(zhuǎn)的速度。

接下來是構(gòu)造函數(shù)。構(gòu)造函數(shù)接受告訴類的位置的值,并將相機分配給相應(yīng)的變量(xPos,yPos 。..)。

public Camera(double x, double y, double xd, double yd, double xp, double yp)

{

xPos = x;

yPos = y;

xDir = xd;

yDir = yd;

xPlane = xp;

yPlane = yp;

}

相機對象在最終程序中將需要它,所以讓我們繼續(xù)添加一個。在具有所有其他變量聲明的Game類中,添加

public Camera camera;

,并在構(gòu)造函數(shù)中添加

camera = new Camera(4.5, 4.5, 1, 0, 0, -.66);

addKeyListener(camera);

,此攝像機將與地圖一起使用我正在使用,如果您使用的是其他地圖,或者想從其他位置開始,請調(diào)整xPos和yPos的值(在我的示例中為4和6)。使用.66可以提供良好的視野,但是您可以調(diào)整該值以獲得不同的FOV。

現(xiàn)在,Camera類具有構(gòu)造函數(shù),我們可以開始添加方法來跟蹤用戶的輸入并更新相機的位置/方向。因為Camera類實現(xiàn)了KeyboardListener,所以它必須具有其實現(xiàn)的所有方法。 Eclipse應(yīng)該自動提示您添加這些方法。您可以將keyTyped方法保留為空白,但將使用其他兩種方法。當(dāng)按下相應(yīng)的鍵時,keyPressed會將布爾值設(shè)置為true,而釋放鍵時,keyReleased會將其更改為false。方法看起來像這樣:

public void keyPressed(KeyEvent key) {

if((key.getKeyCode() == KeyEvent.VK_LEFT))

left = true;

if((key.getKeyCode() == KeyEvent.VK_RIGHT))

right = true;

if((key.getKeyCode() == KeyEvent.VK_UP))

forward = true;

if((key.getKeyCode() == KeyEvent.VK_DOWN))

back = true;

}

public void keyReleased(KeyEvent key) {

if((key.getKeyCode() == KeyEvent.VK_LEFT))

left = false;

if((key.getKeyCode() == KeyEvent.VK_RIGHT))

right = false;

if((key.getKeyCode() == KeyEvent.VK_UP))

forward = false;

if((key.getKeyCode() == KeyEvent.VK_DOWN))

back = false;

}

現(xiàn)在,Camera類正在跟蹤按下了哪些鍵,我們可以開始更新播放器的位置。為此,我們將使用在Game類的run方法中調(diào)用的update方法。在此過程中,我們將繼續(xù)進行操作,并通過在Game類中將地圖傳遞給update方法時,將沖突檢測添加到update方法中。更新方法如下所示:

public void update(int[][] map) {

if(forward) {

if(map[(int)(xPos + xDir * MOVE_SPEED)][(int)yPos] == 0) {

xPos+=xDir*MOVE_SPEED;

}

if(map[(int)xPos][(int)(yPos + yDir * MOVE_SPEED)] ==0)

yPos+=yDir*MOVE_SPEED;

}

if(back) {

if(map[(int)(xPos - xDir * MOVE_SPEED)][(int)yPos] == 0)

xPos-=xDir*MOVE_SPEED;

if(map[(int)xPos][(int)(yPos - yDir * MOVE_SPEED)]==0)

yPos-=yDir*MOVE_SPEED;

}

if(right) {

double oldxDir=xDir;

xDir=xDir*Math.cos(-ROTATION_SPEED) - yDir*Math.sin(-ROTATION_SPEED);

yDir=oldxDir*Math.sin(-ROTATION_SPEED) + yDir*Math.cos(-ROTATION_SPEED);

double oldxPlane = xPlane;

xPlane=xPlane*Math.cos(-ROTATION_SPEED) - yPlane*Math.sin(-ROTATION_SPEED);

yPlane=oldxPlane*Math.sin(-ROTATION_SPEED) + yPlane*Math.cos(-ROTATION_SPEED);

}

if(left) {

double oldxDir=xDir;

xDir=xDir*Math.cos(ROTATION_SPEED) - yDir*Math.sin(ROTATION_SPEED);

yDir=oldxDir*Math.sin(ROTATION_SPEED) + yDir*Math.cos(ROTATION_SPEED);

double oldxPlane = xPlane;

xPlane=xPlane*Math.cos(ROTATION_SPEED) - yPlane*Math.sin(ROTATION_SPEED);

yPlane=oldxPlane*Math.sin(ROTATION_SPEED) + yPlane*Math.cos(ROTATION_SPEED);

}

}

該方法中控制前進和后退運動的部分通過分別向xPos和yPos添加xDir和yDir來工作。在此動作發(fā)生之前,程序會檢查該動作是否會將相機放置在墻內(nèi),如果可以,則不進行檢查。對于旋轉(zhuǎn),方向矢量和平面矢量都乘以旋轉(zhuǎn)矩陣,即:

[ cos(ROTATION_SPEED) -sin(ROTATION_SPEED) ]

[ sin(ROTATION_SPEED) cos(ROTATION_SPEED) ]

以獲得其新值。完成update方法后,我們現(xiàn)在可以從Game類中調(diào)用它。在Game類的run方法中,添加以下代碼行,在此處顯示

Add this:

camera.update(map);

in here:

while(running) {

long now = System.nanoTime();

delta = delta + ((now-lastTime) / ns);

lastTime = now;

while (delta 》= 1)//Make sure update is only happening 60 times a second

{

//handles all of the logic restricted time

camera.update(map);

delta--;

}

render();//displays to the screen unrestricted time

}

現(xiàn)在,完成了,我們終于可以進入最終類并計算屏幕了!

第4步:計算屏幕

在Screen類中,大部分的計算都是為了使程序正常工作。要工作,該類需要以下導(dǎo)入:

import java.util.ArrayList;

import java.awt.Color;

實際的類是這樣開始的:

public class Screen {

public int[][] map;

public int mapWidth, mapHeight, width, height;

public ArrayList textures;

該地圖與在游戲類。屏幕使用它來確定墻壁在哪里以及與玩家之間的距離。寬度和高度定義屏幕的大小,并且應(yīng)始終與Game類中創(chuàng)建的框架的寬度和高度相同。紋理是所有紋理的列表,以便屏幕可以訪問紋理的像素。在聲明了這些變量之后,必須像下面這樣在構(gòu)造函數(shù)中對其進行初始化:

public Screen(int[][] m, ArrayList tex, int w, int h) {

map = m;

textures = tex;

width = w;

height = h;

}

現(xiàn)在是時候編寫類具有的一個方法了:update方法。更新方法根據(jù)用戶在地圖中的位置重新計算屏幕的外觀。該方法被不斷調(diào)用,并將更新后的像素數(shù)組返回給Game類。該方法開始于“清除”屏幕。通過將上半部分的所有像素設(shè)置為一種顏色,并將下半部分的所有像素設(shè)置為另一種顏色來實現(xiàn)此目的。

public int[] update(Camera camera, int[] pixels) {

for(int n=0; n if(pixels[n] != Color.DARK_GRAY.getRGB()) pixels[n] = Color.DARK_GRAY.getRGB();

}

for(int i=pixels.length/2; i if(pixels[i] != Color.gray.getRGB()) pixels[i] = Color.gray.getRGB();

}

讓屏幕的頂部和底部為兩個不同顏色也使它看起來好像有地板和天花板。清除像素陣列后,該是進行主要計算的時候了。該程序循環(huán)遍歷屏幕上的每個垂直條,并投射光線以找出該垂直條上的屏幕上應(yīng)該有什么墻。循環(huán)的開始看起來像這樣:

for(int x=0; xdouble cameraX = 2 * x / (double)(width) -1;

double rayDirX = camera.xDir + camera.xPlane * cameraX;

double rayDirY = camera.yDir + camera.yPlane * cameraX;

//Map position

int mapX = (int)camera.xPos;

int mapY = (int)camera.yPos;

//length of ray from current position to next x or y-side

double sideDistX;

double sideDistY;

//Length of ray from one side to next in map

double deltaDistX = Math.sqrt(1 + (rayDirY*rayDirY) / (rayDirX*rayDirX));

double deltaDistY = Math.sqrt(1 + (rayDirX*rayDirX) / (rayDirY*rayDirY));

double perpWallDist;

//Direction to go in x and y

int stepX, stepY;

boolean hit = false;//was a wall hit

int side=0;//was the wall vertical or horizontal

這里發(fā)生的所有事情都是計算出循環(huán)其余部分將要使用的一些變量。 CameraX是攝影機平面上當(dāng)前垂直條紋的x坐標(biāo),并且rayDir變量為射線創(chuàng)建矢量。計算所有以DistX或DistY結(jié)尾的變量,以便程序僅在可能發(fā)生碰撞的位置檢查碰撞。 perpWallDist是從播放器到射線與之碰撞的第一堵墻的距離。這將在以后計算。完成此操作后,我們需要根據(jù)已經(jīng)計算出的變量來找出其他一些變量。

//Figure out the step direction and initial distance to a side

if (rayDirX 《 0)

{

stepX = -1;

sideDistX = (camera.xPos - mapX) * deltaDistX;

}

else

{

stepX = 1;

sideDistX = (mapX + 1.0 - camera.xPos) * deltaDistX;

}

if (rayDirY 《 0)

{

stepY = -1;

sideDistY = (camera.yPos - mapY) * deltaDistY;

}

else

{

stepY = 1;

sideDistY = (mapY + 1.0 - camera.yPos) * deltaDistY;

}

一旦完成,就該找出射線與何處碰撞了。一堵墻。為此,程序要經(jīng)過一個循環(huán),在該循環(huán)中檢查射線是否與墻壁接觸,如果沒有,則移動到下一個可能的碰撞點,然后再次檢查。

//Loop to find where the ray hits a wall

while(!hit) {

//Jump to next square

if (sideDistX 《 sideDistY)

{

sideDistX += deltaDistX;

mapX += stepX;

side = 0;

}

else

{

sideDistY += deltaDistY;

mapY += stepY;

side = 1;

}

//Check if ray has hit a wall

if(map[mapX][mapY] 》 0) hit = true;

}

現(xiàn)在我們知道射線在何處撞擊墻壁,我們可以開始計算墻壁在我們當(dāng)前所在的垂直條紋中的外觀。為此,我們首先計算到墻的距離,然后使用該距離來計算出墻在垂直條中應(yīng)該有多高。然后,我們根據(jù)屏幕上的像素將該高度轉(zhuǎn)換為起點和終點。代碼如下所示:

//Calculate distance to the point of impact

if(side==0)

perpWallDist = Math.abs((mapX - camera.xPos + (1 - stepX) / 2) / rayDirX);

else

perpWallDist = Math.abs((mapY - camera.yPos + (1 - stepY) / 2) / rayDirY);

//Now calculate the height of the wall based on the distance from the camera

int lineHeight;

if(perpWallDist 》 0) lineHeight = Math.abs((int)(height / perpWallDist));

else lineHeight = height;

//calculate lowest and highest pixel to fill in current stripe

int drawStart = -lineHeight/2+ height/2;

if(drawStart 《 0)

drawStart = 0;

int drawEnd = lineHeight/2 + height/2;

if(drawEnd 》= height)

drawEnd = height - 1;

計算完之后,就該開始從墻的紋理中找出哪些像素會真正呈現(xiàn)給用戶了。為此,我們首先必須確定與剛擊中的墻關(guān)聯(lián)的紋理,然后確定將向用戶顯示的像素的紋理的x坐標(biāo)。

//add a texture

int texNum = map[mapX][mapY] - 1;

double wallX;//Exact position of where wall was hit

if(side==1) {//If its a y-axis wall

wallX = (camera.xPos + ((mapY - camera.yPos + (1 - stepY) / 2) / rayDirY) * rayDirX);

} else {//X-axis wall

wallX = (camera.yPos + ((mapX - camera.xPos + (1 - stepX) / 2) / rayDirX) * rayDirY);

}

wallX-=Math.floor(wallX);

//x coordinate on the texture

int texX = (int)(wallX * (textures.get(texNum).SIZE));

if(side == 0 && rayDirX 》 0) texX = textures.get(texNum).SIZE - texX - 1;

if(side == 1 && rayDirY 《 0) texX = textures.get(texNum).SIZE - texX - 1;

通過獲取在2D地圖上擊中墻壁的確切位置并減去整數(shù)值(僅保留小數(shù))來計算x坐標(biāo)。然后將此小數(shù)(wallX)乘以墻的紋理大小即可在我們希望繪制的像素的墻上獲得確切的x坐標(biāo)。一旦我們知道剩下要做的就是計算紋理上像素的y坐標(biāo)并將其繪制在屏幕上。為此,我們遍歷垂直條帶中屏幕上的所有像素,然后對其進行計算并計算紋理上像素的確切y坐標(biāo)。然后,使用該程序,程序?qū)⒓y理中像素的數(shù)據(jù)寫入屏幕上的像素陣列。該程序還使此處的水平墻比垂直墻暗,以提供基本的照明效果。

//calculate y coordinate on texture

for(int y=drawStart; y int texY = (((y*2 - height + lineHeight) 《《 6) / lineHeight) / 2;

int color;

if(side==0) color = textures.get(texNum).pixels[texX + (texY * textures.get(texNum).SIZE)];

else color = (textures.get(texNum).pixels[texX + (texY * textures.get(texNum).SIZE)]》》1) & 8355711;//Make y sides darker

pixels[x + y*(width)] = color;

}

然后,Screen類中剩下的就是返回像素數(shù)組

return pixels;

該類完成。現(xiàn)在,我們要做的就是在Game類中添加幾行代碼以使屏幕正常運行。在變量頂部添加以下內(nèi)容:

public Screen screen;

,然后在構(gòu)造函數(shù)中,在初始化紋理之后,將其添加到某處。

screen = new Screen(map, mapWidth, mapHeight, textures, 640, 480);

最后,在在camera.update(map)之前運行運行方法add

screen.update(camera, pixels);

。程序就完成了!

步驟5:最終代碼

責(zé)任編輯:wv

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • JAVA
    +關(guān)注

    關(guān)注

    20

    文章

    3001

    瀏覽量

    116434
  • 3D引擎
    +關(guān)注

    關(guān)注

    0

    文章

    6

    瀏覽量

    8335
收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關(guān)推薦
    熱點推薦

    常見3D打印材料介紹及應(yīng)用場景分析

    3D打印材料種類豐富,不同材料性能差異明顯。本文介紹PLA、ABS、PETG等常見3D打印材料的特點與應(yīng)用場景,幫助讀者了解3D打印什么材料更合適,為選材提供基礎(chǔ)參考。
    的頭像 發(fā)表于 12-29 14:52 ?619次閱讀
    常見<b class='flag-5'>3D</b>打印材料介紹及應(yīng)用場景分析

    探索TLE493D-P3XX-MS2GO 3D 2Go套件:開啟3D磁傳感器評估之旅

    探索TLE493D-P3XX-MS2GO 3D 2Go套件:開啟3D磁傳感器評估之旅 在電子工程師的日常工作中,評估和開發(fā)磁傳感器是一項常見且重要的任務(wù)。英飛凌(Infineon
    的頭像 發(fā)表于 12-18 17:15 ?826次閱讀

    半導(dǎo)體“HBM和3D Stacked Memory”技術(shù)的詳解

    3D Stacked Memory是“技術(shù)方法”,而HBM是“這種方法解決特定問題的產(chǎn)品”。
    的頭像 發(fā)表于 11-07 19:39 ?6131次閱讀
    半導(dǎo)體“HBM和<b class='flag-5'>3D</b> Stacked Memory”技術(shù)的詳解

    微納尺度的神筆——雙光子聚合3D打印 #微納3D打印

    3D打印
    楊明遠
    發(fā)布于 :2025年10月25日 13:09:29

    玩轉(zhuǎn) KiCad 3D模型的使用

    “ ?本文將帶您學(xué)習(xí)如何將 3D 模型與封裝關(guān)聯(lián)、文件嵌入,講解 3D 查看器中的光線追蹤,以及如何使用 CLI 生成 PCBA 的 3D 模型。? ” ? 在日常的 PCB 設(shè)計中,我們大部分
    的頭像 發(fā)表于 09-16 19:21 ?1.2w次閱讀
    玩轉(zhuǎn) KiCad <b class='flag-5'>3D</b>模型的使用

    AD 3D封裝庫資料

    ?AD ?PCB 3D封裝
    發(fā)表于 08-27 16:24 ?7次下載

    3D打印能用哪些材質(zhì)?

    3D打印的材質(zhì)有哪些?不同材料決定了打印效果、強度、用途乃至安全性,本文將介紹目前主流的3D打印材質(zhì),幫助你找到最適合自己需求的材料。
    的頭像 發(fā)表于 07-28 10:58 ?3792次閱讀
    <b class='flag-5'>3D</b>打印能用哪些材質(zhì)?

    3D AD庫文件

    3D庫文件
    發(fā)表于 05-28 13:57 ?6次下載

    光庭信息Kustom3D引擎登陸2025上海車展

    隨著智能座艙的演進,3D交互界面已成為車載體驗的核心載體。從3D車模、感知地圖到沉浸式桌面,3D技術(shù)正逐步滲透座艙的每個角落。傳統(tǒng)3D交互模式因場景固化、高成本和迭代困難等問題,難以實
    的頭像 發(fā)表于 04-30 16:04 ?916次閱讀

    3D閃存的制造工藝與挑戰(zhàn)

    3D閃存有著更大容量、更低成本和更高性能的優(yōu)勢,本文介紹了3D閃存的制造工藝與挑戰(zhàn)。
    的頭像 發(fā)表于 04-08 14:38 ?2432次閱讀
    <b class='flag-5'>3D</b>閃存的制造工藝與挑戰(zhàn)

    開源項目!如何制作一個手機的電動3D掃描轉(zhuǎn)盤

    這個項目里,作者會教你怎么做一個簡單的電動3D掃描轉(zhuǎn)盤,主要是給手機的。整個裝置分為三個部分:頂板、齒輪板和底座。頂板是個固定的平臺,用來放置你要掃描的物體。 中間的齒輪板是整個裝置的核心,它有
    發(fā)表于 03-25 13:45

    英倫科技光場裸眼3D顯示產(chǎn)品在博物館裸眼3D顯示方面的應(yīng)用

    英倫科技的技術(shù)突破了傳統(tǒng)展陳的物理限制,通過高沉浸感體驗提升觀眾參與度(據(jù)統(tǒng)計,采用裸眼3D的展區(qū)觀眾停留時間增加40%),同時為文物保護和非接觸式觀展提供了創(chuàng)新路徑。未來隨著AI生成內(nèi)容(AIGC)的發(fā)展,其3D內(nèi)容制作效率將
    的頭像 發(fā)表于 03-25 10:27 ?1054次閱讀
    英倫科技光場裸眼<b class='flag-5'>3D</b>顯示產(chǎn)品在博物館裸眼<b class='flag-5'>3D</b>顯示方面的應(yīng)用

    3D打印可以打印那種柔韌性好,能隨意變形的模型嗎?

    3D打印) 顯然,TPU打印的模型在經(jīng)歷了多次扭曲后仍能保持結(jié)構(gòu)完整性,雖然在過程中出現(xiàn)了一些變形,也很快就能恢復(fù)原狀。所以說,3D打印是能夠用來制作像鞋墊、手機殼、護腕這樣的產(chǎn)品,是不是非常神奇!
    發(fā)表于 03-13 11:41

    配備3D圖形加速引擎的通用微處理器RZ/G2LC數(shù)據(jù)手冊

    RZ/G2LC 微處理器配備 Cortex?-A55 (1.2 GHz) CPU、16 位 DDR3L/DDR4 接口以及帶 Arm Mali-G31的 3D 圖形加速引擎。 此外,這款微處理器還
    的頭像 發(fā)表于 03-12 17:29 ?871次閱讀
    配備<b class='flag-5'>3D</b>圖形加速<b class='flag-5'>引擎</b>的通用微處理器RZ/G2LC數(shù)據(jù)手冊

    EPLAN 2.6 3D制作與使用

    電子發(fā)燒友網(wǎng)站提供《EPLAN 2.6 3D制作與使用.pdf》資料免費下載
    發(fā)表于 03-11 15:53 ?1次下載