rgl vector diagrams: show right angles for orthogo

2019-02-22 08:52发布

问题:

In the matlib package, https://github.com/friendly/matlib/, I have a function, vectors3d() to draw geometric vector diagrams.

The following code gives an example figure showing a unit vector "J" and some of its projections on the X, Y, Z axes. In the calls to segments3d, each argument is a 2 x 3 matrix giving start/end coordinates.

if (!require(matlib)) devtools::install_github(friendly/matlib)
library(matlib)
library(rgl)

vec <- rbind(diag(3), c(1,1,1))
rownames(vec) <- c("X", "Y", "Z", "J")
open3d()
vectors3d(vec, col=c(rep("black",3), "red"), lwd=2)
# draw the XZ plane, whose equation is Z=0
planes3d(0, 0, 1, 0, col="gray", alpha=0.2)
# show projections of the unit vector J
segments3d(v1 <- rbind( c(1,1,1), c(1, 1, 0)))
segments3d(v2 <- rbind( c(0,0,0), c(1, 1, 0)))
segments3d(v3 <- rbind( c(1,0,0), c(1, 1, 0)))
segments3d(v4 <- rbind( c(0,1,0), c(1, 1, 0)))

I want to add to this the right angle lines, like |_ to show that pairs of vectors that I plot using segments3d are orthogonal. I've drawn these in by hand in the following figure. But I don't know how to compute the small line segments needed for a given pair of vectors in this form, say, v1 and v2. I'm willing to assume that each length of the |_ segments is a small number, like 0.05.

EDIT: The problem reduces to the following: Given three points, p1, p2, p3, find the points labeled p21, p23, and p123 in the diagram below. The first two are simple examples of finding a point along a line between two points, but I'm stumped on finding the coordinates of the third point, p123, that is the position of a point a distance d along a line parallel to the line p2->p3 starting at p21.

In R, what I have so far is

#' Find position of a point along a line from x1 to x2
point_on_line <- function(x1, x2, d, absolute=TRUE) {
    v <- x2 - x1
    if (!absolute) v <- v / len(v)
    x1 + d * v
}

p1 <- c(0,0,0)
p2 <- c(1,1,0)
p3 <- c(1,1,1)

(p21 <- point_on_line(p2, p1, .10))
(p23 <- point_on_line(p2, p3, .10))
points3d(rbind(p21, p23), size=10, col="red")

This gives me the following diagram. Can someone help me complete it?