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 的情况发生
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <iostream>
using namespace std;
#define N 1005
#define eps 1e-6
const double PI = acos(-1.0);
char s[];
int rec[N]; struct Matrix{
double m[][];
Matrix operator*(const Matrix &t) const {
Matrix ans;
for(int i= ; i< ; i++){
for(int j= ; j< ; j++){
ans.m[i][j] = ;
for(int k= ; k< ; k++){
ans.m[i][j]+=m[i][k]*t.m[k][j];
}
}
}
return ans;
}
Matrix(){}
Matrix(double p[][])
{
for(int i= ; i< ; i++)
for(int j= ; j< ; j++)
m[i][j] = p[i][j];
}
void init(){
memset( m , , sizeof(m));
for(int i= ; i< ; i++) m[i][i] = ;
}
void out(){
for(int i= ; i< ; i++){
for(int j= ; j< ; j++)
cout<<m[i][j]<<" ";
cout<<endl;
}
}
}mat[] , tmp; Matrix q_pow(Matrix a , int k)
{
Matrix ret;
ret.init();
while(k)
{
if(k&) ret = ret*a;
a = a*a;
k>>=;
}
return ret;
}
//当向量方向指向自己的时候逆时针旋转A的弧度
void Rotate(Matrix &p , double a , double b , double c , double A)
{
double len = sqrt(a*a+b*b+c*c);
double x = a/len , y = b/len , z = c/len;
double sine = sin(A) , cosine = cos(A);
double m[][] = {
{cosine+(-cosine)*x*x, x*y*(-cosine)-z*sine, x*z*(-cosine)+y*sine, },
{y*x*(-cosine)+z*sine, cosine+y*y*(-cosine), y*z*(-cosine)-x*sine, },
{z*x*(-cosine)-y*sine, z*y*(-cosine)+x*sine, cosine+z*z*(-cosine), },
{ , , , }
};
p = Matrix(m);
} void Trans(Matrix &p , double a , double b , double c)
{
p.init();
p.m[][]=a , p.m[][]=b , p.m[][]=c;
} void Scale(Matrix &p , double a , double b , double c)
{
p.init();
p.m[][] = a , p.m[][] = b , p.m[][] = c;
} int main()
{
// freopen("in.txt" , "r" , stdin);
int n;
double a,b,c,d; while(scanf("%d" , &n) , n){
mat[].init();
int cnt = ;//repeat次数
while(scanf("%s" , s)){
if(s[]=='e' && cnt==) break;
if(s[]=='e'){
// cout<<"id: "<<cnt<<": "<<endl;
// mat[cnt].out();
mat[cnt] = q_pow(mat[cnt] , rec[cnt]);
// cout<<"id: "<<cnt<<": "<<endl;
// mat[cnt].out();
mat[cnt-] = mat[cnt-]*mat[cnt];
// cout<<"id: "<<cnt<<": "<<endl;
// mat[cnt-1].out();
cnt--;
}
if(s[]=='r' && s[]=='e') {
scanf("%d" , &rec[++cnt]);
mat[cnt].init();
}
else if(s[]=='t'){
scanf("%lf%lf%lf" , &a , &b , &c);
Trans(tmp , a , b , c);
// tmp.out();
mat[cnt] = mat[cnt]*tmp;
}
else if(s[]=='s'){
scanf("%lf%lf%lf" , &a , &b , &c);
Scale(tmp , a , b , c);
mat[cnt] = mat[cnt]*tmp;
}
else if(s[]=='r' && s[]=='o'){
scanf("%lf%lf%lf%lf" , &a , &b , &c , &d);
Rotate(tmp , a , b , c , -d/*PI);
mat[cnt] = mat[cnt]*tmp;
}
}
// mat[0].out();
for(int i= ; i<n ; i++){
double x , y , z , xx , yy , zz;
scanf("%lf%lf%lf" , &x , &y , &z);
xx = x*mat[].m[][]+y*mat[].m[][]+z*mat[].m[][]+mat[].m[][];
yy = x*mat[].m[][]+y*mat[].m[][]+z*mat[].m[][]+mat[].m[][];
zz = x*mat[].m[][]+y*mat[].m[][]+z*mat[].m[][]+mat[].m[][];
printf("%.2f %.2f %.2f\n" , xx+eps , yy+eps , zz+eps);
}
puts("");
}
return ;
}
HDU 4087 三维上的平移缩放旋转矩阵变化的更多相关文章
- 【OpenGL(SharpGL)】支持任意相机可平移缩放的轨迹球实现
[OpenGL(SharpGL)]支持任意相机可平移缩放的轨迹球 (本文PDF版在这里.) 在3D程序中,轨迹球(ArcBall)可以让你只用鼠标来控制模型(旋转),便于观察.在这里(http://w ...
- WPF中的平移缩放和矩阵变换(TranslateTransform、ScaleTransform、MatrixTransform)
在WPF中的平移缩放都是通过RenderTransform这个类来实现这些效果的,在这个类中,除了平移和缩放还有旋转.扭曲变换.矩阵变换.这些都差不多的,都是坐标的变换. 这里我就先简单弄个平移和缩放 ...
- 一步一步手写GIS开源项目-(2)地图平移缩放实现
系列文章目录 一步一步手写GIS开源项目-(1)500行代码实现基础GIS展示功能 一步一步手写GIS开源项目-(2)地图平移缩放实现 项目github地址:https://github.com/Hu ...
- WPF/Silverlight中图形的平移,缩放,旋转,倾斜变换演示
原文:WPF/Silverlight中图形的平移,缩放,旋转,倾斜变换演示 为方便描述, 这里仅以正方形来做演示, 其他图形从略. 运行时效果图:XAML代码:// Transform.XAML< ...
- CSS 实现背景图尺寸不随浏览器缩放而变化
<!-- Author:博客园小dee --> 一些网站的首页背景图尺寸不随浏览器缩放而变化,例如百度个人版的首页,缩放后背景图的尺寸并不改变: 再比如花瓣网( http://www.hu ...
- CSS实现背景图尺寸不随浏览器缩放而变化
方法一. 把图片作为background,方法二使用img标签.同时要有一张足够大尺寸的图片. 方法一. 把图片作为background 有几个CSS的属性要提一下:background-size:c ...
- HDU 1253 三维数组的图上找最短路
题目大意: 从三维空间的(0,0,0)出发到(a-1,b-1,c-1),每移动一个都要时间加一,计算最短时间 根据六个方向,开个bfs,像spfa那样计算最短路径就行了,但是要1200多ms,也不知道 ...
- Graphics平移缩放旋转(转载)+点睛
点睛:可以进行多次旋转和平移,也就是平移以后再平移,旋转以后再旋转,有时候一次达不到要求,如果你想一次调整完美的话很麻烦,所以最好多次,上代码 private void btnTranslate_Cl ...
- C#图片上传服务器缩放存储功能
项目需求上需要用户上传头像.本来是用第三方的插件的.但是很多都是收费的. 不过,我需要花这钱么?是不?所以网络上搜集了些资料.. 果然.这个世界 大神是很多很多的. 用了个免费插件. <scri ...
随机推荐
- 怎么进入BAT的研发部门?
怎么进入BAT的研发部门? ======================================剑指offer+leetcode+geeksforgeeks+编程之美+算法导论====秒杀BA ...
- Microsoft VS 2008 过期解决方法
开始>控制面板>添加或删除程序 里找到VS2008,点“更改/删除”,出现: 然后,打开“显示Visual Studio试用版序列号输入框小程序”的软件(单击链接可以转到下载地址),显示: ...
- 转!!MAC和PHY的区别
一块以太网网卡包括OSI(开方系统互联)模型的两个层,物理层和数据链路层.物理层定义了数据传送与接收所需要的电与光信号.线路状态.时钟基准.数据编码和电路等,并向数据链路层设备提供标准接口.数据链路层 ...
- eclipse插件在线发布发布和版本更新(web site) 转
欢迎关注我的社交账号: 博客园地址: http://www.cnblogs.com/jiangxinnju/p/4781259.html GitHub地址: https://github.com/ji ...
- linux笔记:linux常用命令-网络命令
网络命令:ping(测试网络连通性) 网络命令:ifconfig(查看和设置网卡信息) 注意:在查看网卡信息时,直接输入ifconfig命令即可. 网络命令:last(列出目前和过去登入系统的用户信息 ...
- css选择符有哪些?哪些属性可以继承?优先级算法如何计算?内联和important哪个优先
通配选择符* { sRules } 类型选择符E { sRules } td { font-size:14px; width:120px; } 属性选择符 E [ attr ] { sRule ...
- selenium+python笔记5
#!/usr/bin/env python # -*- coding: utf-8 -*- """ @desc: 登陆126邮箱 """ f ...
- 在VBA中调用工作表函数
虽然VBA几乎可以完成所有工作表函数的功能,但是有时候在无法打开思路的时候,适当调用一些工作表函数也未尝不可,在VBA中调用工作表函数需要用到 WorksheetFunction对象,例如: Work ...
- [转载]JMeter源码导入Eclipse
转载自:http://www.cnblogs.com/taoSir/p/5144274.html 由于JMeter纯Java开发,界面也是基于Swing或AWT搞出来的,所以想更深层次的去了解这款工具 ...
- 意外的节点类型 Element。只能在简单内容或空内容上调用 ReadElementString 方法
问题出现的情景: 在调用携程团购接口时,需要把获取的xml字符串反序列化实体对象,出现了这个错误. 详情: 在对xml文档有这样一条语句“ <Description Category=" ...