數據挖掘筆記:點到線段的距離計算

1. 寫在前面

最近在搞一個"大曲率彎道"場景的數據挖掘,里面有個邏輯是給定自車的定位坐標和車道線的坐標點,根據點到線段的距離,去找到自車所在的車道中心線。

然后發現這個計算其實在很多場景中都是可以用到的,所以就想通過一篇文章來整理下這塊的原理和代碼實戰,算是把學校學習的向量知識真正的應用到實戰中。

2. 原理

首先得知道一個點:點到線段最短距離的運算與點到直線的最短距離的運算二者之間存在一定的差別,即求點到線段最短距離時需要考慮參考點在沿線段方向的投影點是否在線段上,若在線段上才可采用點到直線距離公式。
Alt
三種情況:

  1. 點在投射在線段上, 點到線段的距離 等效 點到直線的距離, 圖(a)
  2. 點在線段外, 點到線段的距離為該點到最近短點的距離, 圖(b)(c )
  3. 點在線段上, 點到線段的距離為0

參考這篇文章, 介紹3種方法:

Alt

3. 實戰

有了理論, 下面給出代碼實戰, 用python實現了兩版。

import numpy as np
import math# 向量之間直接運算
def distance_point_to_segment(point, segment_start, segment_end):"""計算點到線段的最短距離:param point: 點的坐標,形如(x, y):param segment_start: 線段起點坐標,形如(x, y):param segment_end: 線段終點坐標,形如(x, y):return: 最短距離"""segment_vec = segment_end - segment_startpoint_vec = point - segment_startprojection_length = np.dot(point_vec, segment_vec) / np.dot(segment_vec, segment_vec)if projection_length < 0:return np.linalg.norm(point_vec)elif projection_length > 1:return np.linalg.norm(point - segment_end)else:projection = segment_start + projection_length * segment_vecreturn np.linalg.norm(point - projection)# 如果用坐標的計算方式
def distance_point_to_line_segment(point, start, end):"""計算點到線段的距離:param point: 點 (x, y):param start: 線段起點 (x, y):param end: 線段終點 (x, y):return: 點到線段的距離"""px, py = pointsx, sy = startex, ey = end# 計算線段的長度line_length = math.sqrt((ex - sx) ** 2 + (ey - sy) ** 2)if line_length == 0:return math.sqrt((px - sx) ** 2 + (py - sy) ** 2)# 計算點到線段所在直線的投影比例dot_product = ((px - sx) * (ex - sx) + (py - sy) * (ey - sy)) / (line_length ** 2)if dot_product < 0:return math.sqrt((px - sx) ** 2 + (py - sy) ** 2)elif dot_product > 1:return math.sqrt((px - ex) ** 2 + (py - ey) ** 2)else:# 計算投影點的坐標proj_x = sx + dot_product * (ex - sx)proj_y = sy + dot_product * (ey - sy)return math.sqrt((px - proj_x) ** 2 + (py - proj_y) ** 2)# 三個點計算曲率
def get_lane_curve(lane, closest_end_point_idx):point_len = len(lane.geometry.points)point_1 = lane.geometry.points[closest_end_point_idx]point_0 = lane.geometry.points[min(closest_end_point_idx + 12, point_len - 2)]point_2 = lane.geometry.points[max(closest_end_point_idx - 8, 0)]cur_point = np.array((point_1.xyz.x, point_1.xyz.y))points = lane.geometry.points# 向后搜索30米的點(point_0)for i in range(closest_end_point_idx, point_len):next_point = np.array((points[i].xyz.x, points[i].xyz.y))if np.linalg.norm(next_point - cur_point) >= 15:point_0 = points[i]break# 向前搜索30米的點(point_2)for i in range(closest_end_point_idx, -1, -1):next_point = np.array((points[i].xyz.x, points[i].xyz.y))if np.linalg.norm(next_point - cur_point) >= 15:point_2 = points[i]breakpoint_0 = np.array((point_0.xyz.x, point_0.xyz.y))point_1 = np.array((point_1.xyz.x, point_1.xyz.y))point_2 = np.array((point_2.xyz.x, point_2.xyz.y))x0, y0 = point_0x1, y1 = point_1x2, y2 = point_2cross_product = (x1 - x0) * (y2 - y0) - (x2 - x0) * (y1 - y0)if cross_product == 0:curve_radius = float('inf')else:# 計算三邊長度ab = np.linalg.norm(point_1 - point_0)bc = np.linalg.norm(point_1 - point_2)ca = np.linalg.norm(point_0 - point_2)# 計算曲率半徑curve_radius = (ab * bc * ca) / (2 * abs(cross_product))return curve_radius

lua實現了一版

-- 計算點到線段的最短距離
function distance_point_to_segment(point, segment_start, segment_end)local segment_vec = vec_sub(segment_end, segment_start)local point_vec = vec_sub(point, segment_start)local segment_length_sq = vec_dot(segment_vec, segment_vec)if segment_length_sq == 0 thenreturn vec_norm(point_vec)end-- 限制在[0,1]區間local t = vec_dot(point_vec, segment_vec) / segment_length_sqt = math.max(0, math.min(1, t))local projection = vec_add(segment_start, vec_mul_scalar(segment_vec, t))return vec_norm(vec_sub(point, projection))
end

參考資料:

  • 數學—點到線段的最短距離
  • 可視化學習:利用向量計算點到線段的距離并展示
  • 點到線段的距離
  • 使用向量的方法計算點到直線的距離(有一些基礎知識)

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/919500.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/919500.shtml
英文地址,請注明出處:http://en.pswp.cn/news/919500.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

C++篇(2)C++入門(下)

一、引用1.1 引用的概念和定義引用不是新定義一個變量&#xff0c;而是給已經存在的變量取別名&#xff0c;編譯器不會為引用變量開辟內存空間&#xff0c;它和它引用的變量共用一塊內存空間。類型& 引用別名 引用對象int a 10;int& b a; //b是a的引用1.2 引用的…

Windows 如何清理右鍵菜單?電腦桌面右鍵菜單里出現一個清理內存 怎么去掉?

RightMenuMgr是一款綠色小巧免費的右鍵菜單管理工具&#xff0c;簡體中文界面&#xff0c;很方便操作&#xff0c;可以幫助用戶輕松管理右鍵菜單&#xff0c;能夠重新定義傳統的右鍵&#xff0c;軟件體積小&#xff0c;功能強大&#xff0c;安全無毒&#xff0c;且使用免費&…

【力扣 Hot100】 刷題日記——雙指針的經典應用

D11 兩數之和 II - 輸入有序數組 LCR 006. 兩數之和 II - 輸入有序數組 - 力扣&#xff08;LeetCode&#xff09; 這道題目也是雙指針的一個典型應用&#xff0c;題目要求找出和為target的兩個數字的下標&#xff0c;并且告訴了有且僅有一對符合條件的數字。 而且題目已經給…

在一臺沒聯網的機器上,用ollama加載qwen3,14b

文章目錄 背景 去另一臺機器下載模型 使用docker部署ollama 后續 背景 項目甲方終于搞定了一臺T4,咱們的項目又可以正常推進了。 但是,高高興興地上去之后,發現,此機器竟不可以聯網~ 不過好在,前輩已經把docker裝好了。 竟然還有ollama的鏡像。 可以的,至少可以節省一…

Angular由一個bug說起之十八:伴隨框架升級而升級ESLint遇到的問題與思考

伴隨框架升級而升級ESLint遇到的問題與思考 對于eslint這個前端事實上的代碼檢查工具標準&#xff0c;大家可能是再熟悉不過了。幾乎是在編碼的時時刻刻都在和它接觸。在我們開發維護長達十年的項目中自然也是采用了ESLint&#xff0c;在從 AngularJS 一路到今天現代化的 Angu…

unfold 切圖像,圖形transformer的切割操作

import torch x torch.arange(8*12).view(1,1,8,12) mx.unfold(2, 4, 4) n m.unfold(3, 4, 4)輸入第一次切&#xff0c;切高度維度&#xff0c;但是切完做了轉置 &#xff0c;得到&#xff08;1&#xff0c;1&#xff0c;2&#xff0c;12&#xff0c;4&#xff09;切寬度 得…

基于最小二乘支持向量機的數據回歸預測 LSSVM

一、作品詳細簡介 1.1附件文件夾程序代碼截圖 全部完整源代碼&#xff0c;請在個人首頁置頂文章查看&#xff1a; 學行庫小秘_CSDN博客?編輯https://blog.csdn.net/weixin_47760707?spm1000.2115.3001.5343 1.2各文件夾說明 1.2.1 main.m主函數文件 該MATLAB 代碼實現了…

Java虛擬機故障處理工具全指南

目錄 一、JVM故障處理工具概述 二、詳細工具解析 1. jps&#xff1a;虛擬機進程狀況工具 2. jstat&#xff1a;虛擬機統計信息監視工具 3. jinfo&#xff1a;Java配置信息工具 4. jmap&#xff1a;Java內存映像工具 5. jhat&#xff1a;堆轉儲快照分析工具 6. jstack&a…

【LeetCode熱題100道筆記+動畫】接雨水

題目描述 給定 n 個非負整數表示每個寬度為 1 的柱子的高度圖,計算按此排列的柱子,下雨之后能接多少雨水。 示例 1: 輸入:height = [0,1,0,2,1,0,1,3,2,1,2,1] 輸出:6 解釋:上面是由數組 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度圖,在這種情況下,可以接 6 個單位的雨水…

短劇小程序系統開發:構建影視娛樂新生態的基石

在移動互聯網的浪潮中&#xff0c;影視娛樂行業正經歷著深刻的變革。短劇&#xff0c;作為一種新興的內容形式&#xff0c;以其獨特的魅力和廣泛的受眾基礎&#xff0c;成為了行業發展的新亮點。而短劇小程序系統開發&#xff0c;則是構建影視娛樂新生態的基石&#xff0c;為行…

基于Pytochvideo訓練自己的的視頻分類模型

視頻分類模型簡介 ?X3D 系列模型 官方網站 https://github.com/facebookresearch/SlowFast ?提出論文? Facebook Research 的《X3D: Expanding Architectures for Efficient Video Recognition》 https://arxiv.org/pdf/2004.04730 原理 X3D 的設計思路受到機器學習中…

LidaRefer-v2論文速讀

研究背景 研究背景 3D視覺定位&#xff08;3D Visual Grounding, VG&#xff09;是一項旨在根據自然語言描述&#xff0c;在三維場景中精確定位出相應物體或區域的任務 。這項技術在人機交互領域至關重要&#xff0c;尤其是在自動駕駛、機器人技術和AR/VR等應用中&#xff0c;它…

邏輯移位與算術移位

根本的區別在于&#xff1a;它們如何對待符號位&#xff08;最高位&#xff09;。 一、邏輯移位 (Logical Shift) 無論左移、右移&#xff0c;空出的位永遠用 0 填充。主要針對無符號整數、快速乘除2的冪。 二、算術移位 (Arithmetic Shift) 左移用 0 填充、右移用符號位填充。…

內存對齊的使用和禁用

在 C 語言和 C 中&#xff0c;__attribute__((packed)) 是一種用于數據結構體的編譯器擴展屬性&#xff0c;這個屬性主要用于修改結構體的內存對齊行為。背景知識&#xff1a;結構體內存對齊在許多計算機架構中&#xff0c;編譯器會自動對數據進行對齊&#xff08;alignment&am…

SpringBoot3后端項目介紹:mybig-event

mybig-event 項目簡介 mybig-event 是一個基于 Spring Boot 的事件管理系統&#xff0c;提供用戶管理、文章發布、分類管理、文件上傳等功能&#xff0c;采用現代化的 Java 技術棧構建&#xff0c;支持高效開發和部署。 倉庫鏈接&#xff1a;https://github.com/foorgange/mybi…

week3-[分支嵌套]方陣

week3-[分支嵌套]方陣 題目描述 有 nmn\times mnm 個人站成 nnn 行 mmm 列的方陣。我們想知道第 xxx 行 yyy 列的人的某個方向有沒有人。 輸入格式 輸入共 222 行。 第 111 行輸入 444 個正整數 n,m,x,yn,m,x,yn,m,x,y。 第 222 行輸入 111 個字符為 U、D、L、R 其中之一&#…

深入理解C++ std::shared_ptr:現代C++內存管理的藝術與實踐

在C++的發展歷程中,內存管理始終是開發者面臨的核心挑戰。從C語言繼承而來的手動內存管理方式,雖然提供了極大的靈活性,卻也成為無數程序錯誤的根源。內存泄漏、懸空指針、雙重釋放等問題長期困擾著C++開發者,直到智能指針的出現改變了這一局面。作為C++11標準引入的重要特…

一個 WPF 文檔和工具窗口布局容器

一個 WPF 文檔和工具窗口布局容器、用于排列文檔 和工具窗口的方式與許多知名 IDE 類似&#xff0c;例如 Eclipse、Visual Studio、 PhotoShop 等等 AvalonDock 是一個 WPF 文檔和工具窗口布局容器&#xff0c;用于排列文檔 和工具窗口的方式與許多知名 IDE 類似&#xff0c;例…

【qml-5】qml與c++交互(類型單例)

背景&#xff1a; 【qml-1】qml與c交互第一次嘗試&#xff08;實例注入&#xff09; 【qml-2】嘗試一個有模式的qml彈窗 【qml-3】qml與c交互第二次嘗試&#xff08;類型注冊&#xff09; 【qml-4】qml與c交互&#xff08;類型多例&#xff09; 【qml-5】qml與c交互&#…

循環神經網絡(RNN)、LSTM 與 GRU (一)

循環神經網絡&#xff08;RNN&#xff09;、LSTM 與 GRU &#xff08;一&#xff09; 文章目錄循環神經網絡&#xff08;RNN&#xff09;、LSTM 與 GRU &#xff08;一&#xff09;循環神經網絡&#xff08;RNN&#xff09;、LSTM 與 GRU一、RNN&#xff08;Recurrent Neural N…