(1)已知2D下,新坐标系的原点、X轴方向向量、Y轴方向向量在原始坐标系下的表示,求原始坐标系中直线ax+by+c=0,在新坐标系下的直线方程;

(2)求直线与2D包围盒的交点,可能有0、1或2个交点;

using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
//using System.Windows.Forms;namespace DTSAlgorithm
{class CoordinateTransform{// 定义一个方法来计算变换矩阵public static double[,] CalculateTransformationMatrix(double Ox, double Oy, double ux, double uy, double vx, double vy){// 创建一个3x3的变换矩阵double[,] transformationMatrix = new double[3, 3];// 设置矩阵的元素transformationMatrix[0, 0] = ux; // 新坐标系x轴方向向量的x分量transformationMatrix[0, 1] = uy; // 新坐标系y轴方向向量的x分量transformationMatrix[0, 2] = -ux * Ox - uy * Oy; // 新坐标系原点的x坐标transformationMatrix[1, 0] = vx; // 新坐标系x轴方向向量的y分量transformationMatrix[1, 1] = vy; // 新坐标系y轴方向向量的y分量transformationMatrix[1, 2] = -vx * Ox - vy * Oy; // 新坐标系原点的y坐标transformationMatrix[2, 0] = 0;  // 齐次坐标部分transformationMatrix[2, 1] = 0;transformationMatrix[2, 2] = 1;return transformationMatrix;}// 打印矩阵的方法public static void PrintMatrix(double[,] matrix){for (int i = 0; i < matrix.GetLength(0); i++){for (int j = 0; j < matrix.GetLength(1); j++){Console.Write(matrix[i, j] + "\t");}Console.WriteLine();}}}public struct BoundingBox{public double XMin { get; }public double XMax { get; }public double YMin { get; }public double YMax { get; }public BoundingBox(double xmin, double xmax, double ymin, double ymax){XMin = xmin;XMax = xmax;YMin = ymin;YMax = ymax;}public override string ToString() =>$"X:[{XMin}, {XMax}], Y:[{YMin}, {YMax}]";}public class BoundingBoxCalculator{public static BoundingBox GetTransformedBoundingBox(List<PointF> originalPoints,double[,] transformMatrix){if (originalPoints == null || originalPoints.Count == 0)throw new ArgumentException("点集不能为空");if (transformMatrix.GetLength(0) != 3 || transformMatrix.GetLength(1) != 3)throw new ArgumentException("变换矩阵必须是3x3矩阵");double xmin = double.MaxValue, xmax = double.MinValue;double ymin = double.MaxValue, ymax = double.MinValue;foreach (var point in originalPoints){// 应用变换矩阵 (齐次坐标变换)double x = transformMatrix[0, 0] * point.X +transformMatrix[0, 1] * point.Y +transformMatrix[0, 2];double y = transformMatrix[1, 0] * point.X +transformMatrix[1, 1] * point.Y +transformMatrix[1, 2];// 透视除法(如果是仿射变换,则w=1)double w = transformMatrix[2, 0] * point.X +transformMatrix[2, 1] * point.Y +transformMatrix[2, 2];if (Math.Abs(w) > 1e-6) // 避免除以零{x /= w;y /= w;}// 更新边界xmin = Math.Min(xmin, x);xmax = Math.Max(xmax, x);ymin = Math.Min(ymin, y);ymax = Math.Max(ymax, y);}return new BoundingBox(xmin, xmax, ymin, ymax);}}public class LineTransformer{/// <summary>/// 计算变换后的直线方程系数/// </summary>/// <param name="a">原始直线方程ax+by+c=0的a系数</param>/// <param name="b">原始直线方程ax+by+c=0的b系数</param>/// <param name="c">原始直线方程ax+by+c=0的c系数</param>/// <param name="transformMatrix">3x3齐次变换矩阵(仿射变换)</param>/// <returns>新坐标系下的直线系数(a', b', c')</returns>public static (double a, double b, double c) TransformLineEquation(double a, double b, double c,double[,] transformMatrix){// 验证矩阵尺寸if (transformMatrix.GetLength(0) != 3 || transformMatrix.GetLength(1) != 3)throw new ArgumentException("变换矩阵必须是3x3矩阵");// 计算变换矩阵的逆矩阵(用于直线变换)if (!InvertMatrix(transformMatrix, out double[,] invMatrix))throw new ArgumentException("变换矩阵不可逆");// 直线变换公式:新系数 = 原始系数 * 逆变换矩阵double a_new = a * invMatrix[0, 0] + b * invMatrix[1, 0];double b_new = a * invMatrix[0, 1] + b * invMatrix[1, 1];double c_new = a * invMatrix[0, 2] + b * invMatrix[1, 2] + c;return (a_new, b_new, c_new);}/// <summary>/// 3x3矩阵求逆(简化版,适用于仿射变换)/// </summary>private static bool InvertMatrix(double[,] matrix, out double[,] inverse){inverse = new double[3, 3];double det = matrix[0, 0] * (matrix[1, 1] * matrix[2, 2] - matrix[1, 2] * matrix[2, 1]) -matrix[0, 1] * (matrix[1, 0] * matrix[2, 2] - matrix[1, 2] * matrix[2, 0]) +matrix[0, 2] * (matrix[1, 0] * matrix[2, 1] - matrix[1, 1] * matrix[2, 0]);if (Math.Abs(det) < 1e-6f) return false;double invDet = 1.0f / det;inverse[0, 0] = (matrix[1, 1] * matrix[2, 2] - matrix[1, 2] * matrix[2, 1]) * invDet;inverse[0, 1] = (matrix[0, 2] * matrix[2, 1] - matrix[0, 1] * matrix[2, 2]) * invDet;inverse[0, 2] = (matrix[0, 1] * matrix[1, 2] - matrix[0, 2] * matrix[1, 1]) * invDet;inverse[1, 0] = (matrix[1, 2] * matrix[2, 0] - matrix[1, 0] * matrix[2, 2]) * invDet;inverse[1, 1] = (matrix[0, 0] * matrix[2, 2] - matrix[0, 2] * matrix[2, 0]) * invDet;inverse[1, 2] = (matrix[0, 2] * matrix[1, 0] - matrix[0, 0] * matrix[1, 2]) * invDet;inverse[2, 0] = (matrix[1, 0] * matrix[2, 1] - matrix[1, 1] * matrix[2, 0]) * invDet;inverse[2, 1] = (matrix[0, 1] * matrix[2, 0] - matrix[0, 0] * matrix[2, 1]) * invDet;inverse[2, 2] = (matrix[0, 0] * matrix[1, 1] - matrix[0, 1] * matrix[1, 0]) * invDet;return true;}}public class LineSegmentCalculator{public static Tuple<PointF, PointF> GetLineSegmentInBoundingBox(double a, double b, double c, BoundingBox box){double xmin = box.XMin;double xmax = box.XMax;double ymin = box.YMin;double ymax = box.YMax;List<PointF> intersections = new List<PointF>();// 检查直线是否与矩形的四条边相交// 1. 左边界 (x = xmin)if (b != 0) // 避免垂直于y轴的直线{double y = (-a * xmin - c) / b;if (y >= ymin && y <= ymax)intersections.Add(new PointF(xmin, y));}// 2. 右边界 (x = xmax)if (b != 0){double y = (-a * xmax - c) / b;if (y >= ymin && y <= ymax)intersections.Add(new PointF(xmax, y));}// 3. 下边界 (y = ymin)if (a != 0) // 避免垂直于x轴的直线{double x = (-b * ymin - c) / a;if (x >= xmin && x <= xmax)intersections.Add(new PointF(x, ymin));}// 4. 上边界 (y = ymax)if (a != 0){double x = (-b * ymax - c) / a;if (x >= xmin && x <= xmax)intersections.Add(new PointF(x, ymax));}// 去重并验证交点数量intersections = RemoveDuplicates(intersections);if (intersections.Count == 2){return new Tuple<PointF, PointF>(intersections[0], intersections[1]);}else if (intersections.Count == 1){// 直线与矩形相切(仅一个交点)return new Tuple<PointF, PointF>(intersections[0], intersections[0]);}else{// 无交点(直线完全在矩形外或矩形退化为点)return null;}}private static List<PointF> RemoveDuplicates(List<PointF> points){List<PointF> uniquePoints = new List<PointF>();foreach (var point in points){bool isDuplicate = false;foreach (var uniquePoint in uniquePoints){if (Math.Abs(point.X - uniquePoint.X) < 1e-6 &&Math.Abs(point.Y - uniquePoint.Y) < 1e-6){isDuplicate = true;break;}}if (!isDuplicate)uniquePoints.Add(point);}return uniquePoints;}}internal class Program{[STAThread]private static void Main(){string filePath = "rotate.csv";var points = new List<PointF>();using (var reader = new StreamReader(filePath)){while (!reader.EndOfStream){string line = reader.ReadLine();string[] values = line.Split(';');if (values.Length == 3 &&double.TryParse(values[0], out double x) &&double.TryParse(values[1], out double y) &&double.TryParse(values[2], out double z)){points.Add(new PointF(x, y));}else{Console.WriteLine($"跳过无效行: {line}");}}}double ux = 0.935277;double uy = -0.353918;double vx = 0.353918;double vy = 0.935277;double Ox = -1.274;double Oy = 9.878;double[,] transformationMatrix = CoordinateTransform.CalculateTransformationMatrix(Ox, Oy, ux, uy, vx, vy);BoundingBox box = BoundingBoxCalculator.GetTransformedBoundingBox(points, transformationMatrix);double outerline_A = 0.354;double outerline_B = 0.935;double outerline_C = -8.788;(double a, double b, double c)  = LineTransformer.TransformLineEquation(outerline_A, outerline_B, outerline_C, transformationMatrix);Tuple<PointF, PointF> result = LineSegmentCalculator.GetLineSegmentInBoundingBox(a, b, c, box);}}
}

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

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Pandas-特征工程详解

Pandas-特征工程详解一、特征工程的核心目标二、数据类型与基础转换1. 数值型特征&#xff1a;类型优化与异常处理2. 分类型特征&#xff1a;编码与规范化&#xff08;1&#xff09;标签编码&#xff08;Label Encoding&#xff09;&#xff08;2&#xff09;独热编码&#xff…

pip install torch各种版本的命令及地址

一、遇到的问题&#xff1a;cuda和torch编译时的版本不一致 在安装mmcv时遇到error MMCV_WITH_OPS1 python setup.py develo RuntimeError: The detected CUDA version (11.3) mismatches the version that was used to compile PyTorch (10.2). Please make sure to use th…

【spring boot】三种日志系统对比:ELK、Loki+Grafana、Docker API

文章目录**方案 1&#xff1a;使用 ELK&#xff08;Elasticsearch Logstash Kibana&#xff09;****适用场景****搭建步骤****1. 修改 Spring Boot 日志输出****2. 创建 Docker Compose 文件****3. 配置 Logstash****4. 启动服务****方案 2&#xff1a;使用 Loki Grafana***…

Cesium加载3DTiles模型并且重新设置3DTiles模型的高度

代码&#xff1a; 使用的时候&#xff0c;直接调用 load3DTiles() 方法既可。 // 加载3Dtiles const load3DTiles async () > {let tiles_url "/3DTiles2/Production_1.json";let tileset await Cesium.Cesium3DTileset.fromUrl(tiles_url, {enableCollision: …

Matlab批量转换1km降水数据为tiff格式

1km降水数据处理- 制作数据裁剪掩膜 0 引言1 示例程序2 结语0 引言 本篇介绍用Matlab工具将中国1km分辨率逐月降水量数据集(1901-2024)批量转为tiff格式的过程。下面为具体内容: 1 示例程序 下载得到的nc数据(如pre_2001.nc)包含4个字段,其中降水数据的第1个维度为1-12,…

HandyJSON使用详情

注意事项:Model 需要实现 HandyJSON 协议&#xff0c;对于简单情况&#xff0c;只需声明 class/struct 并添加 HandyJSON 协议即可1.简单 JSON 结构JSON 数据:{"name": "John","age": 30,"isStudent": false }Model 类:struct Person:…

comfyUI-IPApterfaceID人脸特征提取

1.基础节点 以Checkpoint、CLIP、空Latent、K采样器、VAE解码、预览图像为基础节点。 2.人脸特征获取节点 IPAdapter FaceID节点专用于将特定人脸特征&#xff08;通过参考图提取&#xff09;融入生成图像。 参考图像&#xff0c;正面图像是想要参考人物的人像&#xff0c;最…

【React Native】Switch、Alert、Dimensions、StatusBar、Image组件

其他常用组件 swich https://reactnative.dev/docs/next/switch alert Alert React Native 如果想增加里面的按钮&#xff0c;就往这个数组里&#xff0c;按照这个格式不断的加东西就行了。但是&#xff1a; 在iOS上&#xff0c;里面多少个都有问题&#xff0c;3 个以上它…

渗透笔记1-4

一、HTTPS安全机制 1. HTTP的安全风险 窃听风险&#xff1a;明文传输导致通信内容可被直接截获&#xff08;如Wireshark抓包获取密码&#xff09;。篡改风险&#xff1a;中间人可修改传输内容&#xff08;如注入恶意脚本&#xff09;。冒充风险&#xff1a;攻击者伪造服务端身份…

《星盘接口6:星际联盟》

《星盘接口6&#xff1a;星际联盟》⚡ 第一章&#xff1a;新的黎明地球历2097年&#xff0c;陈欣和她的团队成功地将“数据之神”封印在一个独立的数据维度中&#xff0c;暂时解除了对银河系的威胁。然而&#xff0c;这场胜利并没有带来长久的和平。随着人类文明不断扩展至更遥…

【安卓笔记】进程和线程的基础知识

0. 环境&#xff1a; 电脑&#xff1a;Windows10 Android Studio: 2024.3.2 编程语言: Java Gradle version&#xff1a;8.11.1 Compile Sdk Version&#xff1a;35 Java 版本&#xff1a;Java11 1. 先熟悉JVM虚拟机的线程 ----------以下都是系统线程&#xff0c;由JV…

26-计组-多处理器

多处理器的基本概念1. 计算机体系结构分类依据&#xff1a;根据指令流和数据流的数量关系&#xff0c;计算机体系结构可分为四种类型&#xff1a;SISD、SIMD、MISD、MIMD。&#xff08;1&#xff09;SISD 单指令流单数据流定义&#xff1a;任意时刻计算机只能执行单一指令操作单…

vscode 插件开发activityba

在 VS Code 插件开发中&#xff0c;**Activity Bar&#xff08;活动栏&#xff09;**是左侧垂直导航栏的核心组成部分&#xff0c;它为用户提供了快速访问插件功能的入口。通过自定义 Activity Bar&#xff0c;开发者可以显著提升插件的可见性和用户体验。以下是关于 Activity …

【橘子分布式】Thrift RPC(理论篇)

一、简介 首先还是那句话&#xff0c;概念网上已经很多了&#xff0c;我们就不多逼逼了。我来大致介绍一下。 Thrift是一个RPC框架可以进行异构系统(服务的提供者 和 服务的调用者 不同编程语言开发系统)的RPC调用为什么在当前的系统开发中&#xff0c;会存在着异构系统的RPC…

项目进度依赖纸面计划,如何提升计划动态调整能力

项目进度依赖纸面计划会导致实际执行中的调整能力不足。提升计划动态调整能力的方法包括&#xff1a;建立动态进度管理系统、强化团队沟通与协作、定期开展风险评估与进度复盘。特别是建立动态进度管理系统&#xff0c;通过信息技术工具实现实时跟踪和反馈&#xff0c;使计划能…

递推预处理floor(log_2{n})

在C中&#xff0c;除了使用<cmath>中的log或log2函数求对数&#xff0c;也可以通过递推求出所有可能用到的⌊log⁡2i⌋,i∈[1,n]\lfloor \log_2i\rfloor, i\in[1, n]⌊log2​i⌋,i∈[1,n] 证明&#xff1a;⌊log⁡2i⌋⌊log⁡2⌊i2⌋⌋1\lfloor \log_2i \rfloor\lfloor \…

【AI智能体】智能音视频-搭建可视化智能体

可视化智能体是语音小伴侣智能体的升级版&#xff0c;支持语音与视频的双模态交互。本文详细介绍了音视频交互的实现原理、智能体搭建方法及效果测试&#xff0c;帮助开发者快速构建支持音视频交互的智能体。 应用场景 可视化智能体适用于多种场景&#xff0c;举例如下&#…

Sensoglove推出新一代外骨骼力反馈手套:主动力反馈+亚毫米级手指追踪,助力机器人操控与虚拟仿真

在工业自动化、虚拟现实和医疗康复等领域&#xff0c;高精度手部交互设备的需求日益增长。Sensoglove推出的Rembrandt外骨骼力反馈手套&#xff0c;结合主动力反馈、触觉反馈与亚毫米级追踪技术&#xff0c;为用户提供更自然、更安全的操作体验。Sensoglove外骨骼力反馈手套核心…

AutoMapper入门

在 ASP.NET Core 开发中&#xff0c;我们经常需要在不同层之间传递数据&#xff1a;比如从数据库模型&#xff08;Entity&#xff09;转换到 DTO&#xff0c;再从 DTO 转换为前端视图模型。这些转换代码大量重复、冗长、容易出错。为了解决这个问题&#xff0c;AutoMapper 诞生…

PyTorch武侠演义 第一卷:初入江湖 第1章:武林新秀遇Tensor - 张量基础

第一卷&#xff1a;初入江湖 第1章&#xff1a;武林新秀遇Tensor - 张量基础晨起码农村 鸡鸣三声&#xff0c;林小码已经收拾好了行囊。他最后看了眼床头那本翻旧的《Python入门心法》&#xff0c;轻轻抚平卷起的书角。 "小码&#xff0c;路上小心。"父亲将一把青铜匕…