3D模拟自然——山体

2024-05-15 10:58
文章标签 模拟 3d 自然 山体

本文主要是介绍3D模拟自然——山体,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

算法上使用分形插值算法。渲染上,效率和扩展性中最理想的是用shader,但为了方便也可以用封装好的pixmap或shapeRenderer。这里用pixmap来绘制3d山。值得一提,1.6.1API:Color.toIntBits(int r,int g,int b,int a)是错的,参数位置前后倒了,导致山体一片红,所以顺着对的修改完毕。可以重置,修改blend模式以及精细程度。

以下是代码和效果图。

           

(可以看到n值为2倍后内存消耗增加不止1倍,渲染算法上是需要改进的)

package indi.dawn.ff.work;import java.util.StringTokenizer;import com.badlogic.gdx.Application.ApplicationType;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.Pixmap;
import com.badlogic.gdx.graphics.Pixmap.Blending;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.Pixmap.Format;
import com.badlogic.gdx.graphics.g2d.Batch;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
import com.badlogic.gdx.scenes.scene2d.Actor;
import com.badlogic.gdx.scenes.scene2d.InputEvent;
import com.badlogic.gdx.scenes.scene2d.InputListener;
import com.badlogic.gdx.utils.Disposable;class MountainC extends Actor implements Disposable{ShapeRenderer jj;int n = 32, n1,  h,w,h2,w2, mx0,my0,  xPol[],yPol[], iCol[][][];double rnd,  fiX = .2, fiY = .3, dfi = .01, scale = .8, m20,m21,m22;double vert[][][], vert1[][][], Norm[][][][], Norm1z[][][], M[];Color col[][];boolean painted;Texture buffImage;Pixmap buffGraphics;InputListener ip;public MountainC(){ip=new InputListener(){@Overridepublic boolean touchDown(InputEvent event, float x, float y,int pointer, int button) {// TODO Auto-generated method stubmx0 = (int) x;  my0 = (int) y;if ( Gdx.input.isKeyPressed(Input.Keys.CONTROL_LEFT) ){setup();
//				    repaint();}if ( Gdx.input.isKeyPressed(Input.Keys.ALT_LEFT) ){if (Gdx.input.isKeyPressed(Input.Keys.SHIFT_LEFT) ){ n /= 2;  if (n < 1) n = 1;}else n *= 2;setup();
//				    repaint();}if(Gdx.app.getType()==ApplicationType.Android){if (pointer==1){n *= 2;setup();
//						    repaint();}if (pointer==2 ){ n /= 2;  if (n < 1) n = 1;}}return true;}@Overridepublic void touchDragged(InputEvent event, float x, float y,int pointer) {// TODO Auto-generated method stubint x1 = (int) x;  int y1 = (int) y;if ( Gdx.input.isKeyPressed(Input.Keys.SHIFT_LEFT) )  scale *= Math.exp(-(y1 - my0)/(double)w);else   fiX += dfi*(y1 - my0);fiY += dfi*(x1 - mx0);   mx0 = x1;  my0 = y1;rotate();
//				  repaint();}};init();/*for(int i=0;i<4;i++){for(Color c:col[i]){System.out.println(c.toIntBits());}}*/}private Color calCol(int r,int g,int b){return new Color(Color.toIntBits(255, b, g, r));};int getN(){return 32;}Color getCol(){return Color.WHITE;}Color bgColor;int pmWidth=600,pmHeight=800;public void init(){
//		w=(int) getWidth();h=(int) getHeight();w = pmWidth;  h = pmHeight;  w2 = w/2;  h2 = h/2;
//		  n=getN();xPol = new int[3];  yPol = new int[3];buffGraphics=new Pixmap(w, h, Pixmap.Format.RGB888);
//		  buffGraphics.setBlending(Blending.SourceOver);buffImage= new Texture(buffGraphics);col = new Color[4][256];for (int i = 0; i < 256; i++){col[0][i] = calCol(0, 0, i);col[1][i] = calCol(0, (i*220)/256, 0);col[2][i] = calCol((i*150)/256, (i*150)/256, (i*50)/256);col[3][i] = calCol(i, i, i);}for(int i=0;i<4;i++){for(Color c:col[i]){System.out.println(c);}}bgColor=getCol();if(bgColor==null)bgColor=Color.WHITE;addListener(ip);setup();}public double R(){ return rnd*(Math.random()-.5);}public void setup(){rnd = 1;n1 = n+1;iterate();vert = new double[n1][n1][3];  vert1 = new double[n1][n1][2];double dx = w/(double)n;int t = 0;for (int i = 0; i < n1; i++) for (int j = 0; j < n1; j++){vert[i][j][0] = dx*i - w2;  vert[i][j][2] = dx*j - w2;double mi = M[t++];if (mi < 0) mi = .01*Math.random();vert[i][j][1] = w*mi - w2/2;}Norm = new double[n1][n1][2][3];  Norm1z = new double[n1][n1][2];iCol = new int[n][n][2];for (int i = 0; i < n; i++)for (int j = 0; j < n; j++){double s =((vert[i][j][1] + vert[i+1][j][1] + vert[i+1][j+1][1])/3 + w2/2)/w;if (s < .01) iCol[i][j][0] = 0;else if (s+.1*Math.random() > .35) iCol[i][j][0] = 3;else if (s+.1*Math.random() > .15)  iCol[i][j][0] = 2;else  iCol[i][j][0] = 1;s = ((vert[i][j][1] + vert[i][j+1][1] + vert[i+1][j+1][1])/3 + w2/2)/w;if (s < .01) iCol[i][j][1] = 0;else if (s+.1*Math.random() > .35) iCol[i][j][1] = 3;else if (s+.1*Math.random() > .15)  iCol[i][j][1] = 2;else  iCol[i][j][1] = 1;Norm[i][j][0][0] = vert[i][j][1] - vert[i+1][j][1];Norm[i][j][0][1] = dx;Norm[i][j][0][2] = vert[i+1][j][1] - vert[i+1][j+1][1];double mod = Math.sqrt(Norm[i][j][0][0]*Norm[i][j][0][0] + Norm[i][j][0][1]*Norm[i][j][0][1] + Norm[i][j][0][2]*Norm[i][j][0][2]) / 255.5;Norm[i][j][0][0] /= mod; Norm[i][j][0][1] /= mod; Norm[i][j][0][2] /= mod;Norm[i][j][1][0] = vert[i][j+1][1] - vert[i+1][j+1][1];Norm[i][j][1][1] = dx;Norm[i][j][1][2] = vert[i][j][1] - vert[i][j+1][1];mod = Math.sqrt(Norm[i][j][1][0]*Norm[i][j][1][0] + Norm[i][j][1][1]*Norm[i][j][1][1] + Norm[i][j][1][2]*Norm[i][j][1][2]) / 255.5;Norm[i][j][1][0] /= mod; Norm[i][j][1][1] /= mod; Norm[i][j][1][2] /= mod;}rotate();}public void iterate(){int nc=n, Max=n1*n1, ncn1;double Min=-1;M = new double[Max];for (int i=n+2; i < n*n1-1; i++) M[i] = Min;for (int i=2*n1; i < n*n1; i += n1) M[i] = M[i-1] = 0;while ( (nc /= 2) >= 1){ncn1 = nc*n1;for (int j=ncn1; j < Max; j += ncn1+ncn1){for (int i= nc; i < n; i += nc+nc){if (M[i+j]==Min)M[i+j] = (M[i+j+nc-ncn1] + M[i+j-nc+ncn1])/2.+R();if (M[i+j+nc]==Min)M[i+j+nc] = (M[i+j+nc+ncn1] + M[i+j+nc-ncn1])/2.+R();if (M[i+j+ncn1]==Min)M[i+j+ncn1] = (M[i+j-nc+ncn1] + M[i+j+nc+ncn1])/2.+R(); }}rnd /= 2.;}}public void rotate(){double ct = Math.cos(fiX), cf = Math.cos(fiY),st = Math.sin(fiX), sf = Math.sin(fiY),m00 =  scale*cf,    m02 =  scale*sf,m10 = scale*st*sf, m11 =  scale*ct, m12 = -scale*st*cf;m20 = -ct*sf; m21 = st; m22 = ct*cf;for (int i = 0; i < n1; i++)for (int j = 0; j < n1; j++){vert1[i][j][0] = m00*vert[i][j][0] + m02*vert[i][j][2];vert1[i][j][1] = m10*vert[i][j][0] + m11*vert[i][j][1] + m12*vert[i][j][2];}for (int i = 0; i < n; i++)for (int j = 0; j < n; j++)for (int k = 0; k < 2; k++)Norm1z[i][j][k] = m20*Norm[i][j][k][0] + m21*Norm[i][j][k][1] +m22*Norm[i][j][k][2];painted = false;}@Overridepublic void draw(Batch batch, float parentAlpha) {// TODO Auto-generated method stubif ( !painted ){if(buffImage!=null){buffImage.dispose();buffImage=null;/* buffGraphics.dispose();buffGraphics=new Pixmap(w, h, Format.RGB888);*/}
//			 buffGraphics.dispose();
//			 Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);buffGraphics.setColor(Color.WHITE);buffGraphics.fill();int ib=0, ie=n, sti=1,  jb=0, je=n, stj=1;if (m20 < 0){ ib = n; ie = -1; sti = -1;}if (m22 < 0){ jb = n; je = -1; stj = -1;}for (int i = ib; i != ie; i += sti)for (int j = jb; j != je; j += stj){if (Norm1z[i][j][0] > 0){xPol[0] = w2 + (int)vert1[i][j][0];xPol[1] = w2 + (int)vert1[i+1][j][0];xPol[2] = w2 + (int)vert1[i+1][j+1][0];yPol[0] = h2 - (int)vert1[i][j][1];yPol[1] = h2 - (int)vert1[i+1][j][1];yPol[2] = h2 - (int)vert1[i+1][j+1][1];System.out.println(iCol[i][j][0]+"?"+(int)(Norm1z[i][j][0]));System.out.println(col[iCol[i][j][0]][(int)(Norm1z[i][j][0])].toString());buffGraphics.setColor(col[iCol[i][j][0]][(int)(Norm1z[i][j][0])]);buffGraphics.fillTriangle(xPol[0], yPol[0], xPol[1], yPol[1], xPol[2], yPol[2]);
//			     buffGraphics.fillPolygon(xPol,yPol, 3);}if (Norm1z[i][j][1] > 0){xPol[0] = w2 + (int)vert1[i][j][0];xPol[1] = w2 + (int)vert1[i][j+1][0];xPol[2] = w2 + (int)vert1[i+1][j+1][0];yPol[0] = h2 - (int)vert1[i][j][1];yPol[1] = h2 - (int)vert1[i][j+1][1];yPol[2] = h2 - (int)vert1[i+1][j+1][1];buffGraphics.setColor(col[iCol[i][j][1]][(int)(Norm1z[i][j][1])]);buffGraphics.fillTriangle(xPol[0], yPol[0], xPol[1], yPol[1], xPol[2], yPol[2]);} }painted = true;buffImage=new Texture(buffGraphics, true);}
//		 Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);batch.draw(buffImage, getX(), getY());/*if(!painted){buffGraphics.setColor(col(255, 0, 0));buffGraphics.fill();buffImage=new Texture(buffGraphics);painted = true;}batch.draw(buffImage, getX(), getY());*///			 g.drawImage(buffImage, 0, 0, this);}@Overridepublic void dispose() {// TODO Auto-generated method stubbuffGraphics.dispose();buffImage.dispose();}/***************************************************//*public void init2(){w = getSize().width;  h = getSize().height;   w2 = w/2;  h2 = h/2;String s=getParameter("N");  if (s != null) n = Integer.parseInt(s);xPol = new int[3];  yPol = new int[3];buffImage = createImage(w, h);   buffGraphics = buffImage.getGraphics();col = new Color[4][256];for (int i = 0; i < 256; i++){col[0][i] = new Color(0, 0, i);col[1][i] = new Color(0, (i*220)/256, 0);col[2][i] = new Color((i*150)/256, (i*150)/256, (i*50)/256);col[3][i] = new Color(i, i, i);}s = getParameter("bgColor"); if (s != null){StringTokenizer st = new StringTokenizer(s);int red = Integer.parseInt(st.nextToken());int green = Integer.parseInt(st.nextToken());int blue = Integer.parseInt(st.nextToken());setBackground( new Color(red, green, blue));}else setBackground(new Color(255,255,255));addMouseListener(this);addMouseMotionListener(this);setup();for(int i=0;i<4;i++){for(Color c:col[i]){int a=c.getRed();int b=c.getGreen();int g=c.getBlue();int r=			c.getAlpha();int m=(a << 24) | (b << 16) | (g << 8) | r;System.out.println(m);}}}*/public void rotate2(){double ct = Math.cos(fiX), cf = Math.cos(fiY),st = Math.sin(fiX), sf = Math.sin(fiY),m00 =  scale*cf,    m02 =  scale*sf,m10 = scale*st*sf, m11 =  scale*ct, m12 = -scale*st*cf;m20 = -ct*sf; m21 = st; m22 = ct*cf;for (int i = 0; i < n1; i++)for (int j = 0; j < n1; j++){vert1[i][j][0] = m00*vert[i][j][0] + m02*vert[i][j][2];vert1[i][j][1] = m10*vert[i][j][0] + m11*vert[i][j][1] + m12*vert[i][j][2];}for (int i = 0; i < n; i++)for (int j = 0; j < n; j++)for (int k = 0; k < 2; k++)Norm1z[i][j][k] = m20*Norm[i][j][k][0] + m21*Norm[i][j][k][1] +m22*Norm[i][j][k][2];painted = false;}public void iterate2(){int nc=n, Max=n1*n1, ncn1;double Min=-1;M = new double[Max];for (int i=n+2; i < n*n1-1; i++) M[i] = Min;for (int i=2*n1; i < n*n1; i += n1) M[i] = M[i-1] = 0;while ( (nc /= 2) >= 1){ncn1 = nc*n1;for (int j=ncn1; j < Max; j += ncn1+ncn1){for (int i= nc; i < n; i += nc+nc){if (M[i+j]==Min)M[i+j] = (M[i+j+nc-ncn1] + M[i+j-nc+ncn1])/2.+R();if (M[i+j+nc]==Min)M[i+j+nc] = (M[i+j+nc+ncn1] + M[i+j+nc-ncn1])/2.+R();if (M[i+j+ncn1]==Min)M[i+j+ncn1] = (M[i+j-nc+ncn1] + M[i+j+nc+ncn1])/2.+R(); }}rnd /= 2.;}}public void setup2(){rnd = 1;n1 = n+1;iterate();vert = new double[n1][n1][3];  vert1 = new double[n1][n1][2];double dx = w/(double)n;int t = 0;for (int i = 0; i < n1; i++) for (int j = 0; j < n1; j++){vert[i][j][0] = dx*i - w2;  vert[i][j][2] = dx*j - w2;double mi = M[t++];if (mi < 0) mi = .01*Math.random();vert[i][j][1] = w*mi - w2/2;}Norm = new double[n1][n1][2][3];  Norm1z = new double[n1][n1][2];iCol = new int[n][n][2];for (int i = 0; i < n; i++)for (int j = 0; j < n; j++){double s =((vert[i][j][1] + vert[i+1][j][1] + vert[i+1][j+1][1])/3 + w2/2)/w;if (s < .01) iCol[i][j][0] = 0;else if (s+.1*Math.random() > .35) iCol[i][j][0] = 3;else if (s+.1*Math.random() > .15)  iCol[i][j][0] = 2;else  iCol[i][j][0] = 1;s = ((vert[i][j][1] + vert[i][j+1][1] + vert[i+1][j+1][1])/3 + w2/2)/w;if (s < .01) iCol[i][j][1] = 0;else if (s+.1*Math.random() > .35) iCol[i][j][1] = 3;else if (s+.1*Math.random() > .15)  iCol[i][j][1] = 2;else  iCol[i][j][1] = 1;Norm[i][j][0][0] = vert[i][j][1] - vert[i+1][j][1];Norm[i][j][0][1] = dx;Norm[i][j][0][2] = vert[i+1][j][1] - vert[i+1][j+1][1];double mod = Math.sqrt(Norm[i][j][0][0]*Norm[i][j][0][0] + Norm[i][j][0][1]*Norm[i][j][0][1] + Norm[i][j][0][2]*Norm[i][j][0][2]) / 255.5;Norm[i][j][0][0] /= mod; Norm[i][j][0][1] /= mod; Norm[i][j][0][2] /= mod;Norm[i][j][1][0] = vert[i][j+1][1] - vert[i+1][j+1][1];Norm[i][j][1][1] = dx;Norm[i][j][1][2] = vert[i][j][1] - vert[i][j+1][1];mod = Math.sqrt(Norm[i][j][1][0]*Norm[i][j][1][0] + Norm[i][j][1][1]*Norm[i][j][1][1] + Norm[i][j][1][2]*Norm[i][j][1][2]) / 255.5;Norm[i][j][1][0] /= mod; Norm[i][j][1][1] /= mod; Norm[i][j][1][2] /= mod;}rotate();}
}


这篇关于3D模拟自然——山体的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/991643

相关文章

无人叉车3d激光slam多房间建图定位异常处理方案-墙体画线地图切分方案

墙体画线地图切分方案 针对问题:墙体两侧特征混淆误匹配,导致建图和定位偏差,表现为过门跳变、外月台走歪等 ·解决思路:预期的根治方案IGICP需要较长时间完成上线,先使用切分地图的工程化方案,即墙体两侧切分为不同地图,在某一侧只使用该侧地图进行定位 方案思路 切分原理:切分地图基于关键帧位置,而非点云。 理论基础:光照是直线的,一帧点云必定只能照射到墙的一侧,无法同时照到两侧实践考虑:关

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象

usaco 1.2 Transformations(模拟)

我的做法就是一个一个情况枚举出来 注意计算公式: ( 变换后的矩阵记为C) 顺时针旋转90°:C[i] [j]=A[n-j-1] [i] (旋转180°和270° 可以多转几个九十度来推) 对称:C[i] [n-j-1]=A[i] [j] 代码有点长 。。。 /*ID: who jayLANG: C++TASK: transform*/#include<

hdu4431麻将模拟

给13张牌。问增加哪些牌可以胡牌。 胡牌有以下几种情况: 1、一个对子 + 4组 3个相同的牌或者顺子。 2、7个不同的对子。 3、13幺 贪心的思想: 对于某张牌>=3个,先减去3个相同,再组合顺子。 import java.io.BufferedInputStream;import java.io.BufferedReader;import java.io.IOExcepti

【每日一题】LeetCode 2181.合并零之间的节点(链表、模拟)

【每日一题】LeetCode 2181.合并零之间的节点(链表、模拟) 题目描述 给定一个链表,链表中的每个节点代表一个整数。链表中的整数由 0 分隔开,表示不同的区间。链表的开始和结束节点的值都为 0。任务是将每两个相邻的 0 之间的所有节点合并成一个节点,新节点的值为原区间内所有节点值的和。合并后,需要移除所有的 0,并返回修改后的链表头节点。 思路分析 初始化:创建一个虚拟头节点

MiniGPT-3D, 首个高效的3D点云大语言模型,仅需一张RTX3090显卡,训练一天时间,已开源

项目主页:https://tangyuan96.github.io/minigpt_3d_project_page/ 代码:https://github.com/TangYuan96/MiniGPT-3D 论文:https://arxiv.org/pdf/2405.01413 MiniGPT-3D在多个任务上取得了SoTA,被ACM MM2024接收,只拥有47.8M的可训练参数,在一张RTX

每日一题|牛客竞赛|四舍五入|字符串+贪心+模拟

每日一题|四舍五入 四舍五入 心有猛虎,细嗅蔷薇。你好朋友,这里是锅巴的C\C++学习笔记,常言道,不积跬步无以至千里,希望有朝一日我们积累的滴水可以击穿顽石。 四舍五入 题目: 牛牛发明了一种新的四舍五入应用于整数,对个位四舍五入,规则如下 12345->12350 12399->12400 输入描述: 输入一个整数n(0<=n<=109 ) 输出描述: 输出一个整数

【算法专场】模拟(下)

目录 前言 38. 外观数列 算法分析 算法思路 算法代码 1419. 数青蛙 算法分析 算法思路 算法代码  2671. 频率跟踪器 算法分析 算法思路 算法代码 前言 在前面我们已经讲解了什么是模拟算法,这篇主要是讲解在leetcode上遇到的一些模拟题目~ 38. 外观数列 算法分析 这道题其实就是要将连续且相同的字符替换成字符重复的次数+

SAM2POINT:以zero-shot且快速的方式将任何 3D 视频分割为视频

摘要 我们介绍 SAM2POINT,这是一种采用 Segment Anything Model 2 (SAM 2) 进行零样本和快速 3D 分割的初步探索。 SAM2POINT 将任何 3D 数据解释为一系列多向视频,并利用 SAM 2 进行 3D 空间分割,无需进一步训练或 2D-3D 投影。 我们的框架支持各种提示类型,包括 3D 点、框和掩模,并且可以泛化到不同的场景,例如 3D 对象、室

模拟实现vector中的常见接口

insert void insert(iterator pos, const T& x){if (_finish == _endofstorage){int n = pos - _start;size_t newcapacity = capacity() == 0 ? 2 : capacity() * 2;reserve(newcapacity);pos = _start + n;//防止迭代