[ntustgraphics99] [電腦圖學]嗨,大家好,有鑑於大家保證,一定,硬要,需要一個討論平台

  • From: 天亮damody <t1238142000@xxxxxxxxx>
  • To: ntustgraphics99@xxxxxxxxxxxxx
  • Date: Mon, 15 Nov 2010 16:29:52 +0800

2010/11/15 天亮damody <t1238142000@xxxxxxxxx>

> 各位同學大家好:
>        助教我"黃亮軒"申請了一個maillist來跟大家討論,
> 所謂的maillist就是你寄給ntustgraphics99@xxxxxxxxxxxxx的信,助教能看到,大家也能看到,
> 我回的信大家也都能收到,這樣就比較不會有重複的問題一直問,別人問助教得到的結果,其它人不知道等問題,
> 希望大家多多利用這個資源多多討論^^
> 最後給大家一點參考如何切點跟看正面
> Frustum.h是給大家一點參考
> 決定視野內的點最好還是用投影片上的ccw比較準。
>
> 下面是簡單用視野去切點,但沒有寫怎麼找到要畫的邊切好的兩點。
> void Maze::
> Draw_View(const float focal_dist)
> //======================================================================
> {
>     using namespace std;
>     frame_num++;
>     LineSeg line(view_cell->edges[0]);
>     cout << line.start[0] << " " << line.start[1] << " " << line.end[0] <<
> " " << line.end[1] << endl;
>     point clip1, clip2;
>     Frustum viewf(viewer_dir, viewer_fov, viewer_posn[X], viewer_posn[Y]);
>     clip1 = line.Cross_Param_point(viewf.edgelines[0]); //clip1 左邊切到的點
>     float bill = viewf.edgelines[0].Cross_Param(line);
>     float bill2 = viewf.edgelines[1].Cross_Param(line);
>     clip2 = line.Cross_Param_point(viewf.edgelines[1]); //clip2 右邊切到的點
>     if (bill>0 && bill<1 || bill2>0 && bill2<1)
>         cout << clip1.x << " " << clip1.y << " " << clip2.x << " " <<
> clip2.y  << endl;
>     else
>         cout << "error : " << bill << " " << bill2 << endl;
> }
>
>
> --
> 有心情就是有壓力^^
>



-- 
有心情就是有壓力^^
#pragma once
#include "LineSeg.h"
#include <cmath>
static double   rad(double num) { return num / 180.0 * 3.14159; };
static double   deg(double num) { return num * 180.0 / 3.14159; };
static float   rad(float num) { return (float)(num / 180.0 * 3.14159); };
static float   deg(float num) { return (float)(num * 180.0 / 3.14159); };
class Frustum {
public:
        LineSeg edgelines[2];
        Frustum(float viewangle, float fov, float pos_x, float pos_y)
        {
                edgelines[0] = LineSeg(pos_x, pos_y, pos_x + 1*cos( 
rad(viewangle - fov/2) ), pos_y + 1*sin( rad(viewangle - fov/2) ));
                edgelines[0].end[0] += 
(edgelines[0].end[0]-edgelines[0].start[0])*100;
                edgelines[0].end[1] += 
(edgelines[0].end[1]-edgelines[0].start[1])*100;
                edgelines[1] = LineSeg(pos_x, pos_y, pos_x + 1*cos( 
rad(viewangle + fov/2) ), pos_y + 1*sin( rad(viewangle + fov/2) ));
                edgelines[1].end[0] += 
(edgelines[1].end[0]-edgelines[1].start[0])*100;
                edgelines[1].end[1] += 
(edgelines[1].end[1]-edgelines[1].start[1])*100;
        }
        Frustum(float start_x, float start_y, float right_end_x, float 
right_end_y, float left_end_x, float left_end_y)
        {
                edgelines[0] = LineSeg( 
start_x,start_y,right_end_x,right_end_y);
                edgelines[0].end[0] += 
(edgelines[0].end[0]-edgelines[0].start[0])*100;
                edgelines[0].end[1] += 
(edgelines[0].end[1]-edgelines[0].start[1])*100;
                edgelines[1] = LineSeg( start_x,start_y,left_end_x,left_end_y);
                edgelines[1].end[0] += 
(edgelines[1].end[0]-edgelines[1].start[0])*100;
                edgelines[1].end[1] += 
(edgelines[1].end[1]-edgelines[1].start[1])*100;
        }
};
/************************************************************************
     File:        LineSeg.cpp

     Author:     
                  Stephen Chenney, schenney@xxxxxxxxxxx
     Modifier
                  Yu-Chi Lai, yu-chi@xxxxxxxxxxx

     Comment:    
                                                (c) 2001-2002 Stephen Chenney, 
University of Wisconsin at Madison
                                                Class header file for LineSeg 
class.
                

     Platform:    Visio Studio.Net 2003 (converted to 2005)

*************************************************************************/

#include "LineSeg.h"

//**********************************************************************
//
// * Constructor from an edge
//======================================================================
LineSeg::
LineSeg(Edge *e)
//======================================================================
{
        start[0] = e->endpoints[Edge::START]->posn[Vertex::X];
        start[1] = e->endpoints[Edge::START]->posn[Vertex::Y];

        end[0] = e->endpoints[Edge::END]->posn[Vertex::X];
        end[1] = e->endpoints[Edge::END]->posn[Vertex::Y];
}

//**********************************************************************
//
// * Constructor for specifyng start and end point
//======================================================================
LineSeg::
LineSeg(float xs, float ys, float xe, float ye)
//======================================================================
{
        start[0] = xs;
        start[1] = ys;
        end[0] = xe;
        end[1] = ye;
}


//**********************************************************************
//
// * Return the parameter value at which this segment crosses the given
//   segment. This will return parameter values outside the range 0,1
//   THIS FUNCTION IS EXTREMELY USEFUL FOR CLIPPING, but it 
//   DOES NOT tell you whether the edge is "entering" or "leaving".
//   But you can use tests like Edge::Point_Side() to figure that out.
//======================================================================
float LineSeg::
Cross_Param(LineSeg e)
//======================================================================
{
        float   dx1, dy1, dx2, dy2;
        float   denom, s;

        // This computation comes from writing each segment in parametric form,
        // and solving a simulataneous equation to determine the parameter
        // value of the intersection point on this LineSeg.
        dx1 = e.end[0] - e.start[0];
        dy1 = e.end[1] - e.start[1];
        dx2 = end[0] - start[0];
        dy2 = end[1] - start[1];

        if ( ( denom = dx2 * dy1 - dy2 * dx1 ) == 0.0 )
                // Parallel segments.
                return 1.0e20f;

        s = ( e.start[0] - start[0] ) * dy1 - ( e.start[1] - start[1] ) * dx1;

        return s / denom;
}

point LineSeg::
Cross_Param_point(LineSeg e)
//======================================================================
{
        float   dx1, dy1, dx2, dy2;
        float   denom, s;

        // This computation comes from writing each segment in parametric form,
        // and solving a simulataneous equation to determine the parameter
        // value of the intersection point on this LineSeg.
        dx1 = e.end[0] - e.start[0];
        dy1 = e.end[1] - e.start[1];
        dx2 = end[0] - start[0];
        dy2 = end[1] - start[1];

        if ( ( denom = dx2 * dy1 - dy2 * dx1 ) == 0.0 )
                // Parallel segments.
                denom = 0.01;

        s = ( e.start[0] - start[0] ) * dy1 - ( e.start[1] - start[1] ) * dx1;
        float balance = s / denom;
        point res(start[0] + ( end[0] - start[0] ) * balance, start[1] + ( 
end[1] - start[1] ) * balance);
        return res;
}
/************************************************************************
     File:        LineSeg.h

     Author:     
                  Stephen Chenney, schenney@xxxxxxxxxxx
     Modifier
                  Yu-Chi Lai, yu-chi@xxxxxxxxxxx

     Comment:    
                                                (c) 2001-2002 Stephen Chenney, 
University of Wisconsin at Madison
                                                Class header file for LineSeg 
class.
                

     Platform:    Visio Studio.Net 2003 (converted to 2005)

*************************************************************************/

#ifndef _LINESEG_H_
#define _LINESEG_H_

#include "Edge.h"
struct point
{
        point(){}
        point(float _x, float _y):x(_x),y(_y)
        {}
        float x,y;
};
class LineSeg {

        public:
                // First constructor takes the endpoints.
                LineSeg(float xs, float ys, float xe, float ye);

                // Second constructor takes an edge. The LineSeg created has 
the same
                // start and end points as the edge.
                LineSeg(Edge*);

                LineSeg(){}
        public:
                // Return the parameter value at which this segment crosses the 
given
                // segment. This will return parameter values outside the range 
0,1
                // THIS FUNCTION IS EXTREMELY USEFUL FOR CLIPPING, but it 
                // DOES NOT tell you whether the edge is "entering" or 
"leaving".
                // But you can use tests like Edge::Point_Side() to figure that 
out.
                float   Cross_Param(LineSeg);
                point   Cross_Param_point(LineSeg);
        public:
                float   start[2];       // Starting point, x and y.
                float   end[2]; // Ending point, x and y.
};

#endif

Other related posts: