三维变换之斜投影、透视投影

编译器:VS2013

原理:依旧是矩阵相乘,只要求得矩阵就可以很方便的求出结果

注意!注意!注意!

楼主数学学得不好,齐次坐标这里没好好听,齐次坐标的第四个坐标值一直为1,楼主懵逼的也按物体坐标等比例放大导致错误调了两天

错误:

1 int a[8][4] = { 0, 0, 0, 200, 200, 0, 0,200, 200, 200, 0,200, 0, 200, 0,200, 0, 0, 200,200, 200, 0, 200,200, 200, 200, 200,200, 0, 200, 200,200};

正确:

1 int a[8][4] = { 0, 0, 0, 1, 200, 0, 0, 1, 200, 200, 0, 1, 0, 200, 0, 1, 0, 0, 200, 1, 200, 0, 200, 1, 200, 200, 200, 1, 0, 200, 200, 1 };

主函数块

 1 #include "stdafx.h"
 2 #include<stdio.h>
 3 #include"graphics.h"
 4 #include<stdlib.h>
 5 #include<math.h>
 6
 7 #define PI 3.14159
 8
 9 //函数声明
10 void apoint(int a[][4]);//一点透视
11 void oblique2_30(int a[][4]);//斜二测45°
12 void oblique2_45(int a[][4]);//斜二测30°
13 void twopoint(int a[][4]);//两点透视
14 void threepoint(int a[][4]);//三点透视
15 void putline(double b[][4]);//画线函数
16
17 int main()
18 {
19     int gdriver = DETECT, gmove;
20     int a[8][4] = { 0, 0, 0, 1, 200, 0, 0, 1, 200, 200, 0, 1, 0, 200, 0, 1, 0, 0, 200, 1, 200, 0, 200, 1, 200, 200, 200, 1, 0, 200, 200, 1 };
21
22     initgraph(&gdriver, &gmove, "");
23     setcolor(YELLOW);
24
25     apoint(a);//一点透视
26     //oblique2_30(a);//斜二测30°
27     //oblique2_45(a);//斜二测45°
28     //twopoint(a);//两点透视
29     //threepoint(a);//三点透视
30
31     system("pause");
32
33     closegraph();
34
35     return 0;
36 }

一点透视:

 1 //一点透视
 2 void apoint(int a[][4])
 3 {
 4     double k = 160, m = 220, n = 400, d = 500,b[8][4];
 5     int i;
 6
 7     for (i = 0; i < 8; i++)
 8     {
 9         b[i][3] = (d + n + a[i][2]) / d*1.0;//其次变换
10         b[i][0] = (a[i][0] + k) / b[i][3]*1.0;//x变换
11         b[i][1] = (a[i][1] + m) / b[i][3]*1.0;//y变换
12         b[i][2] = 0;//z变换
13         b[i][3] = 1;//齐次坐标赋1
14     }
15
16     putline(b);//画线函数

画线函数

 1 void putline(double b[][4])
 2 {
 3     int i;
 4
 5     //小图层
 6     for (i = 0; i < 3; i++)
 7         line(b[i][0], b[i][1], b[i + 1][0], b[i + 1][1]);
 8
 9     //小图层尾连接
10     line(b[3][0], b[3][1], b[0][0], b[0][1]);
11
12     //大图层
13     for (i = 4; i < 7; i++)
14         line(b[i][0], b[i][1], b[i + 1][0], b[i + 1][1]);
15
16     //大图层首尾连接
17     line(b[4][0], b[4][1], b[7][0], b[7][1]);
18
19     //大小图层连接
20     for (i = 0; i < 4; i++)
21         line(b[i][0], b[i][1], b[i + 4][0], b[i + 4][1]);
22 }

二点透视

 1 //两点透视
 2 void twopoint(int a[][4])
 3 {
 4     double p = 0.002, r = 0.002, A = PI / 6.0, k = 150, n = 30, m = 50;
 5     //二维数组c为转换矩阵
 6     double b[8][4] = { 0 };
 7     //转换矩阵
 8     double c[4][4] = { { cos(A), 0, 0, p*cos(A) - r*sin(A) }, { 0, 1, 0, 0 }, { sin(A), 0, 0, p*sin(A) + r*cos(A) }, { k*cos(A) + n*sin(A), m, 0, p*(k*cos(A) + n*sin(A)) + r*(n*cos(A) - k*sin(A)) + 1 } };
 9     int i, j, x;
10
11     //矩阵相乘
12     for (i = 0; i < 8; i++)
13         for (j = 0; j < 4; j++)
14             for (x = 0; x < 4; x++)
15                 b[i][j] += a[i][x] * c[x][j];
16
17     for (i = 0; i < 8; i++)
18         for (j = 0; j < 4; j++)
19         {
20             b[i][j] /= b[i][3];//使齐次坐标变为1
21             b[i][j] = (int)b[i][j];//取整
22         }
23
24     putline(b);//画线函数
25 }

三点透视

 1 //三点透视
 2 void threepoint(int a[][4])
 3 {
 4     double p = 0.0015,q=0.0015, r = 0.0015, A = PI / 6.0,B=PI/45, k = 150, n = 30, m = 30;
 5     //二维数组c为转换矩阵
 6     double b[8][4] = { 0 };
 7     //转换矩阵
 8     double c[4][4] = { { cos(A),sin(A)*sin(B),0,p }, { 0,cos(B),0,q }, { sin(A),-cos(A)*sin(B),0,r }, { k*cos(A)+n*sin(A), m*cos(B)+sin(B)*(k*sin(B)-n*cos(A)),0,k*p+m*q+n*r} };
 9     int i, j, x;
10
11     //矩阵相乘
12     for (i = 0; i < 8; i++)
13         for (j = 0; j < 4; j++)
14             for (x = 0; x < 4; x++)
15                 b[i][j] += a[i][x] * c[x][j];
16
17     for (i = 0; i < 8; i++)
18         for (j = 0; j < 4; j++)
19         {
20             b[i][j] /= b[i][3];//使齐次坐标变为1
21             b[i][j] = (int)b[i][j];//取整
22         }
23
24     putline(b);//画线函数,括号内强制转换成int
25 }

斜二测30°

 1 //斜二测30°
 2 void oblique2_45(int a[][4])
 3 {
 4     double b[8][4];
 5     int i;
 6
 7     for (i = 0; i < 8; i++)
 8     {
 9         b[i][0] = a[i][0] + a[i][2] * cos(PI / 4)*sqrt(5.0) / 5 * 1.0;//x变换
10         b[i][1] = a[i][1] + a[i][2] * sin(PI / 4)*sqrt(5.0) / 5 * 2.0;//y变换
11         b[i][2] = 0;//z变换
12         b[i][3] = 1;//齐次坐标变换
13     }
14
15     putline(b);//画线函数
16 }

斜二测45°

 1 //斜二测45°
 2 void oblique2_30(int a[][4])
 3 {
 4     double b[8][4];
 5     int i;
 6
 7     for (i = 0; i < 8; i++)
 8     {
 9         b[i][0] = a[i][0] + a[i][2] * cos(PI / 6)*sqrt(5.0) / 5 * 1.0;//x变换
10         b[i][1] = a[i][1] + a[i][2] * sin(PI / 6)*sqrt(5.0) / 5 * 2.0;//y变换
11         b[i][2] = 0;//z变换
12         b[i][3] = 1;//齐次坐标变换
13     }
14
15     putline(b);//画线函数
16 }

时间: 2024-10-01 18:38:28

三维变换之斜投影、透视投影的相关文章

CSS3景深、三维变换属性及旋转三维立方体的实现

浏览器坐标系 在讲正式语法之前,首先需要了解浏览器坐标系 这需要我们把浏览器界面想象成一个立体的场景 这是网上流传很广的浏览器坐标系图片 从左到右的方向是浏览器x轴的正方向 从上到下的方向是浏览器y轴的正方向 而z轴正方向是面对于我们的 了解这个很重要,因为下面我们旋转元素需要借助它来理解 3D旋转 我们在平面中使用的旋转只是单纯的让元素在平面旋转一定角度 在三维旋转中稍微要复杂一下 属性当然还是用我们的transform 三维旋转有下面三个函数分别对应三个维度的旋转 rotateX(xxdeg

【Win 10 应用开发】三维变换

所谓三维变换,其实是在二维平面上产生三维的视觉效果.前面老周简单提了一下透视效果,如果透视效果不能满需求,那可以考虑用三维变换. UIElement类有一个属性叫Transform3D,它定义的类型为Transform3D,但,这个类是没有公共的构造函数的,困为它只作为基类.从这个类派生出两个类: PerspectiveTransform3D——这个类的作用是设置观察点的位置,它不能单独使用,单独使用这个类,看不到变换效果.所谓观察点,就好比咱们照相时照相机的观察窗口,照相机放到什么位置,就会看

图解计算机图形学三维变换算法

工程下载 http://pan.baidu.com/s/1o7OEMc6 tcddd.rar 此处为在Windows下运行的TC图形程序:使用了EasyX库: EasyX库可参考: http://blog.csdn.net/bcbobo21cn/article/details/51207782 http://www.easyx.cn 代码参考 http://blog.sina.com.cn/s/articlelist_1287275024_9_1.html 一 三维透视投影变换算法 #inclu

三维变换的一个应用之组合变换

这种组合变换在实际开发当中应用很多,所以知道原理可以举一反三 第一,你要明白矩阵是有结合律的 第二,你要知道旋转矩阵 绕x轴 绕y轴 绕z轴时,这个旋转矩阵是三个形式的矩阵 第三,你要明白为什么我们在旋转一个模型时一定要把它先移回原点,当然了,这个旋转矩阵有关 小应用: 对三角形(中心点(75,93,1))以中心点左旋转90度,要经过一下几步: 1.将三角形的中心移动到原点,也即是相反方向(75,93,1)个单位 2.使用x轴的选装矩阵 3.将中心点移回原来的位置 1  0 -75       

Duanxx的图像处理学习: 图像变换 三维变换及其齐次坐标表示

SharpGL学习笔记(七) OpenGL的变换总结

笔者接触OpenGL最大的困难是: 经常调试一份代码时, 屏幕漆黑一片, 也不知道结果对不对,不知道如何是好! 这其实就是关于OpenGL"变换"的基础概念没有掌握好, 以至于对"将三维体正确的显示在屏幕上指定位置"这样的操作都无法完成. OpenGL变换包括计算机图形学中最基本的三维变换,即几何变换.投影变换.裁剪变换.视口变换,以及针对OpenGL的特殊变换概念理解和用法,如相机模拟.矩阵堆栈等,这些基础是开始真正走进三维世界无法绕过的基础. 所以笔者在前面花了

三维图形概述

原文 三维图形概述 通过 Windows Presentation Foundation (WPF) 中的三维功能,开发人员可以使用标记代码和程序代码对三维图形进行绘制.转换和动画处理. 开发人员可以合并二维和三维图形以创建丰富的控件,提供复杂的数据图解,或者增强用户对应用程序界面的体验.WPF 中的三维支持并非旨在提供功能齐全的游戏开发平台.本主题概述了 WPF 图形系统中的三维功能. 本主题包括下列各节. 二维容器中的三维 三维坐标空间 照相机和投影 模型和网格基元 向模型应用 Materi

转载:透视投影的原理和实现

透视投影的原理和实现 by Goncely 转载:http://blog.csdn.net/wong_judy/article/details/6283019 摘  要 :透视投影是3D渲染的基本概念,也是3D程序设计的基础.掌握透视投影的原理对于深入理解其他3D渲染管线具有重要作用.本文详细介绍了透视投影的原理和算法实现,包括透视投影的标准模型.一般模型和屏幕坐标变换等,并通过VC实现了一个演示程序. 1 概述 在计算机三维图像中,投影可以看作是一种将三维坐标变换为二维坐标的方法,常用到的有正

透视投影的原理和实现

透视投影的原理和实现 摘  要 :透视投影是3D渲染的基本概念,也是3D程序设计的基础.掌握透视投影的原理对于深入理解其他3D渲染管线具有重要作用.本文详细介绍了透视投影的原理和算法实现,包括透视投影的标准模型.一般模型和屏幕坐标变换等,并通过VC实现了一个演示程序. 1 概述 在计算机三维图像中,投影可以看作是一种将三维坐标变换为二维坐标的方法,常用到的有正交投影和透视投影.正交投影多用于三维健模,透视投影则由于和人的视觉系统相似,多用于在二维平面中对三维世界的呈现. 透视投影(Perspec