[問題] OpenGL畫Wave equation問題
開發平台(Platform): (Ex: VC++, GCC, Linux, ...)
DEV C++ (devcpp-4.9.9.2_setup)
額外使用到的函數庫(Library Used): (Ex: OpenGL, ...)
OpenGL (glut.3.7+.DevPak)
問題(Question):
使用熱傳方程式範例來修改成wave equation ,
編譯後所鍵入方程式會畫出兩個對稱波形
希望能夠修正成僅只一個波形
餵入的資料(Input):
這是用exp函數和差分法寫出的波動方程
for(j=0; j<Ngrid; j++){
x = j*dx;
T4[j] = T1[j]= y = exp((-(x-b)*(x-b))/d);
}
for(j=0; j<Ngrid; j++){
x = j*dx;
T5[j] = T2[j]= y = exp((-(x-c)*(x-c))/d);
T3[j]=a*((T2[j+1]-2*T2[j]+T2[j-1])/dx*dx)*dt*dt+2*T2[j]-T1[j];
預期的正確結果(Expected Output):
一個用OpenGL繪出波的圖形左去又回
如 wiki百科上wave equation右邊的紅色圖
http://en.wikipedia.org/wiki/Wave_equation
錯誤結果(Wrong Output):
兩個波從中間對稱展開 ...
程式碼(Code):(請善用置底文網頁, 記得排版)
程式碼連結
http://ideone.com/fv35R
http://codepad.org/vbo4R9SH
#include <stdio.h>
#include <GL/glut.h>
#include <stdlib.h>
#include <math.h>
#define GL_PI 3.1415926f
const int Ngrid=301;
const double dt=0.5,a=2.0,b=50.0,c=51.0,d=10.0;
double t,T1[Ngrid],T2[Ngrid],T3[Ngrid],T4[Ngrid],T5[Ngrid];
double L=100.0,x,y;
double dx=L/(1.0*(Ngrid-1));
int i,j;
void RenderScene(void) //繪圖函數
{
GLfloat x,y,z,angle;
glClear(GL_COLOR_BUFFER_BIT); //清空視窗
glColor3f(1.0f, 0.0f, 0.0f); //設定物件(在此為矩形)顏色(R,G,B)
glBegin(GL_LINE_STRIP); //指定一連串連續線段
for(j=0; j<Ngrid; j++){
x = j*dx;
y = T4[j];
glVertex2f(x, y);
}
glEnd();
glBegin(GL_LINE_STRIP); //指定一連串連續線段
for(j=0; j<Ngrid; j++){
x = j*dx;
y = T5[j];
glVertex2f(x, y);
}
glEnd();
for(j=1;j<Ngrid-1;j++){
T3[j]=a*((T2[j+1]-2*T2[j]+T2[j-1])/dx*dx)*dt*dt+2*T2[j]-T1[j]; //公式
}
T3[0]=0.0;
T3[Ngrid]=0.0;
glColor3f(0.0f, 0.0f, 1.0f);
glBegin(GL_LINE_STRIP); //指定一連串連續線段
for(j=0; j<Ngrid; j++){
x = j*dx;
y = T3[j];
glVertex3f(x, y, 0);
}
glEnd();
for(j=0;j<Ngrid;j++){
T1[j]=T2[j];
T2[j]=T3[j];
}
glutSwapBuffers();
}
void TimerFunction(int value){
t += dt;
glutPostRedisplay(); //通知GLUT更新目前的視窗
glutTimerFunc(1,TimerFunction, 1);//重新呼叫 glutTimerFunc產生迴圈的作用
}
void SetupRC(void) //設定視窗
{
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);//設定視窗顏色(R,G,B,1=完全不透明)
}
void ChangeSize(GLsizei w, GLsizei h)// 當視窗改變大小時呼叫此函數
{
if(h == 0) h = 1; // 避免h=0,aspectRatio-->無限大
GLfloat aspectRatio; // 設定視窗長寬比
aspectRatio = (GLfloat)w / (GLfloat)h;
glViewport(0, 0, w, h); // 將Clipping volume對應到整個視窗
glMatrixMode(GL_PROJECTION); //用來定義 clipping volume
glLoadIdentity(); //將 project 矩陣設為單位矩陣
// 設定或修改 clipping volume 範圍 (left, right, bottom, top, near, far)
if (w <= h)
glOrtho (-10.0, 105.0, -10.0 / aspectRatio, 10.0 / aspectRatio, 1.0,
-1.0);
else
glOrtho (-10.0 * aspectRatio, 105.0 * aspectRatio, -10.0, 10.0, 1.0,
-1.0);
glMatrixMode(GL_MODELVIEW);//指定目前的操作矩陣是 modelview矩陣
glLoadIdentity(); //將 modelview矩陣設為單位矩陣
}
int main()
{
for(j=0; j<Ngrid; j++){
x = j*dx;
T4[j] = T1[j]= y = exp((-(x-b)*(x-b))/d);
}
for(j=0; j<Ngrid; j++){
x = j*dx;
T5[j] = T2[j]= y = exp((-(x-c)*(x-c))/d);
}
T4[0]=T1[0]=0.0;
T5[0]=T2[0]=0.0;
T4[Ngrid]=T1[Ngrid]=0.0;
T5[Ngrid]=T2[Ngrid]=0.0;
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);//建立視窗時要使用的模式;單一
緩衝區,RGB色彩模式
glutInitWindowSize(600,600);
glutCreateWindow("GLRect"); //建立視窗將標題設為 GLRect
glutReshapeFunc(ChangeSize); //呼叫 ChangeSize function
glutDisplayFunc(RenderScene); //顯示 RenderScene這個繪圖函數
// ;繪圖函數會在視窗第一次顯
示,或改變視窗大小時重新呼叫
glutTimerFunc(1,TimerFunction, 1);
SetupRC(); //執行繪圖前初始化
glutMainLoop();
return 0;
}
http://ideone.com/fv35R
http://codepad.org/vbo4R9SH
(原始碼連結)
補充說明(Supplement):
懇請熟悉OpenGL的大大們協助解答 <(_ _)> 感激不盡!!
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 125.228.151.53
※ 編輯: Ferrarin 來自: 125.226.228.113 (06/26 22:24)
→
06/26 22:30, , 1F
06/26 22:30, 1F
→
06/26 22:30, , 2F
06/26 22:30, 2F
→
06/26 22:34, , 3F
06/26 22:34, 3F
※ 編輯: Ferrarin 來自: 125.228.151.53 (06/26 22:41)
→
06/26 22:52, , 4F
06/26 22:52, 4F
→
06/27 10:09, , 5F
06/27 10:09, 5F
C_and_CPP 近期熱門文章
PTT數位生活區 即時熱門文章