这是一个简短的代码片段,只要叉积有意义就可以使用:3D 版本返回一个向量,2D 版本返回一个标量。如果您只想要简单的代码来给出正确的答案而不需要引入外部库,那么这就是您所需要的。
# Compute the vector cross product between x and y, and return the components
# indexed by i.
CrossProduct3D <- function(x, y, i=1:3) {
# Project inputs into 3D, since the cross product only makes sense in 3D.
To3D <- function(x) head(c(x, rep(0, 3)), 3)
x <- To3D(x)
y <- To3D(y)
# Indices should be treated cyclically (i.e., index 4 is "really" index 1, and
# so on). Index3D() lets us do that using R's convention of 1-based (rather
# than 0-based) arrays.
Index3D <- function(i) (i - 1) %% 3 + 1
# The i'th component of the cross product is:
# (x[i + 1] * y[i + 2]) - (x[i + 2] * y[i + 1])
# as long as we treat the indices cyclically.
return (x[Index3D(i + 1)] * y[Index3D(i + 2)] -
x[Index3D(i + 2)] * y[Index3D(i + 1)])
}
CrossProduct2D <- function(x, y) CrossProduct3D(x, y, i=3)
它有效吗?
让我们看看我在网上找到的一个随机示例:
> CrossProduct3D(c(3, -3, 1), c(4, 9, 2)) == c(-15, -2, 39)
[1] TRUE TRUE TRUE
看起来还不错!
为什么这比以前的答案更好?
- 它是 3D 的(Carl 的只有 2D)。
- 它简单而惯用。
- 很好的评论和格式化;因此,易于理解
缺点是数字“3”被硬编码了好几次。实际上,这并不是一件坏事,因为它突出了向量叉积纯粹是一个 3D 构造的事实。就个人而言,我建议完全放弃交叉产品并学习几何代数。:)