4.3 stability应用程序

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/JennyBi/article/details/82109958

4.2 flashlight基础上的改进

kernel.h

#pragma once
#ifndef KERNEL_H
#define KERNEL_H

struct uchar4;
struct int2;

void kernelLauncher(uchar4 *d_out, int w, int h, float p, int s);

#endif // !KERNEL_H

kernel.cu

#include "kernel.h"
#define TX 32//线程数
#define TY 32
#define LEN 5.f//空间比例因子
#define TIME_STEP 0.005f//时间步长
#define FINAL_TIME 10.f//时间间隔

__device__ float scale(int i, int w)//限定像素值的坐标范围[-LEN,LEN]
{
	return 2 * LEN*(((1.f*i) / w) - 0.5f);
}

__device__ float f(float x, float y, float param, float sys)//速度的变化率
{
	if (sys==1)//线性阻尼振荡器
	{
		return x - 2 * param*y;
	}
	if (sys == 2)//负有效刚度线性振荡器(接近于倒立摆位的情况)
	{
		return -x + param*(1 - x*x)*y;
	}
	else
		return -x - 2 * param*y;//范德堡尔振荡器,具有一个非线性阻尼项
}

//对一个给定的初始状态进行模拟,并且根据轨迹的位置在模拟区间结尾返回一个float2型的值
__device__ float2 euler(float x, float y, float dt, float tFinal, float param, float sys)
{
	float dx = 0.f, dy = 0.f;
	for (float t = 0; t < tFinal; t+=dt)
	{
		dx = dt*y;
		dy = dt*f(x, y, param, sys);
		x += dx;
		y += dy;
	}
	return make_float2(x, y);
}

__device__ unsigned char clip(int n)
{
	return n > 255 ? 255 : (n < 0 ? 0 : n);
}
__global__ void stabImageKernel(uchar4 *d_out, int w, int h, float p, int s)//阻尼参数p 振荡器类型s
{
	const int c = blockIdx.x*blockDim.x + threadIdx.x;
	const int r = blockIdx.x*blockDim.y + threadIdx.y;
	if ((c>=w)||(r>=h))
	{
		return;
	}
	const int i = c + r*w;
	const float x0 = scale(c, w);
	const float y0 = scale(r, h);
	const float dist_0 = sqrt(x0*x0 + y0*y0);
	const float2 pos = euler(x0, y0, TIME_STEP, FINAL_TIME, p, s);
	const float dist_f = sqrt(pos.x*pos.x+pos.y*pos.y);//基于距离比较分配阴影值
	const float dist_r = dist_f / dist_0;
	d_out[i].x = clip(dist_r * 255);//red逐渐远离平衡(即否决稳定的其他投票)
	d_out[i].y = ((c == w / 2));//green
	d_out[i].z = clip((1 / dist_r) * 255);//blue代表衰减到平衡(即稳定的投票)
	d_out[i].w = 255;

}
void kernelLauncher(uchar4 *d_out, int w, int h, float p, int s)
{
	const dim3 blockSize(TX, TY);
	const dim3 gridSize = dim3((w + TX - 1) / TX, (h + TY - 1) / TY);
	stabImageKernel << <gridSize, blockSize >> > (d_out, w, h, p, s);
}

interactions.h

#pragma once
#ifndef INTERACTIONS_H
#define INTERACTIONS_H
#define W 600//图像维度
#define H 600
#define DELTA 5//每按下箭头键参考点移动的距离(以像素为单位)
//#define  TITLE_STRING "flashlight:distance image display app"//标题栏中显示的文本
#define DELTA_P 0.1f
#define  TITLE_STRING "Stablility"

int sys = 0;
float param = 0.1f;
void keyboard(unsigned char key, int x, int y)
{
	if (key==27)
	{
		exit(0);
	}
	if (key=='0')
	{
		sys = 0;
	}
	if (key == '1')
		sys = 1;
	if (key == '2')
		sys = 2;
	glutPostRedisplay();
}

void handleSpecialKeypress(int key, int x, int y)
{
	if (key==GLUT_KEY_DOWN)
	{
		param -= DELTA_P;
	}
	if (key==GLUT_KEY_UP)
	{
		param += DELTA_P;//调节阻尼值
	}
	glutPostRedisplay();
}

void mouseMove(int x, int y) { return; }
void mouseDrag(int x, int y) { return; }

void printInstructions()
{
	printf("Stability visualizer\n");
	printf("Use number keys to select system:\n");
	printf("\t0: linear oscillator:positive stiffness\n");
	printf("\t1: linear oscillator:negative stiffness\n");
	printf("\t2: van der Pol oscillator:nonlinear damping\n");
	printf("up/down arrow keys adjust parameter value\n\n");
	printf("Choose the van der Pol (sys=2)\n");
	printf("Keep up arrow key depressed and watch the show.\n");
}
#endif

main.cpp中只对render()函数进行了改动,标题栏信息和内核启动调用

void render()//创造属于自己的CUDA/OPENGL互操作应用程序时,唯一需要改变的就是render函数
{
	uchar4 *d_out = 0;
	cudaGraphicsMapResources(1, &cuda_pbo_resource, 0);
	cudaGraphicsResourceGetMappedPointer((void**)&d_out, NULL, cuda_pbo_resource);
	kernelLauncher(d_out, W, H, param, sys);
	cudaGraphicsUnmapResources(1, &cuda_pbo_resource, 0);

	char title[64];
	sprintf(title, "Stability:param=%.1f,sys=%d", param, sys);
	glutSetWindowTitle(title);
}

运行结果:

猜你喜欢

转载自blog.csdn.net/JennyBi/article/details/82109958
4.3
今日推荐