Nyoj 298 点的变换[利用矩阵求解坐标点的转换,平移,绕原点旋转,沿x,y轴翻转]

2024-06-07 03:38

本文主要是介绍Nyoj 298 点的变换[利用矩阵求解坐标点的转换,平移,绕原点旋转,沿x,y轴翻转],希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

题目链接:acm.nyist.net/JudgeOnline/problem.php?pid=298

题目的意思就是给你一n个点(n<=10000),求m次操作后(m<=1000000),各点变为什么了?操作有:平移,绕原点旋转,沿x,y轴翻转。

思路,利用矩阵相乘来解决。。这个很有意思。。

先来补充一下矩阵相乘的知识。。。。

First, 我们必须需要知道的是,矩阵相乘满足结合律,但是, 不满足交换律。。

接下来补充Matrix67大神总结的:

这里的操作是对所有点同时进行的。其中翻转是以坐标轴为对称轴进行翻转(两种情况),旋转则以原点为中心。如果对每个点分别进行模拟,那么m个操作总共耗时O(mn)。利用矩阵乘法可以在O(m)的时间里把所有操作合并为一个矩阵,然后每个点与该矩阵相乘即可直接得出最终该点的位置,总共耗时O(m+n)。假设初始时某个点的坐标为x和y,下面5个矩阵可以分别对其进行平移、旋转、翻转和旋转操作。预先把所有m个操作所对应的矩阵全部乘起来,再乘以(x,y,1),即可一步得出最终点的位置。
    

刚开始,没有理解他的精髓。。

以为每次每个操作都需要把每个点都变换,这样复杂度就是n*3*3*m了。。。O(mn)的复杂度。。。时间复杂度简直报表啊。。表示,理解错误了。。。。

我们根据结合律可以知道,m次操作是可以先结合的。。。最后求点的坐标。。3*3*3*m + n的复杂度。。时间复杂度O(m + n)的,可以接受的。。。

Code:

#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>using namespace std;const int N = 4;
const int M = 1e4 + 5;
const double PI = acos(-1);struct POINT
{double x, y;
} p[M];struct Matrix
{int n, m;double a[N][N];Matrix(){memset(a, 0, sizeof(a));}Matrix (int x, int  y){n = x;m = y;memset(a, 0, sizeof(a));}
} ans;Matrix operator * (Matrix a, Matrix b)
{Matrix tans;tans.n = a.n;tans.m = b.m;for(int i = 1 ; i <= a.n; i ++){for(int j = 1; j <= b.m; j ++){for(int k = 1; k <= b.n; k ++)tans.a[i][j] += a.a[i][k] * b.a[k][j];}}return tans;
}Matrix Rotation(double r)// rotation, turn left ? turn right?
{Matrix op;op.n = 3;op.m = 3;op.a[1][1] = cos(r);op.a[1][2] = sin(r);op.a[2][1] = -sin(r);op.a[2][2] = cos(r);op.a[3][3] = 1;//trun by the base of (0, 0);return ans * op;
}Matrix go(double px, double py)
{Matrix op;op.n = 3;op.m = 3;op.a[1][1] = 1.0;op.a[2][2] = 1.0;op.a[3][3] = 1.0;op.a[3][1] = px;op.a[3][2] = py;return ans * op;
}Matrix bigger(double p)
{Matrix op;op.n = 3;op.m = 3;op.a[1][1] = p;op.a[2][2] = p;op.a[3][3] = 1;return ans * op;
}Matrix fx()
{Matrix op;op.n = 3;op.m = 3;op.a[1][1] = 1.0;op.a[2][2] = -1.0;op.a[3][3] = 1.0;return ans * op;
}Matrix fy()
{Matrix op;op.n = 3;op.m = 3;op.a[1][1] = -1.0;op.a[2][2] = 1.0;op.a[3][3] = 1.0;return ans * op;
}int main()
{
//    freopen("1.txt", "r", stdin);int n, m;scanf("%d %d", &n, &m);for(int i = 1; i <= n; i ++){scanf("%lf %lf", &p[i].x, &p[i].y);}getchar();ans.n= 3;ans.m = 3;for(int i = 1; i <= 3; i ++) ans.a[i][i] = 1.0;char order;for(int i = 1; i <= m; i ++){scanf("%c", &order);if(order == 'X') ans = fx();if(order == 'Y') ans = fy();if(order == 'M'){double  tmpx, tmpy;cin >> tmpx >> tmpy;ans = go(tmpx, tmpy);}if(order == 'S'){double tmps;cin >> tmps;ans = bigger(tmps);}if(order == 'R'){double tmpr;cin >> tmpr;ans = Rotation(tmpr / 180.0 * PI);}getchar();}for(int i = 1; i <= n; i ++){printf("%.1lf %.1lf\n", p[i].x * ans.a[1][1] + p[i].y * ans.a[2][1] + ans.a[3][1], p[i].x * ans.a[1][2] + p[i].y * ans.a[2][2] + ans.a[3][2]);}return 0;
}

代码虽然有点长,但是,直观性还是很好的。。


这篇关于Nyoj 298 点的变换[利用矩阵求解坐标点的转换,平移,绕原点旋转,沿x,y轴翻转]的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1038065

相关文章

java Long 与long之间的转换流程

《javaLong与long之间的转换流程》Long类提供了一些方法,用于在long和其他数据类型(如String)之间进行转换,本文将详细介绍如何在Java中实现Long和long之间的转换,感... 目录概述流程步骤1:将long转换为Long对象步骤2:将Longhttp://www.cppcns.c

在Java中将XLS转换为XLSX的实现方案

《在Java中将XLS转换为XLSX的实现方案》在本文中,我们将探讨传统ExcelXLS格式与现代XLSX格式的结构差异,并为Java开发者提供转换方案,通过了解底层原理、性能优势及实用工具,您将掌握... 目录为什么升级XLS到XLSX值得投入?实际转换过程解析推荐技术方案对比Apache POI实现编程

C/C++中OpenCV 矩阵运算的实现

《C/C++中OpenCV矩阵运算的实现》本文主要介绍了C/C++中OpenCV矩阵运算的实现,包括基本算术运算(标量与矩阵)、矩阵乘法、转置、逆矩阵、行列式、迹、范数等操作,感兴趣的可以了解一下... 目录矩阵的创建与初始化创建矩阵访问矩阵元素基本的算术运算 ➕➖✖️➗矩阵与标量运算矩阵与矩阵运算 (逐元

Python使用FFmpeg实现高效音频格式转换工具

《Python使用FFmpeg实现高效音频格式转换工具》在数字音频处理领域,音频格式转换是一项基础但至关重要的功能,本文主要为大家介绍了Python如何使用FFmpeg实现强大功能的图形化音频转换工具... 目录概述功能详解软件效果展示主界面布局转换过程截图完成提示开发步骤详解1. 环境准备2. 项目功能结

使用Python实现网页表格转换为markdown

《使用Python实现网页表格转换为markdown》在日常工作中,我们经常需要从网页上复制表格数据,并将其转换成Markdown格式,本文将使用Python编写一个网页表格转Markdown工具,需... 在日常工作中,我们经常需要从网页上复制表格数据,并将其转换成Markdown格式,以便在文档、邮件或

Python将字符串转换为小写字母的几种常用方法

《Python将字符串转换为小写字母的几种常用方法》:本文主要介绍Python中将字符串大写字母转小写的四种方法:lower()方法简洁高效,手动ASCII转换灵活可控,str.translate... 目录一、使用内置方法 lower()(最简单)二、手动遍历 + ASCII 码转换三、使用 str.tr

Java如何将文件内容转换为MD5哈希值

《Java如何将文件内容转换为MD5哈希值》:本文主要介绍Java如何将文件内容转换为MD5哈希值的实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Java文件内容转换为MD5哈希值一个完整的Java示例代码代码解释注意事项总结Java文件内容转换为MD5

使用Java将实体类转换为JSON并输出到控制台的完整过程

《使用Java将实体类转换为JSON并输出到控制台的完整过程》在软件开发的过程中,Java是一种广泛使用的编程语言,而在众多应用中,数据的传输和存储经常需要使用JSON格式,用Java将实体类转换为J... 在软件开发的过程中,Java是一种广泛使用的编程语言,而在众多应用中,数据的传输和存储经常需要使用j

Java实现视频格式转换的完整指南

《Java实现视频格式转换的完整指南》在Java中实现视频格式的转换,通常需要借助第三方工具或库,因为视频的编解码操作复杂且性能需求较高,以下是实现视频格式转换的常用方法和步骤,需要的朋友可以参考下... 目录核心思路方法一:通过调用 FFmpeg 命令步骤示例代码说明优点方法二:使用 Jaffree(FF

使用animation.css库快速实现CSS3旋转动画效果

《使用animation.css库快速实现CSS3旋转动画效果》随着Web技术的不断发展,动画效果已经成为了网页设计中不可或缺的一部分,本文将深入探讨animation.css的工作原理,如何使用以及... 目录1. css3动画技术简介2. animation.css库介绍2.1 animation.cs