问题描述
我正在研究我的硕士论文,以模拟来自Lidar-Data的半球照片。因此,我的主要目标是将笛卡尔坐标系中的3D点(X,Y,Z)投影到立体投影中(请参见图1,here)。我的Pointcloud的坐标系进行了转换,以使中心点位于(0,0),并且所有z值均为正。
我正在RStudio中进行编码,我首先尝试使用wikipedia中列出的笛卡尔坐标到球形坐标的公式来实现Pointcloud的球形投影。
r <- sqrt(x^2 + y^2 + z^2)
theta <- acos(z/r)
phi <- atan2(y,x)
我还尝试使用RPackage实用程序中的cart2sph函数来执行此操作,该功能应该也是如此。但是不幸的是,这两种方法的结果看起来都不像我想要的那样。这些点不适合在平面半球上,而似乎沿z轴定向(参见图2)。
有没有人建议如何在RStudio中实现Lidar Pointcloud的立体投影?甚至有一个带有某些功能的软件包都可以进行坐标转换吗?不幸的是,我没有太多的编码经验,我将非常感谢您提供的所有帮助。
修改
我使用Allans脚本在半球上绘制笛卡尔点。使用软件Cloudcompare的结果如下所示:
图片: Hemisphere
我还使用转换后的笛卡尔坐标进行了立体投影:
x2 <- (x / (1 + z))
y2 <- (y / (1 + z))
project_2d <- data.frame(x2,y2)
我仍然想知道为什么图的外边缘不适合一个完美的圆,因为所有的树干都具有相同的min(z)值(我使用了剪切框)。因此,所有树干都应在半球的“赤道”上对齐。你有什么线索吗?
解决方法
很难以3D形式显示此结果,但我会尽力而为。
假设我们有一个十字形的点悬挂在相机上,平行于地面:
x <- c(rep(seq(-10,10,1),2),rep(-1,21),rep(1,21))
y <- c(rep(-1,rep(seq(-10,2))
z <- rep(3,84)
我们可以尝试在rgl
中显示它,并添加一个红点以指示相机位置:
library(rgl)
plot3d(x,y,z,zlim = c(0,10))
points3d(0,col = "red")
使用您发现的转换为球坐标的公式,我们可以将这些3D点从x,y,z转换为theta,phi和r。但是,要将它们投影到笛卡尔坐标的半球上,我们需要使r与相机保持固定距离。然后,我们需要根据theta,phi和固定r来计算该半球上的点的x,y,z坐标。该函数应该这样做:
projection <- function(x,z) {
r <- sqrt(x^2 + y^2 + z^2)
theta <- acos(z / r)
phi <- atan2(y,x)
y <- theta * cos(phi)
x <- theta * sin(phi)
z <- sqrt((pi / 2)^2 - x^2 - y^2)
data.frame(x,z)
}
现在,当我们这样做时:
df <- projection(x,z)
我们可以再次绘图以显示投影到半球上的点:
plot3d(df$x,df$y,df$z,pi))
从下面查看
从侧面查看