当前位置: 首页 > article >正文

C# | GDI+图像测距辅助线的实现思路

C# | GDI+图像测距辅助线的实现思路

一、辅助线需求概述

在图像测量工具中,动态辅助线的数值标签需要满足两个核心要求:其一,标签方向需与辅助线走向保持一致;其二,无论辅助线处于何种角度,文本必须保持正面朝上显示。
在这里插入图片描述

二、坐标系与角度计算

2.1 笛卡尔坐标系

在屏幕坐标系中,Y轴方向与数学坐标系相反(向下为正方向)。两点间连线形成的角度范围在-π到π之间,对应屏幕空间的360度方向。

2.2 线长和角度计算方法

计算两点之间的距离:

double length = Math.Sqrt(Math.Pow(endPoint.X - startPoint.X, 2) + Math.Pow(endPoint.Y - startPoint.Y, 2));

计算线的反正切值,Math.Atan2 返回的值在 (-π, π] 之间,用于表示线的方向:

double atan = Math.Atan2(endPoint.Y - startPoint.Y, endPoint.X - startPoint.X);
2.3 文本角度矫正计算方法

调整反正切值,以确保显示的长度文本始终保持向上的方向。如果反正切值的绝对值大于 π/2,说明线的倾斜方向可能导致文本倒着显示。
此时通过 -(Math.PI - atan) 来调整反正切值,使其对应的文本方向向上。

atan = Math.Abs(atan) > Math.PI / 2 ? -(Math.PI - atan) : atan;
2.4 坐标变换实现步骤
  1. 平移坐标系至线段中点
  2. 应用旋转变换
  3. 垂直偏移避免覆盖线段

关键代码段:

// 计算中点位置
PointF midPoint = new PointF((startPoint.X + endPoint.X) / 2, (startPoint.Y + endPoint.Y) / 2);

// 调整原点至两点中心
g.TranslateTransform(midPoint.X, midPoint.Y);
g.RotateTransform((float)(atan * 180 / Math.PI));

三、与if判断方式对比

使用if连环判断不但啰嗦还存在除零风险。

if (deltaX >= 0 && deltaY >= 0) // 第一象限
{
    angle = Math.Atan(deltaY / deltaX);
}
else if (deltaX <= 0 && deltaY >= 0) // 第二象限
{
    angle = Math.PI - Math.Atan(deltaY / -deltaX);
}
// 三、四...

四、总结

通过坐标变换矩阵验证法可检测实现效果:

  1. 当辅助线处于水平方向(0度)时,旋转角度为0
  2. 当辅助线垂直向上(-90度)时,实际应用90度旋转
  3. 当辅助线倾斜135度时,自动校正为-45度显示

综上,在0-360度全范围内均能保持文本正向显示,感谢阅读。


http://www.kler.cn/a/562781.html

相关文章:

  • Ubuntu20.04下各类常用软件及库安装汇总
  • DeepSeek:我的AI助手之旅
  • macOS安装Redis
  • 阿里云飞燕生活物联网平台成功实现上传自定义面板(包括环境搭建、自定义面板开发与调试过程记录等)
  • order by布尔盲注、时间盲注
  • 将VsCode变得顺手好用(1
  • randlanet 部署 -- 模型静态化
  • ClickHouse 的分区、分桶和分片详解
  • AIGC-LLAMA模型介绍
  • 在 Ubuntu 下通过 Docker 部署 Mastodon 服务器
  • adb的安装
  • 顾客关系管理CRM思维导图模版
  • 【hot100】刷题记录(29)-搜索二维矩阵
  • PINN求解固体力学问题——论文加代码
  • 通过阿里云RDS排查解决MYSQL慢SQL--图文教学
  • LeetCode 589
  • 编程小白冲Kaggle每日打卡(16)--kaggle学堂:<机器学习简介>欠拟合与过拟合
  • Java 网络协议面试题答案整理,最新面试题
  • C++ 二叉树的后序遍历 - 力扣(LeetCode)
  • 通过Sidecar模式实现服务注册、服务发现和负载均衡的分布式系统架构