【计算机图形学】图形变换(以任意直线为对称轴的对称变换)

news2024/11/27 18:37:31

模块3-2 图形变换

一 实验目的

  1. 编写图形各种变换的算法

二 实验内容

1:任意直线的对称变换。要求将变换矩阵写在实验报告中,并与代码匹配。求对任意直线Ax+By+C=0的对称变换矩阵。

实验结果如下图所示:


1:预设图形初始化


2:鼠标左键点击直线起点


3:鼠标右键点击直线终点


4:继续添加对称情况

求对任意直线Ax+By+C=0的对称变换矩阵:

对于任意直线Ax + By + C = 0,对称变换矩阵为M = (1-2A^2/(A^2+B^2), -2AB/(A^2+B^2), -2AC/(A^2+B^2); -2AB/(A^2+B^2), 1-2B^2/(A^2+B^2), -2BC/(A^2+B^2); 0, 0, 1),其中A和B不同时为0。

1-2A^2/(A^2+B^2)

-2AB/(A^2+B^2)

-2AC/(A^2+B^2)

-2AB/(A^2+B^2)

1-2B^2/(A^2+B^2)

-2BC/(A^2+B^2)

0

0

1

三 程序说明

最终的实验代码如下表所示:

1

//

// 程序名称:任意直线对称变换

// 功    能:实现图形以任意直线为基准的对称变换

// 编译环境:VS2019,EasyX_20220116

// 最后修改:2022-4-7

#include <graphics.h>

#include <conio.h>

#include <iostream>

#include <math.h>

using namespace std;

double points[4][2] = { {150,150},{150,300},{300,300},{300,150} };

const double newpoints[4][2] = { {150,150},{150,300},{300,300},{300,150} };

int num = 4, dimension = 3;

#define PI 3.1415927

//旋转变换

void rotate(double degree);

//平移变换

void trans(double tx, double ty);

//矩阵乘法

void mutiply(double a[5][5], int ar, int ac, double b[5][5], int br, int bc);

//画图函数

void paint();

//任意对称变换

void anysymmetry(int x1, int y1, int x2, int y2);

//坐标轴对称变换

void symmetry(int flag);

void anysymmetry(int x1, int y1, int x2, int y2) {

    double k = 0, b = 0;

    if (x1 == x2) {

         trans(-x1, 0);

         symmetry(1);

         trans(x1, 0);

    }

    else if (y1 == y2) {

         trans(0, -y1);

         symmetry(0);

         trans(0, y1);

    }

    else {

         k = 1.0 * (y1 - y2) / (x1 - x2);

         b = y1 - k * x1;

         trans(0, -b);

         rotate(-atan(k) * 180 * 1.0 / PI);

         symmetry(0);

         rotate(atan(k) * 180 * 1.0 / PI);

         trans(0, b);

    }

}

void symmetry(int flag) {

    int i;

    if (flag == 0) {

         for (i = 0; i < num; i++) {

             points[i][1] = -points[i][1];

         }

    }

    else if (flag == 1) {

         for (i = 0; i < num; i++) {

             points[i][0] = -points[i][0];

         }

    }

    else {

         return;

    }

}

void paint() {

    for (int i = 0; i < num; i++) {

         if (i == num - 1) {

             line(int(points[i][0]), int(points[i][1]), int(points[0][0]), int(points[0][1]));

             break;

         }

         line(int(points[i][0]), int(points[i][1]), int(points[i + 1][0]), int(points[i + 1][1]));

    }

}

void rotate(double degree) {

    double sita = 1.0 * degree / 180 * PI;

    double R[5][5] = { {cos(sita),-sin(sita),0},{sin(sita),cos(sita),0},{0,0,1.0} };

    double point[5][5];

    int i;

    for (i = 0; i < num; i++) {

         point[0][0] = 1.0 * points[i][0];

         point[1][0] = 1.0 * points[i][1];

         point[2][0] = 1;

         mutiply(R, dimension, dimension, point, dimension, 1);

         points[i][0] = point[0][0];

         points[i][1] = point[1][0];

    }

}

void trans(double tx, double ty) {

    double T[5][5] = { {1,0,tx},{0,1,ty},{0,0,1} };

    double point[5][5];

    int i;

    for (i = 0; i < num; i++) {

         point[0][0] = 1.0 * points[i][0];

         point[1][0] = 1.0 * points[i][1];

         point[2][0] = 1;

         mutiply(T, dimension, dimension, point, dimension, 1);

         points[i][0] = point[0][0];

         points[i][1] = point[1][0];

    }

}

void mutiply(double a[5][5], int ar, int ac, double b[5][5], int br, int bc) {

    int i, j, k;

    double c[5][5];

    for (i = 0; i < ar; i++) {

         for (j = 0; j < bc; j++) {

             c[i][j] = 0;

         }

    }

    for (i = 0; i < ar; i++) {

         for (j = 0; j < bc; j++) {

             for (k = 0; k < ac; k++) {

                  c[i][j] += 1.0 * a[i][k] * b[k][j];

             }

         }

    }

    for (i = 0; i < ar; i++) {

         for (j = 0; j < bc; j++) {

             b[i][j] = c[i][j];

         }

    }

}

int main() {

    initgraph(1000, 800);

    ExMessage m;

    //绘画初始矩形

    setcolor(WHITE);

    rectangle(points[0][0], points[0][1], points[2][0], points[2][1]);

    int x0, y0, x1, y1;

    while (1) {

         m = getmessage(EX_MOUSE | EX_KEY);

         switch (m.message) {

             case WM_LBUTTONDOWN:

                  x0 = m.x;

                  y0 = m.y;

                  //画直线起点

                  setlinecolor(WHITE);

                  setfillcolor(GREEN);

                  fillrectangle(m.x - 3, m.y - 3, m.x + 3, m.y + 3);

                  break;

             case WM_RBUTTONDOWN:

                  x1 = m.x;

                  y1 = m.y;

                  //画直线终点

                  setlinecolor(WHITE);

                  setfillcolor(GREEN);

                  fillrectangle(m.x - 3, m.y - 3, m.x + 3, m.y + 3);

                  //处理直线

                  line(x0, y0, x1, y1);

                  anysymmetry(x0, y0, x1, y1);

                  paint();

                  for (int i = 0; i < 4; i++) {

                      points[0][0] = newpoints[0][0];

                      points[0][1] = newpoints[0][1];

                      points[1][0] = newpoints[1][0];

                      points[1][1] = newpoints[1][1];

                      points[2][0] = newpoints[2][0];

                      points[2][1] = newpoints[2][1];

                      points[3][0] = newpoints[3][0];

                      points[3][1] = newpoints[3][1];

                  }

                  break;

             case WM_KEYDOWN:

                  if (m.vkcode == VK_ESCAPE) {

                      return 0;

                  }

        }

    }

    _getch();

    closegraph();

    return 0;

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/474802.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

数据结构与算法(小议递归二)

文章目录 前言一、例二二、为什么总结 前言 前面说到了递归在裴波那契数列计算中并不怎么适用&#xff0c;那么它适合什么样的场景呢&#xff1f; 我们继续举例和python3对比测试来说明。 一、例二 下面我们试试阶乘&#xff0c;在前面的代码上稍稍改一下就可以了&#xff1a…

ApachePOI操作Excel快速入门使用

简介 Apache POI 是一个处理Miscrosoft Office各种文件格式的开源项目&#xff0c;主要任务是创建和维护Java API&#xff0c;以基于Office Open XML标准&#xff08;OOXML&#xff09;和Microsoft的OLE 2复合文档格式&#xff08;OLE2&#xff09;处理各种文件格式&#xff0…

【Java笔试强训 3】

&#x1f389;&#x1f389;&#x1f389;点进来你就是我的人了博主主页&#xff1a;&#x1f648;&#x1f648;&#x1f648;戳一戳,欢迎大佬指点! 欢迎志同道合的朋友一起加油喔&#x1f93a;&#x1f93a;&#x1f93a; 目录 一、选择题 二、编程题 &#x1f525;最长的…

能用OpenCV做的15大计算机视觉任务

使用OpenCV&#xff0c;你几乎可以完成你能想到的每种计算机视觉任务。现实生活中的问题要求同时使用许多计算机视觉算法和模块来获得所需的结果。因此&#xff0c;你只需了解要用哪些OpenCV模块和函数来获得你想要的东西。 让我们来看看OpenCV中可以开箱即用的功能。 1 内置…

跨平台Office文档预览原生插件,非腾讯X5,支持离线,稳定高可用

引言 2023年4月13日零时起&#xff0c;腾讯浏览服务内核文档能力正式下线&#xff0c;要实现真正离线文档预览&#xff0c;于是有了这边文章。 前面写了多篇关于<跨平台文件在线预览解决方案>&#xff0c;不管使用pdf.js、LibreOffice&#xff0c;还是永中DCS&#xff…

JAVA设计模式之观察者模式( 通俗易懂的代码讲解 )

简述&#xff1a;Java的观察者模式是一种设计模式&#xff0c;它定义了一种对象间的一对多的依赖关系&#xff0c;使得当一个对象的状态发生改变时&#xff0c;所有依赖于它的对象都能够得到收到消息通知。在这种模式中&#xff0c;被观察者维护了一个观察者列表&#xff0c;并…

深入浅出 Compose Compiler(1) Kotlin Compiler KCP

前言 Compose 的语法简洁、代码效率非常高&#xff0c;这主要得益于 Compose Compiler 的一系列编译期魔法&#xff0c;帮开发者生成了很多样板代码。但编译期插桩也阻碍了我们对于 Compose 运行原理的认知&#xff0c;想要真正读懂 Compose 就必须先了解它的 Compiler。本系列…

前端系列11集-ES6 知识总结

ES Module 优点 静态分析 浏览器和 Node 都支持 浏览器的新 API 能用模块格式提供 不再需要对象作为命名空间 export 用于规定模块的对外接口 输出的接口与其对应的值是动态绑定关系可以取到模块内部实时的值 import 用于输入其他模块提供的功能 具有提升效果&#xff0c;会提升…

刷题4.28

1、 开闭原则软件实体&#xff08;模块&#xff0c;类&#xff0c;方法等&#xff09;应该对扩展开放&#xff0c;对修改关闭&#xff0c;即在设计一个软件系统模块&#xff08;类&#xff0c;方法&#xff09;的时候&#xff0c;应该可以在不修改原有的模块&#xff08;修改关…

服务注册与发现-Consul(Linux)

本文要有docker支持&#xff0c;docker的安装使用Docker 在Linux-CentOS上的安装使用_XiaoGuaiSs的博客-CSDN博客如果提示 [Warning] IPv4 forwarding is disabled. Networking will not work.然后将项目拷贝至linux 的project目录下&#xff08;随意&#xff09;。生成项目镜像…

Node第三方包 【Request】

文章目录 &#x1f31f;前言&#x1f31f;Request&#x1f31f;安装与使用&#x1f31f;流&#xff08;stream&#xff09;操作&#x1f31f;Form表单&#x1f31f;application/x-www-form-urlencoded (URL编码的Form)&#x1f31f;multipart/form-data (Multipart Form 上传) …

百度地图采集经纬度坐标数据定位的javascript实战开发(地理坐标拾取系统、地址定位点选插件、实时定位、数据导入、地理编码、位置纠偏)

坐标采集 前言1.百度地图地理坐标拾取系统2.位置选择插件百度地图经纬度选择插件默认参数配置 3.数据导入4.地理编码爬取百度webAPI返回参数前端封装转换函数 5.手机GPS定位GPS定位 6.位置纠偏html容器经纬度纠偏 前言 在百度地图的标注开发中&#xff0c;最为关键的操作就是经…

华硕主板来电开机自启

重启电脑&#xff0c;开机按del或者F2进入bios 按F10保存确认即可

浏览器跨站点通信(两个IP不同网站通信)

需求场景&#xff1a;OA系统会通过接口调用的方式将ERP系统的待办信息获取并显示在OA系统中。登录OA系统后&#xff0c;在OA系统中点击ERP系统的待办&#xff0c;会自动打开ERP系统业务处理页面&#xff0c;当ERP系统对应业务处理完毕&#xff0c;需要在OA系统中刷新待办记录&a…

【环境配置】解决No module named ‘librosa‘

执行以下命令下载 pip install librosa我这里遇到了报错&#xff1a; Microsoft Visual C 14.0 or greater is required. Get it with “Microsoft C Build Tools”: https://visualstudio.microsoft.com/visual-cpp-build-tools/ 相关解决方案请参考&#xff1a; 【环境配置…

Python渗透测试编程基础——线程、进程与协程

目录 一、进程与线程的概念 1.进程 2.线程 3.进程和线程的关系 4.任务执行方式 二、Python中的Threading模块 1.线程模块介绍 2.Threading介绍 &#xff08;1&#xff09;方法和属性 &#xff08;2&#xff09;类方法 三、线程简单编写 1.流程 2.创建线程 &#x…

云原生技术在云计算中的应用探讨

第一章&#xff1a;云原生技术的概念与发展 云原生技术是一种针对云计算环境设计的应用程序开发和部署方法&#xff0c;主要目标是提高应用程序的可伸缩性、可移植性、高可用性和自动化管理等方面的特性。这种技术是近年来在云计算领域兴起的一个新的开发模式&#xff0c;它主要…

大模型“涌现”的思维链,究竟是一种什么能力?

听说最近AI大厂的开发人员和高校的NLP研究人员&#xff0c;都在琢磨&#xff0c;怎么让大模型“涌现”。那画面莫名就让我想到了程序员给服务器上香来保佑不宕机&#xff0c;都有种求诸于天的玄学。 所谓“涌现”,在大模型领域指的是当模型突破某个规模时&#xff0c;性能显著提…

商城管理系统的数据表从属关系+navicat建表操作+数据库文件转储并入代码操作

1&#xff0c;商城管理系统的数据表从属关系 在商城管理系统中&#xff0c;我们会面临属性分组的问题&#xff0c;商品表与分类表需要建立链接&#xff1b; 在控制类中我们将分类表中属性类传过来&#xff0c;与商品值params建立链接 public R list(RequestParam Map<Strin…

基于matlab使用波束成形对点对点 MIMO-OFDM 系统进行建模

一、前言 此示例展示了如何使用波束成形对点对点 MIMO-OFDM 系统进行建模。最近的无线标准&#xff08;如 802.11x 系列&#xff09;采用了多输入多输出 &#xff08;MIMO&#xff09; 和正交频分复用 &#xff08;OFDM&#xff09; 技术的组合&#xff0c;以提供更高的数据速率…