ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

计算机图形学(六):1. Triangle类,以及Ray Triangle的求交,画出一个红红的三角形来

2021-05-20 21:05:57  阅读:226  来源: 互联网

标签:求交 tri Triangle double 图形学 viewPlane new 三角形 Point3D


接下来我们开始着手画一个三角形(and 大家不要预设心理障碍,其实挺简单的),首先我们了解图形学和三角形相关的基础知识,重点知识贴图如下:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
其次我们定义Triangle类(三角形类),首先明晰三角形由三个点Point3D p0, p1, p2,以及法线向量normal构成。三个点给出后,法线normal可以利用公式得到。最后编写代码测试上述类定义是否正确:
Triangle类(三角形类)代码:

class Trianglecs
    {
        Point3D p0, p1, p2;
        Vector3D normal;

        internal Point3D P0 { get => p0; set => p0 = value; }
        internal Point3D P1 { get => p1; set => p1 = value; }
        internal Point3D P2 { get => p2; set => p2 = value; }
        internal Vector3D Normal { get => normal; set => normal = value; }
        //构造类一
        public Trianglecs()
        {
            p0 = new Point3D(0, 0, 0);
            p1 = new Point3D(0,0,1);
            p2 = new Point3D(1,0,0);
            normal = new Vector3D(0,1,0);
        }
        //构造类一
        public Trianglecs(Point3D a,Point3D b,Point3D c)
        {
            p0 = a;
            p1 = b;
            p2 = c;
            normal = (p1 - p0) ^ (p2 - p0);
            normal.Normlize();
        }

    }

然后调试看代码是否正确
然后在Ray类中编写bool ray.hit(Triangle tri)方法。该方法返回一条光线是否与三角形相交。
三角形的击中方法代码如下:

//编写bool ray.hit(Triangle tri)方法。该方法返回一条光线是否与三角形相交。
        public bool Hit(Trianglecs tri)
        {
            //根据pdf提供的数学公式计算
            double a = tri.P0.X - tri.P1.X;
            double b = tri.P0.X - tri.P2.X;
            double c = _direction.I;
            double d = tri.P0.X - _origin.X;
            double e = tri.P0.Y - tri.P1.Y;
            double f = tri.P0.Y - tri.P2.Y;
            double g = _direction.J;
            double h = tri.P0.Y - _origin.Y;
            double i = tri.P0.Z - tri.P1.Z;
            double j = tri.P0.Z - tri.P2.Z;
            double k = _direction.K;
            double L = tri.P0.Z - _origin.Z;


            double m = f * k - g * j;
            double n = h * k - g * L;
            double p = f * L - h * j;
            double q = g * i - e * k;
            double s = e * j - f * i;


            double inv_denom = 1.0 / (a * m + b * q + c * s);

            double el = d * m - b * n - c * p;
            double beta = el * inv_denom;

            if(beta <0.0)//根据pdf提供的三个不等式条件判断
            {
                return false;
            }
            double r = e * L - h * i;
            double e2 = a * n + d * q + c * r;
            double gamma = e2 * inv_denom;

            if(gamma <0.0)//根据pdf提供的三个不等式条件判断
            {
                return false;
            }
            if(beta +gamma>1.0)//根据pdf提供的三个不等式条件判断
            {
                return false;
            }
            double e3 = a * p - b * r + d * s;
            double t = e3 * inv_denom;
            if (t < kEpisilon)
            {
                return false;
            }
            double tim = t;//得到不知名参数t值
            Point3D hitpoint = _origin + t * _direction;//得到光线与三角形的击中点
            return true;

        }

最后以之前的代码为基础,实际的在场景中放置一个三角形,并类似渲染一个球一样,将该三角形渲染出来。其中三角形为红色,背景为灰色,或者渲染成自己喜欢的颜色。
渲染代码如下:

Point3D eye = new Point3D(0, 0, 0);//起始点
            ViewPlane viewPlane = new ViewPlane();//实例化
            viewPlane.Position = new Point3D(-2, 1, -1);//网格的左上角位置
            viewPlane.ResW = 800;
            viewPlane.ResH = 600;
            viewPlane.W = 4;
            viewPlane.H = 2;
            Sphere sphere = new Sphere(new Point3D(0,0,-2),0.5);//实例化一个球
            Ray primaryRay ;
            Trianglecs trianglecs = new Trianglecs(new Point3D(0,1,-3),new Point3D(-1,0,-3),new Point3D(1,0,-3));//实例化一个三角形
            
            for (int i=0;i<viewPlane.ResW;i++)
            {
                /*
               int R =random();
                int G = random();
                int B = random();
                Color color = Color.FromArgb(R, G, B);
                */
                for (int j = 0; j < viewPlane.ResH; j++)
                {

                    Point3D viewpoint = new Point3D(viewPlane.Position.X + i * (viewPlane.W / viewPlane.ResW), viewPlane.Position.Y - j * (viewPlane.H / viewPlane.ResH), viewPlane.Position.Z);//计算viewplane的每一个网格点
                    Vector3D primaryVector = viewpoint - eye;//计算初始向量
                    primaryRay = new Ray(eye, primaryVector);//计算初始光线
                    /*
                     *
                     //击中球渲染
                    if (primaryRay.Hit(sphere))
                    {
                        bitmap.SetPixel(i, j, Color.Red);
                    }
                    else
                    {
                        bitmap.SetPixel(i,j,Color.Gray);
                    }
                   // bitmap.SetPixel(j, i, color);//设置颜色
                    */
                    //击中三角形渲染
                    if(primaryRay.Hit(trianglecs))//如果击中则显示为红色
                    {
                        bitmap.SetPixel(i, j, Color.Red);
                    }
                    else//否则显示为灰色
                    {
                        bitmap.SetPixel(i, j, Color.Gray);
                    }
                }
            }
            picBox.BackgroundImage = bitmap;//显示图片

结果如下:
在这里插入图片描述

标签:求交,tri,Triangle,double,图形学,viewPlane,new,三角形,Point3D
来源: https://blog.csdn.net/qq_43625888/article/details/117091502

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有