已知点矩阵的三个顶点坐标、行列数和行列的间距,计算得出剩余所有点的坐标

news2025/2/22 12:38:22

已知点矩阵的三个顶点坐标、行列数和行列的间距,计算得出剩余所有点的坐标

  • 计算矩阵中每个点的坐标
    • 代码实现
    • 案例图
    • 调用验证

计算矩阵中每个点的坐标

给定左上角、左下角和右上角三个点的坐标,以及矩阵的行数、列数、行间距和列间距,我们可以计算出所有点的坐标。
在项目中有一个运动装置,只可按照x或y方向移动。目标是在96孔板的96个孔,而这些孔是排列整齐有序的,那么我们就可通过该方案计算出剩余的点,来简化示教人员的工作。

代码实现

public class PlateWellPoint
{
    public double X { get; }
    public double Y { get; }
    public int RowIndex { get; set; }
    public int ColumnIndex { get; set; }

    public PlateWellPoint(double x, double y)
    {
        X = x;
        Y = y;
    }

    public override string ToString()
    {
        return $"R{RowIndex}C{ColumnIndex}({X:F2}, {Y:F2})";
    }
}
public class PlatePointMatrixGenerator
{
    public static List<PlateWellPoint> GeneratePoints(PlateWellPoint topLeft, PlateWellPoint bottomLeft, PlateWellPoint topRight, int rows, int cols, double rowSpacing, double colSpacing)
    {
        // 计算右下角点坐标
        PlateWellPoint bottomRight = CalculateBottomRightPoint(topLeft, bottomLeft, topRight);
        // 验证输入的四个点是否形成矩形
        if (!IsRectangle(topLeft, bottomLeft, topRight, bottomRight))
        {
            Console.WriteLine("警告:输入的三个点无法形成矩形,计算结果可能不准确。");
        }
        // 计算矩阵中所有点的坐标
        List<PlateWellPoint> allPoints = CalculateAllPoints(topLeft, topRight, bottomLeft, rows, cols);
        // 输出所有点的坐标
        Console.WriteLine("\n矩阵中所有点的坐标:");
        int index = 0;
        for (int r = 0; r < rows; r++)
        {
            for (int c = 0; c < cols; c++)
            {
                Console.WriteLine($"点[{r},{c}]: {allPoints[index]}");
                index++;
            }
        }

        // 验证间距
        VerifySpacing(allPoints, rows, cols, rowSpacing, colSpacing);
        return allPoints;
    }
    // 计算右下角的点坐标
    static PlateWellPoint CalculateBottomRightPoint(PlateWellPoint topLeft, PlateWellPoint bottomLeft, PlateWellPoint topRight)
    {
        // 右下角的坐标可以通过向量加法计算
        // 从左上角到右上角的位移 + 从左上角到左下角的位移 = 从左上角到右下角的位移
        double bottomRightX = topLeft.X + (topRight.X - topLeft.X) + (bottomLeft.X - topLeft.X);
        double bottomRightY = topLeft.Y + (topRight.Y - topLeft.Y) + (bottomLeft.Y - topLeft.Y);

        return new PlateWellPoint(bottomRightX, bottomRightY);
    }
    // 检查四个点是否构成矩形
    static bool IsRectangle(PlateWellPoint topLeft, PlateWellPoint bottomLeft, PlateWellPoint topRight, PlateWellPoint bottomRight)
    {
        // 计算对角线长度是否相等
        double diagonal1 = Math.Sqrt(Math.Pow(topLeft.X - bottomRight.X, 2) + Math.Pow(topLeft.Y - bottomRight.Y, 2));
        double diagonal2 = Math.Sqrt(Math.Pow(topRight.X - bottomLeft.X, 2) + Math.Pow(topRight.Y - bottomLeft.Y, 2));

        // 对角线长度应该近似相等
        return Math.Abs(diagonal1 - diagonal2) < 0.001;
    }
    // 计算矩阵中所有点的坐标
    static List<PlateWellPoint> CalculateAllPoints(PlateWellPoint topLeft, PlateWellPoint topRight, PlateWellPoint bottomLeft, int rows, int cols)
    {
        List<PlateWellPoint> points = new List<PlateWellPoint>();

        // 计算行方向和列方向的单位向量
        double rowVectorX = (bottomLeft.X - topLeft.X) / (rows - 1);
        double rowVectorY = (bottomLeft.Y - topLeft.Y) / (rows - 1);

        double colVectorX = (topRight.X - topLeft.X) / (cols - 1);
        double colVectorY = (topRight.Y - topLeft.Y) / (cols - 1);

        // 计算每个点的坐标
        for (int r = 0; r < rows; r++)
        {
            for (int c = 0; c < cols; c++)
            {
                double x = topLeft.X + r * rowVectorX + c * colVectorX;
                double y = topLeft.Y + r * rowVectorY + c * colVectorY;
                points.Add(new PlateWellPoint(x, y) { RowIndex = r, ColumnIndex = c });
            }
        }

        return points;
    }
    // 验证计算的点是否符合给定的行间距和列间距
    static void VerifySpacing(List<PlateWellPoint> points, int rows, int cols, double expectedRowSpacing, double expectedColSpacing)
    {
        double totalRowSpacingError = 0;
        int rowSpacingCount = 0;
        double totalColSpacingError = 0;
        int colSpacingCount = 0;

        // 检查行间距
        for (int r = 0; r < rows - 1; r++)
        {
            for (int c = 0; c < cols; c++)
            {
                int idx1 = r * cols + c;
                int idx2 = ((r + 1) * cols) + c;

                double distance = Math.Sqrt(Math.Pow(points[idx1].X - points[idx2].X, 2) + Math.Pow(points[idx1].Y - points[idx2].Y, 2));
                totalRowSpacingError += Math.Abs(distance - expectedRowSpacing);
                rowSpacingCount++;
            }
        }

        // 检查列间距
        for (int r = 0; r < rows; r++)
        {
            for (int c = 0; c < cols - 1; c++)
            {
                int idx1 = r * cols + c;
                int idx2 = r * cols + c + 1;

                double distance = Math.Sqrt(Math.Pow(points[idx1].X - points[idx2].X, 2) + Math.Pow(points[idx1].Y - points[idx2].Y, 2));
                totalColSpacingError += Math.Abs(distance - expectedColSpacing);
                colSpacingCount++;
            }
        }

        // 打印平均误差
        if (rowSpacingCount > 0)
        {
            double avgRowError = totalRowSpacingError / rowSpacingCount;
            Console.WriteLine($"\n行间距平均误差: {avgRowError:F4} mm");
        }

        if (colSpacingCount > 0)
        {
            double avgColError = totalColSpacingError / colSpacingCount;
            Console.WriteLine($"列间距平均误差: {avgColError:F4} mm");
        }
    }
}

案例图

矩阵模拟图

调用验证

var leftTop = new PlateWellPoint(2, 2);
var rightTop = new PlateWellPoint(6, 6);
var leftButtom = new PlateWellPoint(4, 0);
int rowCount = 3;
int columnCount = 5;
var points = PlatePointMatrixGenerator.GeneratePoints(leftTop, leftButtom, rightTop, rowCount, columnCount, 1, 1);

运行结果
在这里插入图片描述
注意:行列序号从0开始的。

从上述结果中随便选一个点,在案例图中找到进行坐标验证
例如:取索引为13的点,是R2C3即第三行第四列,在案例图中核对坐标是否为x:7,y:3。
从案例图中任选一个坐标点,在上述结果中查找,是否为指定的行和列。

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

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

相关文章

go 并发 gorouting chan channel select Mutex sync.One

goroutine // head&#xff1a; 前缀 index&#xff1a;是一个int的指针 func print(head string, index *int) {for i : 0; i < 5; i {// 指针对应的int *indexfmt.Println(*index, head, i)// 暂停1stime.Sleep(1 * time.Second)} }/* Go 允许使用 go 语句开启一个新的运…

深度学习入门--python入门2

以前学的全忘了&#xff0c;现在算是才开始学&#xff0c;有错误&#xff0c;恳请指正。 目录 1.4 Python脚本文件 1.4.1保存为文件 1.4.2 类 1.5 Numpy 1.5.1 导入Numpy 1.5.2 生成Numpy数组 1.5.3 Numpy的算术运算 1.5.4 Numpy的N维数组 1.5.5 广播 1.5.6 访问元素…

题海拾贝:【枚举】P2010 [NOIP 2016 普及组] 回文日期

Hello大家好&#xff01;很高兴我们又见面啦&#xff01;给生活添点passion&#xff0c;开始今天的编程之路&#xff01; 我的博客&#xff1a;<但凡. 我的专栏&#xff1a;《编程之路》、《数据结构与算法之美》、《题海拾贝》 欢迎点赞&#xff0c;关注&#xff01; 1、题…

Mac端homebrew安装配置

拷打了一下午o3-mini-high&#xff0c;不如这位博主的超强帖子&#xff0c;10分钟结束战斗 跟随该文章即可&#xff0c;2025/2/19亲测可行 mac 安装HomeBrew(100%成功)_mac安装homebrew-CSDN博客文章浏览阅读10w次&#xff0c;点赞258次&#xff0c;收藏837次。一直觉得自己写…

Python高级语法之selenium

目录&#xff1a; 1、selenium的使用2、selenium元素定位3、selenium使用功能Phantomjs模拟浏览器启动4、selenium使用功能ChromsHandless模拟浏览器启动 1、selenium的使用 2、selenium元素定位 3、selenium使用功能Phantomjs模拟浏览器启动 4、selenium使用功能ChromsHandles…

2025年3月最新算法-鲸鱼迁徙优化算法Whale Migration Algorithm-附Matlab免费代码

引言 本期介绍了一种基于座头鲸协同迁移行为的创新生物启发式优化方法——鲸鱼迁徙优化算法Whale Migration Algorithm&#xff0c;WMA。该算法于2025年3月最新发表在期刊 Results in Engineering 在本节中&#xff0c;我们概述了开发鲸鱼迁移算法&#xff08;WMA&#xff09;…

flowable适配达梦数据库

文章目录 适配相关问题无法从数据库产品名称“DM DBMS”中推断数据库类型分析解决 构建ibatis SqlSessionFactory时出错&#xff1a;inStream参数为null分析解决 liquibase相关问题问题一&#xff1a;不支持的数据库 Error executing SQL call current_schema: 无法解析的成员访…

Jenkins整合Jmeter实现接口自动化测试

&#x1f345; 点击文末小卡片&#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 一、安装jmeter 下载&#xff1a;http://jmeter.apache.org/download_jmeter.cgi 这里我用了一台Windows安装jmeter用来写接口测试的脚本&#xff0c;启动前修改j…

高级推理的多样化推理与验证

25年2月来自波士顿大学、NotBadMath.AI、谷歌、哥伦比亚大学、MIT、Intuit公司和斯坦福大学的论文“Diverse Inference and Verification for Advanced Reasoning”。 OpenAI o1、o3 和 DeepSeek R1 等推理 LLM 在数学和编码方面取得重大进展&#xff0c;但仍发现 IMO 组合问题…

清华大学:DeepSeek与AI幻觉(31页PDF)

PDF深入探讨了AI幻觉的概念、原因、评测方法及其实用应用&#xff0c;特别是在金融领域的具体案例。首先介绍了AI幻觉的定义&#xff0c;主要包括数据偏差、泛化困境、知识固化和意图误解四种情况&#xff0c;以及这些因素导致AI产出不合理结果的原因。随后&#xff0c;通过音乐…

AWS云从业者认证题库 AWS Cloud Practitioner(2.21)

题库持续更新&#xff0c;上方二维码查看完整题库&#xff01; 公司希望减少开发人员用于运行代码的物理计算资源,通过启用无服务器架构&#xff0c;哪种服务可以满足该需求? A&#xff1a; Amazon Elastic Compute Cloud (Amazon EC2) B&#xff1a; AWS Lambda C&#xff1a…

网络工程师 (43)IP数据报

前言 IP数据报是互联网传输控制协议&#xff08;Internet Protocol&#xff0c;IP&#xff09;的数据报格式&#xff0c;由首部和数据两部分组成。 一、首部 IP数据报的首部是控制部分&#xff0c;包含了数据报传输和处理所需的各种信息。首部可以分为固定部分和可变部分。 固定…

京准电钟:水利控制系统网络时间同步设计与应用

京准电钟&#xff1a;水利控制系统网络时间同步设计与应用 京准电钟&#xff1a;水利控制系统网络时间同步设计与应用 引言 在水利工程中&#xff0c;控制系统的高效运行依赖于精准的时间同步。水电站、泵站、闸门控制、水文监测等子系统的协同作业需要毫秒甚至微秒级的时间…

QML 实现一个动态的启动界面

QML 实现一个动态的启动界面 一、效果查看二、源码分享三、所用到的资源下载 一、效果查看 二、源码分享 工程结构 main.qml import QtQuick import QtQuick.Controls import QtQuick.Dialogs import Qt.labs.platformWindow {id:windowwidth: 640height: 400visible: truetit…

【论文阅读】SAM-CP:将SAM与组合提示结合起来的多功能分割

导言 近年来&#xff0c;视觉基础模型的快速发展推动了多模态理解的进步&#xff0c;尤其是在图像分割任务中。例如&#xff0c;Segment Anything模型&#xff08;SAM&#xff09;在图像Mask分割上表现出色&#xff0c;但在语义及实例分割方面仍存在局限。本文提出的SAM-CP&am…

逻辑架构与软件架构在PREEvision中的设计关系

1 Introduction 在如今汽车电子系统的开发过程中&#xff0c;系统架构设计是至关重要的环节。无论是汽车控制系统、信息娱乐系统&#xff0c;还是电动驱动系统&#xff0c;架构设计都决定了整个系统的功能、性能以及后期的可维护性和可扩展性。 在往期文章中&#xff0c;我们…

武汉火影数字|VR沉浸式空间制作 VR大空间打造

VR沉浸式空间制作是指通过虚拟现实技术创建一个逼真的三维环境&#xff0c;让用户能够沉浸在这个环境中&#xff0c;彷佛置身于一个全新的世界。 也许你会好奇&#xff0c;VR 沉浸式空间究竟是如何将我们带入那奇妙的虚拟世界的呢&#xff1f;这背后&#xff0c;离不开一系列关…

大数据学习之任务流调度系统Azkaban、Superset可视化系统

一.任务流调度系统Azkaban 1.课程介绍 2.为什么需要工作流调度系统 3.AZKABAN是什么 4.AZKABAN下载 5.制作安装包 6.tar包准备 7.MYSQL配置AZKABAN 8.配置EXECUTOR SERVER 9.配置WEBSERVER 10.单作业实战_yaml语言(今天稍晚更新) 11.单作业实战 12.多作业依赖实战 13.失败自动重…

在VS-qt的程序中,后期增加PCH预编译功能,提高编译速度

由于前期创建qt程序的时候未勾选pch功能,导致没有启动预编译的功能. 这种情况下需要增加pch功能应该怎么做? 在项目中增加2个文件 stdafx.h和stdafx.cpp文件 stdafx.h增加qt常用头文件 #pragma once //windows #include <windows.h>//qt常用 #include <QObject&g…

蓝桥云客 路径之谜

11.路径之谜 - 蓝桥云课 路径之谜 题目描述 小明冒充X星球的骑士&#xff0c;进入了一个奇怪的城堡。 城堡里边什么都没有&#xff0c;只有方形石头铺成的地面。 假设城堡地面是nn个方格。如下图所示。 按习俗&#xff0c;骑士要从西北角走到东南角。可以横向或纵向移动&…