OpenGL绘制随机的山脉轮廓

OpenGL绘制随机的山脉轮廓

三维图形程序设计作业: 使用递归的方式生成随机的山脉轮廓
运行结果:
运行实例

详细代码

// An highlighted block
#include <GL/glut.h>
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<math.h>

#define random(x) (rand()%x)

//N取奇数,设置数组大小即最大用于描绘山的点的数目
#define N 1001


float a[N][2];
int b[N];

//底两点坐标
float d[2][2] = {{-0.5,-0.5}, {0.5,-0.5} };
float t[2] = {0,0.5};

int randomp(int t1, int t2) {

	//取t1-t2之间的随机数
	float t = rand() % 101;

	int t3 = (int)((t / 100)*(t2 - t1) + t1);
	
	return t3;

}
void randomd(int t1, int t2,int t3) {

	//满足条件能进入函数体的t3做标识,表示将定义此点和进行绘制
	b[t3] = 1;
	float t = rand() % 101;

	//随机取正负
	int sign = random(2);
	if (sign == 0) sign = -1;
	printf("%d\n", sign);
	
	//随机的移动距离,与原两点距离成比例
	float d = sign*(t / 600);

	//给t3点一个新的坐标
	a[t3][0] = (a[t2][0] - a[t1][0])*(float)(t3 - t1) / (float)(t2 - t1) + a[t1][0]
		+d * (a[t2][1] - a[t1][1]) ;
	a[t3][1] = (a[t2][1] - a[t1][1])*(t3 - t1) / (t2 - t1) + a[t1][1]
		+d * (a[t2][0] - a[t1][0]);

	printf("t1,%f,%f\n", a[t1][0], a[t1][1]);
	printf("t2,%f,%f\n", a[t2][0], a[t2][1]);
	printf("t3,%f,%f\n", a[t3][0], a[t3][1]);

	//递归定义
	int t4=randomp(t1, t3);
	if (!(b[t4]==1||t4==t1||t4==t3||t1==t3))
		randomd(t1, t3, t4);


	int t5 = randomp(t3, t2);
	if (!(b[t5] == 1 || t5 == t3|| t5 == t2 || t2 == t3 ))
		randomd(t3, t2,t5);
}

void display()
{
	glClear(GL_COLOR_BUFFER_BIT);


	//设置随机数种子
	srand((int)time(0));

	//对标签数组b进行初始化
	for(int i=0;i<N;i++)
		b[i]=0;

	//底两点设置
	a[0][0] = d[0][0];
	a[0][1] = d[0][1];
	a[N-1][0]= d[1][0];
	a[N - 1][1] = d[1][1];

	//顶点设置
	a[(N - 1) / 2][0] = t[0];
	a[(N - 1) / 2][1] = t[1];

	//对已定的坐标点做标志
	b[0] = 1;
	b[N - 1] = 1;
	b[(N - 1) / 2] = 1;

	//在线段上随机取点,输入参数为两点序号,小的在前,大的在后
	int l=randomp(0, (N - 1) / 2);
	randomd(0, (N - 1) / 2, l);
	int r = randomp( (N - 1) / 2,N-1);
	randomd((N - 1) / 2, N-1, r);
	//递归在函数体randomd中已定义,故不用在此定义
	

	//绘制山峰
	glBegin(GL_LINE_LOOP);
	//glBegin(GL_POLYGON);
	for (int i = 0; i < N; i++) {
		if (b[i] == 1) {
			glVertex2f(a[i][0], a[i][1]);
			printf("%d:%f,%f\n", i,a[i][0], a[i][1]);
		}
	}
	glEnd();

	glFlush();
}

void init()
{
	glClearColor(0.0, 0.0, 0.0, 0.0);
	glColor3f(1.0, 1.0, 1.0);
}


int main(int argc, char* argv[])
{

	glutInit(&argc, argv);

	glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
	glutInitWindowSize(500, 500);
	glutInitWindowPosition(100, 100);
	glutCreateWindow("Simple");

	glutDisplayFunc(display);

	init();

	glutMainLoop();


	return 0;
}

有帮助点一下赞哦~

### 创建或模拟LAMMPS中的三维随机分布粗糙表面 为了在LAMMPS中创建或模拟具有三维随机分布特征的粗糙表面轮廓,可以采用以下方法: #### 方法一:通过自定义数据文件导入 一种常见的方式是预先生成描述粗糙表面的数据文件,并将其作为输入读入到LAMMPS环境中。这可以通过MATLAB或其他编程工具来实现。 对于具体的MATLAB代码片段用于生成这样的表面高度图,可考虑如下形式[^2]: ```matlab sigma = 0.5; %标准差参数调整 bet_x = 1; bet_y = 1; [K, L] = meshgrid(1:100, 1:100); % 定义网格大小 R = sigma^2 * exp(-2.3 * sqrt(((K-1)/bet_x).^2 + ((L-1)./bet_y).^2)); surf(K,L,R); shading interp; colorbar; title('Random Rough Surface'); xlabel('X axis'); ylabel('Y axis'); zlabel('Height Z'); ``` 上述代码能够生成一个基于指数衰减模型的高度矩阵`R`表示的二维表面上每一点处的相对位移量。之后,这些数值被转换成适合于LAMMPS使用的坐标系并保存至外部文件供后续调用。 #### 方法二:利用LAMMPS内置命令构建复杂结构 另一种更为直接的方法是在LAMMPS内部使用特定指令组合来建立所需的几何形状。例如,借助`region`, `lattice`, 和 `create_atoms`等命令配合起来操作,同时应用一些额外的操作符如`displace_atoms`来进行局部扰动以形成不平整的效果。 下面是一个简单的例子展示如何设置基本晶格以及引入随机偏移: ```bash units metal dimension 3 boundary p p s atom_style atomic read_data data.file # 假设已经有一个基础原子配置文件data.file # 添加一层新的原子层模仿上表面 region surface block EDGE EDGE INF 10 units box create_box 1 region surface lattice fcc 3.5 orient x 1 0 0 orient y 0 1 0 orient z 0 0 1 create_atoms 1 region surface # 对新加入的一层施加随机位置变化 variable seed equal 9876543 displace_atoms all random 0.5 0.5 0 ${seed} write_dump all atom surf.dump ``` 这段脚本首先加载了一个现有的体系构型(`data.file`),接着在其顶部添加了一层fcc晶体结构的新原子,并对其执行了限定范围内的随机化移动,从而实现了简单版本的“粗糙”。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值