HDU 4087 三维上的平移缩放旋转矩阵变化

题目大意:

就是根据它给的程序的要求,不断平移,缩放,旋转三维的点,最后计算出点的位置

这里主要是要列出三种转换方式的齐次矩阵描述

平移
translate tx ty tz
1 0 0 0
0 1 0 0
0 0 1 0
tx ty tz 1
缩放
scale a b c
a  0  0  0
0  b  0  0
0  0  c  0
0  0  0  1
绕任意轴(过原点)旋转(注意要把轴向量归一化,否则点在旋转轴上时有问题)

这里是以(x,y,z)向量指向我们人的方向逆时针旋转 d 的弧度
rotate x y z d
(1-cos(d))*x*x+cos(d)     (1-cos(d))*x*y-sin(d)*z   (1-cos(d))*x*z+sin(d)*y   0
(1-cos(d))*y*x+sin(d)*z   (1-cos(d))*y*y+cos(d)     (1-cos(d))*y*z-sin(d)*x   0
(1-cos(d))*z*x-sin(d)*y   (1-cos(d))*z*y+sin(d)*x   (1-cos(d))*z*z+cos(d)     0
          0                          0                          0              1

然后这里因为循环的问题,所以用矩阵快速幂加速

而循环是可能出现嵌套的

我没用递归,而是判断当前循环属于第几个矩阵下的计算,每次进入一个新的循环都会给当前新的循环设置一个编号,以便找到它的矩阵

每次退出循环,都会将当前矩阵和循环外那个矩阵相乘即可

最后输出+eps,防止 -0.0 , -0.0 , -0.0 的情况发生

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <cmath>
  4 #include <algorithm>
  5 #include <iostream>
  6 using namespace std;
  7 #define N 1005
  8 #define eps 1e-6
  9 const double PI = acos(-1.0);
 10 char s[20];
 11 int rec[N];
 12
 13 struct Matrix{
 14     double m[4][4];
 15     Matrix operator*(const Matrix &t) const {
 16         Matrix ans;
 17         for(int i=0 ; i<4 ; i++){
 18             for(int j=0 ; j<4 ; j++){
 19                 ans.m[i][j] = 0;
 20                 for(int k=0 ; k<4 ; k++){
 21                     ans.m[i][j]+=m[i][k]*t.m[k][j];
 22                 }
 23             }
 24         }
 25         return ans;
 26     }
 27     Matrix(){}
 28     Matrix(double p[][4])
 29     {
 30         for(int i=0 ; i<4 ; i++)
 31             for(int j=0 ; j<4 ; j++)
 32                 m[i][j] = p[i][j];
 33     }
 34     void init(){
 35         memset( m , 0 , sizeof(m));
 36         for(int i=0 ; i<4 ; i++) m[i][i] = 1;
 37     }
 38     void out(){
 39         for(int i=0 ; i<4 ; i++){
 40             for(int j=0 ; j<4 ; j++)
 41                 cout<<m[i][j]<<" ";
 42             cout<<endl;
 43         }
 44     }
 45 }mat[1005] , tmp;
 46
 47 Matrix q_pow(Matrix a , int k)
 48 {
 49     Matrix ret;
 50     ret.init();
 51     while(k)
 52     {
 53         if(k&1) ret = ret*a;
 54         a = a*a;
 55         k>>=1;
 56     }
 57     return ret;
 58 }
 59 //当向量方向指向自己的时候逆时针旋转A的弧度
 60 void Rotate(Matrix &p , double a , double b , double c , double A)
 61 {
 62     double len = sqrt(a*a+b*b+c*c);
 63     double x = a/len , y = b/len , z = c/len;
 64     double sine = sin(A) , cosine = cos(A);
 65     double m[][4] = {
 66         {cosine+(1-cosine)*x*x, x*y*(1-cosine)-z*sine, x*z*(1-cosine)+y*sine, 0},
 67         {y*x*(1-cosine)+z*sine, cosine+y*y*(1-cosine), y*z*(1-cosine)-x*sine, 0},
 68         {z*x*(1-cosine)-y*sine, z*y*(1-cosine)+x*sine, cosine+z*z*(1-cosine), 0},
 69         {0                    , 0                    , 0                    , 1}
 70     };
 71     p = Matrix(m);
 72 }
 73
 74 void Trans(Matrix &p , double a , double b , double c)
 75 {
 76     p.init();
 77     p.m[3][0]=a , p.m[3][1]=b , p.m[3][2]=c;
 78 }
 79
 80 void Scale(Matrix &p , double a , double b , double c)
 81 {
 82     p.init();
 83     p.m[0][0] = a , p.m[1][1] = b , p.m[2][2] = c;
 84 }
 85
 86 int main()
 87 {
 88    // freopen("in.txt" , "r" , stdin);
 89     int n;
 90     double a,b,c,d;
 91
 92     while(scanf("%d" , &n) , n){
 93         mat[0].init();
 94         int cnt = 0;//repeat次数
 95         while(scanf("%s" , s)){
 96             if(s[0]==‘e‘ && cnt==0) break;
 97             if(s[0]==‘e‘){
 98               //  cout<<"id: "<<cnt<<": "<<endl;
 99               //  mat[cnt].out();
100                 mat[cnt] = q_pow(mat[cnt] , rec[cnt]);
101               //  cout<<"id: "<<cnt<<": "<<endl;
102               //  mat[cnt].out();
103                 mat[cnt-1] = mat[cnt-1]*mat[cnt];
104              //   cout<<"id: "<<cnt<<": "<<endl;
105               //  mat[cnt-1].out();
106                 cnt--;
107             }
108             if(s[0]==‘r‘ && s[1]==‘e‘) {
109                 scanf("%d" , &rec[++cnt]);
110                 mat[cnt].init();
111             }
112             else if(s[0]==‘t‘){
113                 scanf("%lf%lf%lf" , &a , &b , &c);
114                 Trans(tmp , a , b , c);
115              //   tmp.out();
116                 mat[cnt] = mat[cnt]*tmp;
117             }
118             else if(s[0]==‘s‘){
119                 scanf("%lf%lf%lf" , &a , &b , &c);
120                 Scale(tmp , a , b , c);
121                 mat[cnt] = mat[cnt]*tmp;
122             }
123             else if(s[0]==‘r‘ && s[1]==‘o‘){
124                 scanf("%lf%lf%lf%lf" , &a , &b , &c , &d);
125                 Rotate(tmp , a , b , c , -d/180*PI);
126                 mat[cnt] = mat[cnt]*tmp;
127             }
128         }
129       //  mat[0].out();
130         for(int i=0 ; i<n ; i++){
131             double x , y , z , xx , yy , zz;
132             scanf("%lf%lf%lf" , &x , &y , &z);
133             xx = x*mat[0].m[0][0]+y*mat[0].m[1][0]+z*mat[0].m[2][0]+mat[0].m[3][0];
134             yy = x*mat[0].m[0][1]+y*mat[0].m[1][1]+z*mat[0].m[2][1]+mat[0].m[3][1];
135             zz = x*mat[0].m[0][2]+y*mat[0].m[1][2]+z*mat[0].m[2][2]+mat[0].m[3][2];
136             printf("%.2f %.2f %.2f\n" , xx+eps , yy+eps , zz+eps);
137         }
138         puts("");
139     }
140     return 0;
141 }
时间: 2024-11-08 22:39:09

HDU 4087 三维上的平移缩放旋转矩阵变化的相关文章

百度地图之添加控件——比例尺、缩略图、平移缩放

地图控件概述 百度地图上负责与地图交互的UI元素称为控件.百度地图API中提供了丰富的控件,您还可以通过Control类来实现自定义控件. 地图API中提供的控件有: Control:控件的抽象基类,所有控件均继承此类的方法.属性.通过此类您可实现自定义控件. NavigationControl:地图平移缩放控件,PC端默认位于地图左上方,它包含控制地图的平移和缩放的功能.移动端提供缩放控件,默认位于地图右下方. OverviewMapControl:缩略地图控件,默认位于地图右下方,是一个可折

Android进度条控制图片旋转&#183;平移&#183;缩放&#183;倾斜

初来乍到 平时代码多写于某笔记软件上 现在在这里记录一些 从初学Android开始写起 可能有些地方实现得略小白 或者还不能熟练使用博客园的功能 但是希望能够对需要的人有帮助 不足之处请多指教 一般使用工具:android studio 那么 Here we go. have a good time. 用进度条实现控制图片旋转·平移·缩放·倾斜 效果: 1 public class MainActivity extends AppCompatActivity implements SeekBar

POJ 3528 hdu 3662 三维凸包模板题

POJ 3528题:http://poj.org/problem?id=3528 HDU 3662:http://acm.hdu.edu.cn/showproblem.php?pid=3662 一个是求三维凸包面数,一个是求三维凸包表面积,都是很裸的. 贴代码: #include<stdio.h> #include<algorithm> #include<string.h> #include<math.h> #include<stdlib.h>

旋转 平移 缩放

------------------------------  旋转 平移 缩放  ---------------------------------- - (void)drawRect:(CGRect)rect { // 获取上下文 CGContextRef ctx = UIGraphicsGetCurrentContext(); //  Current graphics state's Transformation Matrix // 缩放 CGContextScaleCTM(ctx, 0.

hdu 4862 Jump 上下界费用流

对于每个点拆点成为两个点a,b,连接a到b的上界为1,下界为1的边,保证用过一次且仅一次. 然后若点u可到达点v,则连接即可.建成了一个上下界网络,将下界拆出去,求最大费用最大流就好. #include <stdio.h> #include <iostream> #include <string.h> using namespace std; const int N=800; const int MAXE=200000; const int inf=1<<3

WPF/Silverlight中图形的平移,缩放,旋转,倾斜变换演示

原文:WPF/Silverlight中图形的平移,缩放,旋转,倾斜变换演示 为方便描述, 这里仅以正方形来做演示, 其他图形从略. 运行时效果图: XAML代码:// Transform.XAML <Canvas Width="700" Height="700" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"  xmlns:x="http://sc

CSS 实现背景图尺寸不随浏览器缩放而变化

<!-- Author:博客园小dee --> 一些网站的首页背景图尺寸不随浏览器缩放而变化,例如百度个人版的首页,缩放后背景图的尺寸并不改变: 再比如花瓣网( huaban.com ): 现在用CSS来实现这一效果. 首先需要一张足够大尺寸的图片,上图百度背景图的尺寸为1600*1000px( 图片地址:http://4.su.bdimg.com/skin/12.jpg?2 ):花瓣背景图的尺寸为1600*1600px( 图片地址:http://hbfile.b0.upaiyun.com/i

CSS实现背景图尺寸不随浏览器缩放而变化的两种方法

方法一. 把图片作为background 有几个CSS的属性要提一下:background-size:cover,这个CSS3的属性作用是把背景图像扩展至足够大,以使背景图像完全覆盖背景区域,背景图像的某些部分也许无法显示在背景定位区域中,如果不使用这个属性,在IE11和FireFox中缩放浏览器,背景图片会随之缩小,同时使用-webkit-background-size: cover和-o-background-size: cover兼容webkit内核浏览器和Opera浏览器:backgro

HDU 1253 三维数组的图上找最短路

题目大意: 从三维空间的(0,0,0)出发到(a-1,b-1,c-1),每移动一个都要时间加一,计算最短时间 根据六个方向,开个bfs,像spfa那样计算最短路径就行了,但是要1200多ms,也不知道有没有更好的方法 1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #include <queue> 5 using namespace std; 6 int dp[52][52][