【发布时间】:2021-05-18 06:24:14
【问题描述】:
我正在尝试找到一种在R中找到2条双曲线交点的方法。单分支双曲线可以用以下等式描述:
或
其中(xi, yi) 和(xj, yj) 是2 个焦点(i 和j)的坐标,r 是双曲线(x, y) 上给定点与每个焦点之间的距离差焦点。
似乎使用 R 可视化双曲线的最佳方法是可视化 3D 双曲线的轮廓线(当轮廓水平 = 0 时),使用上述等式确定并将其实现为函数
f1 <- function(xi, yi, xj, yj, x, y, r){
sqrt((xj - x)^2 + (yj - y)^2) - sqrt((xi - x)^2 + (yi - y)^2) - r
}
例如,我们可以构建一个网格并可视化两条双曲线的 0 级轮廓:
library(tidyverse)
library(sf)
# sample points
tribble(
~name, ~x, ~y,
'a', 25, 25,
'b', 75, 25,
'c', 50, 75,
) %>%
{. ->> sample_points}
# sample hyperbolae
expand.grid(
x = seq(0, 100, length = 100),
y = seq(0, 100, length = 100)
) %>%
as_tibble %>%
mutate(
z1 = f1(xi = 25, yi = 25, xj = 75, yj = 25, x, y, r = 5), # i = point a, j = point b
z2 = f1(xi = 25, yi = 25, xj = 50, yj = 75, x, y, r = 5) # i = point a, j = point c
) %>%
{. ->> hyp_data} %>%
ggplot()+
geom_contour(aes(x, y, z = z1), breaks = 0, colour = 1)+
geom_contour(aes(x, y, z = z2), breaks = 0, colour = 2)+
geom_point(data = sample_points, aes(x, y, color = name), size = 3)+
coord_sf()
目前,我可以通过从两条geom_contour 线中提取线数据,使用ggplot_build(),将线坐标转换为sf LINESTRING,并使用st_intersection 来找到交点交点:
# extract the data from the ggplot using ggplot_build()
ggplot_build(
hyp_data %>%
ggplot()+
geom_contour(aes(x, y, z = z1), breaks = 0, colour = 1)+
geom_contour(aes(x, y, z = z2), breaks = 0, colour = 2)+
# geom_point(data = sample_points, aes(x, y, color = name), size = 3)+ # we dont need the point data in ggplot_build()
coord_sf()
) %>%
.$data %>% # keep only the data component
map(. %>% select(x, y) %>% as.matrix %>% st_linestring) %>% # keep coordinates, turn into a linestring
{. ->> lines1}
# make the lines an sf object
tibble(a = 1:2) %>%
mutate(
geom = st_sfc(lines1),
) %>%
st_as_sf %>% # then make the whole thing an sf object
# use st_intersection to find the point of intersection
st_intersection %>%
# then keep only the 'point' (exclude the original 'lines')
filter(
st_is(geom, 'POINT')
) %>%
{. ->> intersection_point} %>%
ggplot()+
geom_sf(colour = 'red', size = 5)+
geom_contour(data = hyp_data, aes(x, y, z = z1), breaks = 0, colour = 1)+
geom_contour(data = hyp_data, aes(x, y, z = z2), breaks = 0, colour = 2)+
geom_point(data = sample_points, aes(x, y, colour = name), size = 3)
此方法的局限性在于它依赖于ggplot 的geom_contour 可视化轮廓线的能力。当r 的绝对值接近两点之间的距离(a-b 之间的距离 = 50)时,双曲线变窄并最终变为“在”其中一个点“后面”的直线。这里geom_contour无法建立等高线,因此没有创建线数据,所以找不到交点。看看下面的图应该有 6 行时如何只有 5 行; z6 不绘图并导致警告消息:
expand.grid(
x = seq(0, 100, length = 100),
y = seq(0, 100, length = 100)
) %>%
as_tibble %>%
mutate(
# z = f1(x, y, nr)
z1 = f1(xi = 25, yi = 25, xj = 75, yj = 25, x, y, r = 5),
z2 = f1(xi = 25, yi = 25, xj = 75, yj = 25, x, y, r = 15),
z3 = f1(xi = 25, yi = 25, xj = 75, yj = 25, x, y, r = 25),
z4 = f1(xi = 25, yi = 25, xj = 75, yj = 25, x, y, r = 35),
z5 = f1(xi = 25, yi = 25, xj = 75, yj = 25, x, y, r = 45),
z6 = f1(xi = 25, yi = 25, xj = 75, yj = 25, x, y, r = 50),
) %>%
ggplot()+
geom_contour(aes(x, y, z = z1), breaks = 0, colour = 1)+
geom_contour(aes(x, y, z = z2), breaks = 0, colour = 2)+
geom_contour(aes(x, y, z = z3), breaks = 0, colour = 3)+
geom_contour(aes(x, y, z = z4), breaks = 0, colour = 4)+
geom_contour(aes(x, y, z = z5), breaks = 0, colour = 5)+
geom_contour(aes(x, y, z = z6), breaks = 0, colour = 6)+
geom_point(data = sample_points, aes(x, y, color = name), size = 3)+
coord_sf()
# Warning messages:
# 1: stat_contour(): Zero contours were generated
# 2: In min(x) : no non-missing arguments to min; returning Inf
# 3: In max(x) : no non-missing arguments to max; returning -Inf
我已经开发了在无法生成等高线时创建这些直线的方法,但我希望能够使用“数学/代数”方法来找到两条线的交点,而不是依赖于 R 中的空间/映射/计数方法。
我已经探索了使用诸如uniroot() 和solve() 之类的函数的选项,但收效甚微,这可能是由于我对基础数学的理解有限和/或描述双曲线的方程同时具有@987654368 @ 和 y 条款?
我目前的想法是写一对等式,右边相等为 0(为不正确的数学语言道歉?):
(或三个方程式):
其中(xi, yi)、(xj, yj)和(xk, yk)是三个焦点(i、j和k)的坐标,r是距离差。 xi, yi, xj, yj, xk, yk可以代替上例中点a, b, c的坐标
然后,我认为应该可以使用与此处描述的过程类似的过程来解方程 https://www.wikihow.com/Algebraically-Find-the-Intersection-of-Two-Lines,但我不知道这如何转化为 R 代码和/或现有的R 函数。
这样做的目的是根据接收天线 (foci) 接收到的传输的到达时间差 (TDOA) 和双曲线定位原理来确定发射器的位置(交叉点),以及三边测量/多边测量(类似于 GPS 的工作方式)。
我将处理成千上万对双曲线,因此理想情况下,此过程相对较快且可由普通计算机管理。此外,不是必要的,但希望可以实现是在相同传输被超过三个站(例如,使用 GPS 时的“卫星数量”)。
我非常感谢任何人可以提供的任何想法或帮助,因为我一直在思考并努力解决这个问题已经有一段时间了。谢谢。
【问题讨论】:
-
this 有帮助吗?
-
谢谢@Limey!那篇文章确实有帮助。旋转是我见过的,但没有尝试过。看起来文章中的方程式应该能够完成这项工作,我会看看我能用它们做什么。
-
@Limey,我正在研究附件中的示例,但无法得出与示例相同的结果,特别是 r 的值(Eq A.23 )。你有这个例子的经验或自己做这个吗?
标签: r line-intersection