首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 其他教程 > 其他相关 >

二维的射线追踪

2013-03-06 
二维的射线跟踪想要做一个光线跟踪引擎,感觉太困难了,虽然原理不太复杂,但是还是很难搞所以先搞一个二维的

二维的射线跟踪

想要做一个光线跟踪引擎,感觉太困难了,虽然原理不太复杂,但是还是很难搞所以先搞一个二维的试试

这个是图形学那本书上的一个课后作业,就是试试反射怎么反射,做出来效果是这样的,从左下角出发的射线

经过几次反射的路径

二维的射线追踪

代码:(main)

 

/*Author:     lishicaoDate:       2013.2.19*/#include <iostream>#include <fstream>#include <windows.h>#include <gl/gl.h>#include <gl/glu.h>#include <gl/glut.h>#include "Common.h"using namespace std ;ofstream fout ( "ans.txt" ) ;void  setWindow( double , double , double , double ) ;void  setViewport( int , int , int , int ) ;void  myDisplay() ;void  myInit() ;void  input() ;Line  ray ;int  main( int argc , char ** argv ){    input() ;    glutInit( & argc , argv ) ;    glutInitDisplayMode( GLUT_SINGLE | GLUT_RGB ) ;    glutInitWindowSize( 640 , 640 ) ;    glutCreateWindow( "RayTracer2D" ) ;    glutDisplayFunc( myDisplay ) ;    myInit() ;    setWindow( -5.0 , 15.0 , -5.0 , 15.0 ) ;    setViewport( 0 , 640 , 0 , 640 ) ;    glutMainLoop() ;    return 0 ;}void  input(){    Point  P[4] ;    Line  lin[4] ;    ObjectNumber = 0 ;    memset( Count , 0 , sizeof( Count ) ) ;    memset( line  , 0 , sizeof( line  ) ) ;    memset( Count , 0 , sizeof( Count ) ) ;    cout << "Input the Rectangle( two point ) " << endl ;    cin >> P[0].x >> P[0].y ;    cin >> P[3].x >> P[3].y ;    P[1].x = P[0].x ; P[1].y = P[3].y ;    P[2].x = P[3].x ; P[2].y = P[0].y ;    lin[0].start = P[0] ; lin[0].end = P[1] ;    lin[1].start = P[1] ; lin[1].end = P[3] ;    lin[2].start = P[3] ; lin[2].end = P[2] ;    lin[3].start = P[2] ; lin[3].end = P[0] ;    for( int i = 0 ; i <= 3 ; i ++ ){        lin[i].flag = 2 ;        line[ObjectNumber][i] = lin[i] ;    }    ObjectNumber ++ ;    Count[0] = 3 ;    char ch , str ;    while( 1 )    {        cout << "any other object? Y|N" << endl ;        cin >> ch ;        if( ch == 'N' ) break ;        while( 1 )        {            cout << "input Segment? Y|N" << endl ;            cin >> str ;            Line LINE ;            if( str == 'N' ) break ;            cout << "input two point " << endl ;            cin >> LINE.start.x >> LINE.start.y >> LINE.end.x >> LINE.end.y ;            LINE.flag = 2 ;            line[ObjectNumber][Count[ObjectNumber]] = LINE ;            Count[ObjectNumber] ++ ;        }        ObjectNumber ++ ;    }    cout << "input ray" << endl ;    cin >> ray.start.x >> ray.start.y >> ray.end.x >> ray.end.y ;    ray.flag = 1 ;}void  setWindow( double left , double right , double buttom , double top ){    glMatrixMode( GL_PROJECTION ) ;    glLoadIdentity() ;    gluOrtho2D( left , right , buttom , top ) ;}void  setViewport( int left , int right , int buttom , int top ){    glViewport( left , buttom , right - top , top - buttom ) ;}void  myInit(){    glClearColor( 1.0 , 1.0 , 1.0 , 0.0 ) ;    glColor3f( 0.0 , 0.0 , 1.0 ) ;    glLineWidth( 2.0 ) ;}void  myDisplay(){    glClear( GL_COLOR_BUFFER_BIT ) ;    glMatrixMode( GL_MODELVIEW ) ;    glLoadIdentity() ;    for( int i = 0 ; i <= ObjectNumber ; i ++ )        for( int j = 0 ; j <= Count[i] ; j ++ )        {            glBegin( GL_LINES ) ;                glVertex2f( line[i][j].start.x , line[i][j].start.y ) ;                glVertex2f( line[i][j].end.x   , line[i][j].end.y   ) ;            glEnd() ;            glFlush() ;        }    int cnt = 0 ;    Point P     ;    Line * temp ;    Line tmp , next  ;    while( cnt <= 10 )    {        P.x = 0 ; P.y = 0 ;        temp = RayFirstCollision( ray , P ) ;        tmp = *temp ;        next = reflection( ray , tmp ) ;        for( double i = 0 ; i <= 1 ; i += 0.001 )        {            Point cur ;            cur.x = ray.start.x + i * ( P.x - ray.start.x ) ;            cur.y = ray.start.y + i * ( P.y - ray.start.y ) ;            glBegin( GL_POINTS ) ;                glVertex2f( cur.x , cur.y ) ;            glEnd() ;            glFlush() ;        }        ray = next ;        cnt ++ ;    }}


common.h:

#include <gl/gl.h>#include <gl/glu.h>#include <gl/glut.h>#include <cmath>#include <iostream>using namespace std ;const double INF = 999999999 ;class Point{    public :        double x , y ;        int    flag  ;     //0是向量,1是点} ;class Line{    public :        Point  start , end ;        double K , B ;        int   flag ;  // 0 是直线  1是射线  2是线段        void  calc()        {            if( end.x - start.x < 0.00001 && end.x - start.x > -0.00001 ) {                K = INF ;                B = INF ;            }            else {                K = ( end.y - start.y ) / ( end.x - start.x ) ;                B = start.y - K * start.x ;            }        }} ;Line line[100][100] ;int  ObjectNumber ;int  Count[100]   ;Point  segIntersect( Line L1 , Line L2 ){    Point P ;    L1.calc() ; L2.calc() ;    if( L1.K == L2.K ) {        P.x = 0 ; P.y = 0 ; P.flag = INF ;        return P ;    }    if( L1.K == INF ) {        P.x = L1.start.x ;        P.y = L2.K * L1.start.x + L2.B ;    }    else if( L2.K == INF ) {        P.x = L2.start.x ;        P.y = L1.K * L2.start.x + L1.B ;    }    else {        P.x = ( L2.B - L1.B ) / ( L1.K - L2.K ) ;        P.y = L1.K * P.x + L1.B ;    }    return P ;}bool   Intersect( Line L1 , Line L2 , Point &P ){    P = segIntersect( L1 , L2 ) ;    if( P.x == 0 && P.y == 0 && P.flag == INF ) return false ;    if( ( P.x - L1.start.x ) * ( P.x - L1.end.x ) <= 0 ) {        if( ( P.x - L2.start.x ) * ( P.x - L2.end.x ) <= 0 ) return true ;        else {            if( L2.flag == 2 ) return false ;            else if( L2.flag == 1 ) {                if( ( L2.start.x - P.x ) * ( L2.start.x - L2.end.x ) < 0 ) return false ;                else return true ;            }            else if( L2.flag == 0 ) return true ;        }    }    else {        if( L1.flag == 2 || ( L1.flag == 1 && ( L1.start.x - P.x ) * ( L1.start.x - L1.end.x ) <= 0 ) )            return false ;        else {            if( ( P.x - L2.start.x ) * ( P.x - L2.end.x ) <= 0 ) return true ;            else if( ( L2.flag == 1 && ( L2.start.x - P.x ) * ( L2.start.x - L2.end.x ) >= 0 ) || L2.flag == 0 )                return true ;            else return false ;        }    }    return false ;}Line * RayFirstCollision( Line  ray , Point & P ){    double Length = INF ;    Line * nearest ;    Point  point ;    int i , j ;    for( i = 0 ; i <= ObjectNumber ; i ++ )        for( j = 0 ; j <= Count[i] ; j ++ )            if( Intersect( ray , line[i][j] , point ) )            {                if( fabs( point.x - ray.start.x ) < 0.00001 && fabs( point.y - ray.start.y ) < 0.00001 ) continue ;                if( fabs( ray.start.x - point.x ) < Length )                {                    Length = fabs( ray.start.x - point.x ) ;                    P = point ;                    nearest = &line[i][j] ;                }            }    return nearest ;}Line reflection( Line ray , Line seg ){    Line nextRay , par , temp ;    Point point , P , end , inter ;    Point vector , vector_N ;    Intersect( ray , seg , point ) ;    vector.x = seg.end.x - seg.start.x ;    vector.y = seg.end.y - seg.start.y ;    if( vector.y != 0 ) {        vector_N.x = 1 ;        vector_N.y = ( - vector_N.x * vector.x ) / vector.y ;    }    else {        vector_N.x = 0 ;        vector_N.y = 1 ;    }    end.x = ray.start.x + vector.x ;    end.y = ray.start.y + vector.y ;    par.start = ray.start ;    par.end   = end       ;    par.flag  = 0 ;    temp.start = point ;    end.x = point.x + vector_N.x ;    end.y = point.y + vector_N.y ;    temp.end  = end ;    temp.flag = 0 ;    Intersect( par , temp , inter ) ;    P.x = ( inter.x - ray.start.x ) * 2 + ray.start.x ;    P.y = ( inter.y - ray.start.y ) * 2 + ray.start.y ;    nextRay.start = point ;    nextRay.end   = P     ;    nextRay.flag = 1 ;    return nextRay ;}


恩,写得太搓了==

热点排行