【C#】已知有三个坐标点:P0、P1、P2,当满足P3和P4连成的一条直线 与 P0和P1连成一条直线平行且长度一致,该如何计算P3、P4?

news2024/9/23 19:22:04

问题描述

已知有三个坐标点:P0、P1、P2,当满足P3和P4连成的一条直线 与 P0和P1连成一条直线平行长度一致,该如何计算P3、P4?

 

解决办法

思路一:斜率及点斜式方程

6a6ffa76862f47eb9ac46aa74031d56c.png


# 示例坐标
x0, y0 = 1, 1 # P0坐标
x1, y1 = 4, 4 # P1坐标
x2, y2 = 2, 2 # P2坐标

# 计算直线P0P1的斜率
m = (y1 - y0) / (x1 - x0)

# 设定P3和P4在x轴上的不同值
x3 = x2 - 1
x4 = x2 + 1

# 使用点斜式方程求P3和P4的y坐标
y3 = m * (x3 - x2) + y2
y4 = m * (x4 - x2) + y2

# P3和P4的坐标
P3 = (x3, y3)
P4 = (x4, y4)

P3, P4

思路二:斜率及两线相交

直线的斜率

斜率是数学中的一个概念,特别是在解析几何和平面直角坐标系中,用来描述一条直线倾斜程度的量。它定义为直线上任意两点之间的垂直变化量(即纵坐标的变化量,通常称为“上升”或“Δy”)与水平变化量(即横坐标的变化量,通常称为“运行”或“Δx”)之比。斜率通常用字母 m 表示。

 

6af594287d3649baa8746d1254c040a5.png

需要注意的是,对于垂直线,由于水平变化量“Δx” 为零,所以斜率无法定义,因为这会导致分母为零,我们说垂直线的斜率是无穷大或未定义。

斜率的概念在许多数学和物理问题中都有应用,例如在微积分中,导数可以看作是曲线在某一点处的瞬时斜率;在物理学中,斜率可以表示速度、加速度等随时间的变化率。

在实际应用中,斜率也可以帮助我们理解数据的趋势,比如在统计学中,通过计算散点图中数据点的斜率,我们可以了解变量间的关系是正相关还是负相关。

 

注意:两条平行的直线斜率是相等的。

 

如何计算两条直线的垂直交点

15521f07509e4798bcb53b19a91f1433.png

using System;
using System.Numerics; // For handling potential overflow with large numbers

public class LineIntersection
{
    public static Tuple<double, double>? FindPerpendicularIntersection(Tuple<double, double> p1, Tuple<double, double> p2, Tuple<double, double> p3, Tuple<double, double> p4)
    {
        double dx1 = p2.Item1 - p1.Item1;
        double dy1 = p2.Item2 - p1.Item2;
        double dx2 = p4.Item1 - p3.Item1;
        double dy2 = p4.Item2 - p3.Item2;

        // Check for vertical and horizontal lines
        bool isVerticalLine1 = Math.Abs(dx1) < double.Epsilon;
        bool isVerticalLine2 = Math.Abs(dx2) < double.Epsilon;
        bool isHorizontalLine1 = Math.Abs(dy1) < double.Epsilon;
        bool isHorizontalLine2 = Math.Abs(dy2) < double.Epsilon;

        if (isVerticalLine1 && isVerticalLine2)
        {
            // Both lines are vertical, check if they coincide
            if (Math.Abs(p1.Item1 - p3.Item1) > double.Epsilon)
                return null; // Lines do not intersect
        }
        else if (isVerticalLine1)
        {
            // Line 1 is vertical, Line 2 is not
            if (isHorizontalLine2)
            {
                // Line 2 is horizontal, check intersection
                if (p3.Item1 <= p1.Item1 && p1.Item1 <= p4.Item1 || p4.Item1 <= p1.Item1 && p1.Item1 <= p3.Item1)
                    return Tuple.Create(p1.Item1, p3.Item2);
                else
                    return null;
            }
            else
            {
                // Calculate intersection of vertical line 1 and non-vertical line 2
                double m2 = dy2 / dx2;
                double b2 = p3.Item2 - m2 * p3.Item1;
                double y = m2 * p1.Item1 + b2;
                return Tuple.Create(p1.Item1, y);
            }
        }
        else if (isVerticalLine2)
        {
            // Line 2 is vertical, Line 1 is not
            if (isHorizontalLine1)
            {
                // Line 1 is horizontal, check intersection
                if (p1.Item1 <= p3.Item1 && p3.Item1 <= p2.Item1 || p2.Item1 <= p3.Item1 && p3.Item1 <= p1.Item1)
                    return Tuple.Create(p3.Item1, p1.Item2);
                else
                    return null;
            }
            else
            {
                // Calculate intersection of vertical line 2 and non-vertical line 1
                double m1 = dy1 / dx1;
                double b1 = p1.Item2 - m1 * p1.Item1;
                double y = m1 * p3.Item1 + b1;
                return Tuple.Create(p3.Item1, y);
            }
        }
        else if (isHorizontalLine1 && isHorizontalLine2)
        {
            // Both lines are horizontal, check if they coincide
            if (Math.Abs(p1.Item2 - p3.Item2) > double.Epsilon)
                return null; // Lines do not intersect
        }
        else if (isHorizontalLine1)
        {
            // Line 1 is horizontal, Line 2 is not
            double m2 = dy2 / dx2;
            double b2 = p3.Item2 - m2 * p3.Item1;
            double x = (p1.Item2 - b2) / m2;
            return Tuple.Create(x, p1.Item2);
        }
        else if (isHorizontalLine2)
        {
            // Line 2 is horizontal, Line 1 is not
            double m1 = dy1 / dx1;
            double b1 = p1.Item2 - m1 * p1.Item1;
            double x = (p3.Item2 - b1) / m1;
            return Tuple.Create(x, p3.Item2);
        }
        else
        {
            // Neither line is vertical or horizontal
            double det = dx1 * dy2 - dx2 * dy1;
            if (Math.Abs(det) < double.Epsilon)
            {
                // Lines are parallel or coincident
                return null;
            }

            double x = (dx1 * (p3.Item2 - p1.Item2) - dy1 * (p3.Item1 - p1.Item1)) / det;
            double y = (dy2 * (p3.Item1 - p1.Item1) - dx2 * (p3.Item2 - p1.Item2)) / det;
            return Tuple.Create(x, y);
        }

        return null; // Should never reach here
    }
}

需要注意的是,上述代码没有处理垂直线的情况,因为垂直线的斜率为无穷大。在实际应用中,你需要特别检查分母是否为零,以避免除以零的错误。

此外,如果两条直线实际上是平行的而不是垂直的(即 m1=m2​),则上述代码会抛出异常,因为这样的直线没有交点(除非它们是同一直线,在这种情况下,它们有无数个交点)。

如果你需要一个更完整的实现,包括处理垂直线和重合线的情况,请告知我,我可以进一步详细说明。

思路三:方向向量 

using System;

public class CoordinateCalculator
{    public static void Main(string[] args)
    {
        // 坐标1、坐标2、坐标3
        double[] coord1 = { 1.0, 2.0 };
        double[] coord2 = { 4.0, 6.0 };
        double[] coord3 = { 7.0, 8.0 };

        // 计算坐标4和坐标5
        double[][] results = CalculateCoordinates(coord1, coord2, coord3);

        // 输出结果
        Console.WriteLine("坐标4: (" + results[0][0] + ", " + results[0][1] + ")");
        Console.WriteLine("坐标5: (" + results[1][0] + ", " + results[1][1] + ")");
    }

    public static double[][] CalculateCoordinates(double[] coord1, double[] coord2, double[] coord3)
    {
        // 计算坐标1和坐标2连成的直线的方向向量
        double dx = coord2[0] - coord1[0];
        double dy = coord2[1] - coord1[1];

        // 计算坐标1和坐标2之间的距离
        double distance = Math.Sqrt(dx * dx + dy * dy);

        // 归一化方向向量
        double directionX = dx / distance;
        double directionY = dy / distance;

        // 坐标4和坐标5是沿着方向向量和反方向向量的点
        double[] coord4 = { coord3[0] + directionX * distance, coord3[1] + directionY * distance };
        double[] coord5 = { coord3[0] - directionX * distance, coord3[1] - directionY * distance };

        return new double[][] { coord4, coord5 };
    }
}

 

注意:上述只是参考,具体的实现还需自己计算。

 

 

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

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

相关文章

MySQL执行状态查看与分析

当mysql出现性能问题时&#xff0c;一般会查看mysql的执行状态&#xff0c;执行命令&#xff1a; show processlist 各列的含义 列名含义id一个标识&#xff0c;你要kill一个语句的时候使用&#xff0c;例如 mysql> kill 207user显示当前用户&#xff0c;如果不是root&…

生信软件27 - 基于python的基因注释数据查询/检索库mygene

1. mygene库简介 MyGene.info提供简单易用的REST Web服务来查询/检索基因注释数据&#xff0c;具有以下特点&#xff1a; mygene技术文档&#xff1a; https://docs.mygene.info/en/latest/ 多物种支持: 包括人、小鼠、大鼠、斑马鱼等多个模式生物&#xff1b; 多数据源聚合…

mysql-事务的隔离界别

一.事务的隔离级别 二.查看事务的隔离级别 SELECT TRANSASCTION ISOLATION 三.设置事务隔离级别 SET [SESSION | GLOBAL] TRANSACTION ISOLATION LEVEL [READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE] 四.总结 1.事务简介 事务是一组操作的集合…

车载以太网交换机入门基本功(2)— 初识VLAN

在《交换机入门基本功 -上》提到&#xff0c;交换机在物理层面划分通信区域并产生局域网&#xff08;Local Area Network, LAN&#xff09;。局域网具有一个特点&#xff1a;连线拓扑一旦确定&#xff0c;一定时间内不会发生通信区域的变动。在实际通信过程中&#xff0c;广播报…

MKS流量计软件MFC通讯驱动使用于C和P系列MFC控制USB接口W10系统

MKS流量计软件MFC通讯驱动使用于C和P系列MFC控制USB接口W10系统

国产精品ORM框架-SqlSugar详解 SqlSugar初识 附案例源码 云草桑 专题一

国产精品ORM框架-SqlSugar详解 1、SqlSugar初识 2、开始实操 3、增删改操作 4、进阶功能 5、集成整合 6、脚手架应用 sqlsugar 官网-CSDN博客 国产精品ORM框架-SqlSugar详解 SqlSugar初识 专题二-CSDN博客 1、SqlSugar初识 1.1 基本概念和历史 SqlSugar 是一款 老牌 …

论文复现丨物流中心选址问题:蜘蛛猴算法求解

路径优化系列文章&#xff1a; 1、路径优化历史文章2、物流中心选址问题论文复现丨改进蜘蛛猴算法求解 物流中心选址问题 一般物流中心选址问题是指&#xff1a;在有限的用户(即需求点)中找出一定数量的地点建立配送中心&#xff0c;实现从物流中心到用户之间的配送&#xf…

实验3.mbr读取硬盘

简介 实验&#xff1a;编写 mbr&#xff0c;读取0盘0道2扇区的内容写入内存&#xff0c;然后跳转执行写好的loader.s 代码 boot/mbr.s ; boot/mbr.s ; 功能&#xff1a;读取磁盘&#xff0c;加载loader到内存并跳转到loader%include "boot.inc" SECTION MBR vsta…

【Python 基础】方法

方法 方法和函数是一回事,只是它是调用在一个值上。例如,如果一个列表值存储在 spam 中,你可以在这个列表上调用 index()列表方法(稍后我会解释),就像spam.index(‘hello’)一样。方法部分跟在这个值后面,以一个句点分隔。 每种数据类型都有它自己的一组方法。例如,列…

Qt5.12.2安装教程

文章目录 文章介绍下载连接安装教程 文章介绍 安装Qt5.12.2 下载连接 点击官网下载 安装包下载完毕 安装教程 点开设置&#xff0c;添加临时储存库&#xff0c;复制连接“https://download.qt.io/online/qtsdkrepository/windows_x86/root/qt/” 点击测试&#xff0…

航空航天用电机控制器和车规级电机控制器有什么区别?

航空航天用电机控制器和车规级电机控制器有什么区别&#xff1f; 1.标准与认证要求2.工作环境与温度范围3.可靠性与容错性4.性能要求5.使用寿命与维护6.成本与批量生产 最近遇到这样一个问题&#xff0c;处在航空航天动力系统行业中&#xff0c;也会经常遇到类似的问题&#xf…

Spring框架(三)——AOP--基础部分

1、概括 将与核心业务无关的代码独立的抽取出来&#xff0c;形成一个独立的组件&#xff08;抽取公共代码的过程&#xff09;&#xff0c;然后以横向交叉的方式应用到业务流程当中的过程被称为AOP优点 代码复用性强 代码易维护 使开发者更专注于业务逻辑 2、AOP的底层原理&…

探索APP开发中的主流版式设计与应用实践

在当今移动互联网高速发展的时代&#xff0c;APP已成为人们日常生活中不可或缺的一部分。无论是社交娱乐、购物支付还是工作学习&#xff0c;各类APP都以其独特的界面设计和用户体验赢得了用户的青睐。而APP开发的版式设计和页面规范&#xff0c;则是决定用户体验好坏的关键因素…

打卡第15天------二叉树

最近公司给我派活儿太多了,要干好多活儿,好多工作任务要处理,我都没时间刷题了。leetcode上的题目通过数量一直停留在原地不动,我真的很着急呀,我现在每天过的都有一种紧迫感,很着急,有一种与时间赛跑的感觉,真的时间过的太快了,没有任何人能够阻挡住时间的年轮向前推…

SongComposer:让大模型像人类一样具有音乐创作力

人工智能咨询培训老师叶梓 转载标明出处 大模型在翻译、复杂语言环境中的推理等任务中展现出了人类级别的能力。这引发了一个问题&#xff1a;这些模型能否在更具情感、抽象性以及需要专业技能的领域中&#xff0c;如音乐创作&#xff0c;展现出人类的创造力呢&#xff1f;香港…

IAR启动流程深度“起底”

目录 1. IAR启动流程概述 2.可以不用__iar_program_start吗 3.小结 大家好&#xff0c;今天的肌肉也不是很快乐。 今天聊聊IAR特有的一些启动流程以及在调试的时候遇到的一些问题。 1. IAR启动流程概述 ARM M内核芯片里的启动代码通常会提供Arm、gcc、iar等编译器的模板&…

OrangePi 学习摘录

文章目录 1. 参考2. 开发板 Orange-Pi-CM4 预览3. 烧录 Linux 镜像到 TF 卡中4. 制作桌面版镜像qemu/chroot 5. Armbian6. 编译 1. 参考 淘宝 香橙派官网 Orange-Pi-3B Orange-Pi-CM4 基于docker构建香橙派zero系统构建环境 2. 开发板 Orange-Pi-CM4 预览 3. 烧录 Linux 镜像…

[iOS]浅析isa指针

[iOS]浅析isa指针 文章目录 [iOS]浅析isa指针isa指针isa的结构isa的初始化注意事项 上一篇留的悬念不止分类的实现 还有isa指针到底是什么 它是怎么工作的 class方法又是怎么运作的 class_data_bits_t bits; // class_rw_t * plus custom rr/alloc flags 这里面的class又是何方…

【C++11】(lambda)

C11中的lambda与线程。 目录 Lambda&#xff1a;仿函数的缺点&#xff1a;Lambda语法&#xff1a;Lambda使用示例&#xff1a;两数相加&#xff1a;两数交换&#xff1a;解决Goods排序问题&#xff1a; Lambda原理&#xff1a; Lambda&#xff1a; 假设我们有一个商品类&…

controller-from表单1

mvc模式是spring boot 开发web应用程序主要使用模式&#xff0c;mvc分别代表model模型&#xff0c;view是视图 &#xff0c;controller是控制器 controller是对接用户请求数据调用服务层代码&#xff0c;具体怎么操作 浏览器发送http请求给到dispatcherServlet&#xff08;前…