Jede Ebene liegt als Koeffizientenvektor (a, b, c, d) vor, d.h. ax1 + bx2 + c*x3 = d. Der Abstand von A zur Ebene ist
d(A,E) = |ax1 + bx2 + c*x3 - d| / sqrt(a^2 + b^2 + c^2)
A <- c(3, 5, -1)
ebenen <- list(
a = list(coef = c(2, -3, 1, 5), titel = "a) 2x1 - 3x2 + x3 = 5"),
b = list(coef = c(1, 1, 7, 1), titel = "b) x1 + x2 + 7x3 = 1"),
c = list(coef = c(3, -1, 4, 0), titel = "c) 3x1 - x2 + 4x3 = 0")
)
# Hilfsfunktion: Punkt auf Ebene. 'row' = c(s, t) aus apply()
punkt_auf_ebene <- function(row, coef) {
s <- row[1]; t <- row[2]
a <- coef[1]; b <- coef[2]; c <- coef[3]; d <- coef[4]
# nach x1 aufloesen (falls a != 0), sonst nach x2
if (abs(a) > 1e-9) {
x1 <- (d - b*s - c*t) / a
c(x1, s, t)
} else {
x2 <- (d - a*s - c*t) / b
c(s, x2, t)
}
}
# Abstand A -> Ebene
abstand <- function(coef) {
a <- coef[1]; b <- coef[2]; c <- coef[3]; d <- coef[4]
abs(a*A[1] + b*A[2] + c*A[3] - d) / sqrt(a^2 + b^2 + c^2)
}
Die Ebene wird als Flaeche (Patch) gezeichnet. Der Fusspunkt des Lotes und die Lotstrecke machen den Abstand sichtbar. Liegt A auf der Ebene (Abstand ~ 0), ist der Punkt gruen, sonst rot.
plot_ebene <- function(e) {
coef <- e$coef
s <- seq(-4, 4, length.out = 25)
t <- seq(-4, 4, length.out = 25)
grid <- expand.grid(s = s, t = t)
pts <- t(apply(grid, 1, punkt_auf_ebene, coef = coef))
plane <- plot_ly(type = "mesh3d",
x = pts[,1], y = pts[,2], z = pts[,3],
opacity = 0.35, color = "#3b82f6",
showscale = FALSE, name = "Ebene E")
dist <- abstand(coef)
liegt <- dist < 1e-6
farbe <- ifelse(liegt, "#16a34a", "#dc2626")
# Fusspunkt des Lotes: A - vorz * dist * normalisierte Normale (zur Ebene hin)
n <- coef[1:3] / sqrt(sum(coef[1:3]^2))
vorz <- sign(coef[1]*A[1] + coef[2]*A[2] + coef[3]*A[3] - coef[4])
fuss <- A - vorz * dist * n
p <- plot_ly(type = "scatter3d", mode = "markers",
x = A[1], y = A[2], z = A[3],
marker = list(size = 8, color = farbe),
name = "A(3|5|-1)")
if (liegt) {
fig <- plane %>% add_trace(p)
} else {
fig <- plane %>%
add_trace(p) %>%
add_trace(type = "scatter3d", mode = "lines",
x = c(A[1], fuss[1]), y = c(A[2], fuss[2]), z = c(A[3], fuss[3]),
line = list(color = "#f59e0b", width = 6), name = "Lot") %>%
add_trace(type = "scatter3d", mode = "markers",
x = fuss[1], y = fuss[2], z = fuss[3],
marker = list(size = 5, color = "#f59e0b"), name = "Fusspunkt")
}
fig <- layout(
fig,
title = sprintf("%s\nAbstand A zur Ebene: %.3f", e$titel, dist),
scene = list(xaxis = list(title = "x1"),
yaxis = list(title = "x2"),
zaxis = list(title = "x3"))
)
fig
}
for (e in ebenen) print(plot_ebene(e))
df <- data.frame(
Aufgabe = c("a)", "b)", "c)"),
Gleichung = c("2x1-3x2+x3=5", "x1+x2+7x3=1", "3x1-x2+4x3=0"),
Punktprobe = c("6-15-1 = -10", "3+5-7 = 1", "9-5-4 = 0"),
Ergebnis = c("nicht in E", "in E", "in E"),
Abstand = round(sapply(ebenen, function(e) abstand(e$coef)), 3)
)
knitr::kable(df, caption = "Punktprobe und Abstand von A(3|5|-1)")
| Aufgabe | Gleichung | Punktprobe | Ergebnis | Abstand | |
|---|---|---|---|---|---|
| a | a) | 2x1-3x2+x3=5 | 6-15-1 = -10 | nicht in E | 4.009 |
| b | b) | x1+x2+7x3=1 | 3+5-7 = 1 | in E | 0.000 |
| c | c) | 3x1-x2+4x3=0 | 9-5-4 = 0 | in E | 0.000 |