Maxima-Paket: Vektorrechnung und Analytische Geometrie (Dimension 3)

Version 27.11.2018, Walter Fendt

Unterdrückung von Warnmeldungen bei linsolve

linsolvewarn: false$

Reihenfolge der Variablen

ordergreat(x,y,z)$

Spaltenvektor

Vektor(v) := matrix([v[1]],[v[2]],[v[3]])$

Betrag eines Vektors

Betrag(v) := sqrt(v.v)$

Kreuzprodukt zweier Vektoren

Kreuzprodukt(v1,v2) :=
  [v1[2]*v2[3]-v1[3]*v2[2],
   v1[3]*v2[1]-v1[1]*v2[3],
   v1[1]*v2[2]-v1[2]*v2[1]]$

Überprüfung: Sind zwei Vektoren linear abhängig?

linearAbhaengig2(v1,v2) := is(Kreuzprodukt(v1,v2)=[0,0,0])$

Überprüfung: Sind zwei Vektoren linear unabhängig?

linearUnabhaengig2(v1,v2) := not linearAbhaengig2(v1,v2)$

Überprüfung: Sind drei Vektoren linear abhängig?

linearAbhaengig3(v1,v2,v3) := is(determinant(matrix(v1,v2,v3))=0)$

Überprüfung: Sind drei Vektoren linear unabhängig?

linearUnabhaengig3(v1,v2,v3) := not linearAbhaengig3(v1,v2,v3)$

Winkel zwischen zwei Vektoren (Bogenmaß, 0 bis pi)

Winkel(v1,v2) := acos(float(v1.v2/(Betrag(v1)*Betrag(v2))))$

Optimierung eines Richtungsvektors

Optimierung(v) := block(
  [f,w],
  f: lcm(denom(v[1]),denom(v[2]),denom(v[3])),
  w: f*v,
  f: gcd(gcd(w[1],w[2]),w[3]),
  w: (1/f)*w,
  if w[1]<0 and w[2]<0 and w[3]<0 then return(-w),
  if w[1]<0 and w[2]<0 then return(-w),
  if w[1]<0 and w[3]<0 then return(-w),
  if w[2]<0 and w[3]<0 then return(-w),
  if w[1]<0 and w[2]=0 and w[3]=0 then return(-w),
  if w[1]=0 and w[2]<0 and w[3]=0 then return(-w),
  if w[1]=0 and w[2]=0 and w[3]<0 then return(-w),
  w
  )$

Spiegelpunkt bei Punktspiegelung

SpiegelpunktPP(z,p) := 2*z-p$

Optimierung einer Geradengleichung (Richtungsvektor)

OptimierungG(g) := [g[1],Optimierung(g[2])]$

Ausgabe einer Parametergleichung einer Geraden

AusgabeG(g,par) := block(
  simp: false,
  print("X = ",Vektor(g[1])+par*Vektor(g[2])),
  simp: true,
  ""
  )$

Gerade durch zwei Punkte

GeradePP(p1,p2) := [p1,p2-p1]$

Überprüfung: Liegt Punkt auf Gerade?

enthaltenPG(p,g) := linearAbhaengig2(p-g[1],g[2])$

Überprüfung: Sind zwei Geraden parallel?

parallelGG(g1,g2) := linearAbhaengig2(g1[2],g2[2])$

Überprüfung: Sind zwei Geraden gleich?

gleichGG(g1,g2) := block(
  if not parallelGG(g1,g2) then return(false),
  enthaltenPG(g2[1],g1)
  )$

Überprüfung: Schneiden sich zwei Geraden?

schneidendGG(g1,g2) := block(
  if parallelGG(g1,g2) then return(false),
  linearAbhaengig3(g1[2],g2[2],g2[1]-g1[1])
  )$

Überprüfung: Sind zwei Geraden windschief?

windschiefGG(g1,g2) := not linearAbhaengig3(g1[2],g2[2],g2[1]-g1[1])$

Überprüfung: Schneiden sich zwei Geraden senkrecht?

senkrechtGG(g1,g2) := block(
  if not schneidendGG(g1,g2) then return(false),
  is(g1[2].g2[2]=0)
  )$

Lagebeziehung zweier Geraden

LageGG(g1,g2) := block(
  if gleichGG(g1,g2) then return("Geraden gleich"),
  if parallelGG(g1,g2) then return("Geraden parallel, aber nicht gleich"),
  if senkrechtGG(g1,g2) then return("Geraden schneiden sich senkrecht"),
  if schneidendGG(g1,g2) then return("Geraden schneiden sich"),
  "Geraden windschief"
  )$

Umwandlung einer Vektorgleichung in ein Gleichungssystem

Gleichungssystem(vg) := block(
  [ls,rs],
  ls: lhs(vg),
  rs: rhs(vg),
  [ls[1]=rs[1],ls[2]=rs[2],ls[3]=rs[3]]
  )$

Schnittpunkt zweier Geraden

SchnittpunktGG(g1,g2) := block(
  [vg,a,b,lsg],
  if gleichGG(g1,g2) then return("Geraden gleich!"),
  if parallelGG(g1,g2) then return("Geraden parallel!"),
  if windschiefGG(g1,g2) then return("Geraden windschief!"),
  vg: g1[1]+a*g1[2]=g2[1]+b*g2[2],
  lsg: linsolve(Gleichungssystem(vg),[a,b]),
  g1[1]+rhs(lsg[1])*g1[2]
  )$

Parallele zu Gerade durch Punkt

ParalleleGP(g,p) := [p,g[2]]$

Fußpunkt des Lotes zu Gerade durch Punkt (senkrechte Projektion von Punkt auf Gerade)

FusspunktGP(g,p) := block(
  [par],
  par: (g[2].(p-g[1]))/(g[2].g[2]),
  g[1]+par*g[2]
  )$

Lot zu Gerade durch Punkt

LotGP(g,p) := block(
  if enthaltenPG(p,g) then 
    return("Lot nicht eindeutig definiert!"),
  OptimierungG(GeradePP(p,FusspunktGP(g,p)))
  )$

Spiegelpunkt bei Achsenspiegelung

SpiegelpunktGP(a,p) := 2*FusspunktGP(a,p)-p$

Optimierung einer Ebenengleichung (Richtungsvektoren)

OptimierungE(e) := [e[1],Optimierung(e[2]),Optimierung(e[3])]$

Ausgabe einer Ebenengleichung (Parametergleichung)

AusgabeE(e,par1,par2) := block(
  simp: false,
  print("X = ",Vektor(e[1])+par1*Vektor(e[2])+par2*Vektor(e[3])),
  simp: true,
  ""
  )$

Ebene durch drei Punkte

EbenePPP(p1,p2,p3) := [p1,p2-p1,p3-p1]$

Ebene mit gegebener Normalenform

EbeneNF(nf) := block(
  [ls,n1,n2,n3,n0,e],
  ls: expand(lhs(nf)-rhs(nf)),
  n1: coeff(ls,x),
  n2: coeff(ls,y),
  n3: coeff(ls,z),
  n0: ls-n1*x-n2*y-n3*z,
  if n1#0 then e: [[-n0/n1,0,0]]
  else if n2#0 then e: [[0,-n0/n2,0]]
  else e: [[0,0,-n0/n3]],
  if n2#0 or n3#0 then e: append(e,[[0,n3,-n2]]),
  if n1#0 or n3#0 then e: append(e,[[-n3,0,n1]]),
  if length(e)<3 then e: append(e,[[n2,-n1,0]]),
  OptimierungE(e)
  )$

Normalenvektor einer Ebene

NormalenvektorE(e) := Optimierung(Kreuzprodukt(e[2],e[3]))$

Normalenform einer Ebene

NormalenformE(e) := block(
  [n],
  n: NormalenvektorE(e),
  expand(n.([x,y,z]-e[1]))=0
  )$

Überprüfung: Liegt Punkt in Ebene?

enthaltenPE(p,e) := linearAbhaengig3(p-e[1],e[2],e[3])$

Überprüfung: Ist Gerade parallel zu Ebene?

parallelGE(g,e) := linearAbhaengig3(g[2],e[2],e[3])$

Überprüfung: Liegt Gerade in Ebene?

enthaltenGE(g,e) := block(
  if not parallelGE(g,e) then return(false),
  enthaltenPE(g[1],e)
  )$

Überprüfung: Schneidet Gerade Ebene?

schneidendGE(g,e) := not parallelGE(g,e)$

Überprüfung: Schneidet Gerade Ebene senkrecht?

senkrechtGE(g,e) := linearAbhaengig2(g[2],NormalenvektorE(e))$

Lagebeziehung einer Geraden zu einer Ebene

LageGE(g,e) := block(
  if enthaltenGE(g,e) then return("Gerade liegt in Ebene"),
  if parallelGE(g,e) then return("Gerade parallel zur Ebene, aber außerhalb"), 
  if senkrechtGE(g,e) then return("Gerade schneidet Ebene senkrecht"),
  "Gerade schneidet Ebene"
  )$

Schnittpunkt einer Geraden und einer Ebene

SchnittpunktGE(g,e) := block(
  [vg,a,b,c,lsg],
  if enthaltenGE(g,e) then return("Gerade in Ebene!"),
  if parallelGE(g,e) then return("Gerade parallel zur Ebene!"),
  vg: g[1]+a*g[2]=e[1]+b*e[2]+c*e[3],
  lsg: linsolve(Gleichungssystem(vg),[a,b,c]),
  g[1]+rhs(lsg[1])*g[2]
  )$

Überprüfung: Sind zwei Ebenen parallel?

parallelEE(e1,e2) := block(
  [n1,n2],
  n1: NormalenvektorE(e1),
  n2: NormalenvektorE(e2),
  linearAbhaengig2(n1,n2)
  )$

Überprüfung: Sind zwei Ebenen gleich?

gleichEE(e1,e2) := block(
  if not parallelEE(e1,e2) then return(false),
  enthaltenPE(e1[1],e2)
  )$

Überprüfung: Schneiden sich zwei Ebenen?

schneidendEE(e1,e2) := not parallelEE(e1,e2)$

Überprüfung: Schneiden sich zwei Ebenen senkrecht?

senkrechtEE(e1,e2) := is(NormalenvektorE(e1).NormalenvektorE(e2)=0)$

Lagebeziehung zweier Ebenen

LageEE(e1,e2) := block(
  if gleichEE(e1,e2) then return("Ebenen gleich!"),
  if parallelEE(e1,e2) then return("Ebenen parallel, aber nicht gleich"),
  if senkrechtEE(e1,e2) then return("Ebenen schneiden sich senkrecht"),
  "Ebenen schneiden sich"
  )$

Schnittgerade zweier Ebenen

SchnittgeradeEE(e1,e2) := block(
  [n2,c0,c1,c2,gl,a,b,lsg,g],
  if gleichEE(e1,e2) then return("Ebenen gleich!"),
  if parallelEE(e1,e2) then return("Ebenen parallel!"),
  n2: NormalenvektorE(e2),
  c0: n2.(e1[1]-e2[1]),
  c1: n2.e1[2],
  c2: n2.e1[3],
  gl: c0+c1*a+c2*b=0,
  lsg: solve(gl,b),
  g: expand(e1[1]+a*e1[2]+rhs(lsg[1])*e1[3]),
  [coeff(g,a,0),Optimierung(coeff(g,a))]
  )$

Parallelebene zu Ebene durch Punkt

ParallelebeneEP(e,p) := [p,e[2],e[3]]$

Fußpunkt des Lotes zu Ebene durch Punkt

FusspunktEP(e,p) := block(
  [n,par],
  n: NormalenvektorE(e),
  par: (n.(e[1]-p))/(n.n),
  p[1]+par*n
  )$

Lot zu Ebene durch Punkt

LotEP(e,p) := [p,NormalenvektorE(e)]$

Spiegelpunkt bei Ebenenspiegelung

SpiegelpunktEP(e,p) := 2*FusspunktEP(e,p)-p$

Lotebene zu Gerade durch Punkt

LotebeneGP(g,p) := EbeneNF(g[2].([x,y,z]-p)=0)$

Abstand zweier Punkte

AbstandPP(p1,p2) := Betrag(p2-p1)$

Abstand zwischen Punkt und Gerade

AbstandPG(p,g) := Betrag(p-FusspunktGP(g,p))$

Abstand zwischen Punkt und Ebene

AbstandPE(p,e) := block(
  [n],
  n: NormalenvektorE(e),
  abs(n.(p-e[1])/Betrag(n))
  )$

Abstand zweier Geraden

AbstandGG(g1,g2) := block(
  [e],
  if parallelGG(g1,g2) then return(AbstandPG(g1[1],g2)),
  e: [g1[1],g1[2],g2[2]],
  AbstandPE(g2[1],e)
  )$

Abstand zwischen Gerade und Ebene

AbstandGE(g,e) := block(
  if not parallelGE(g,e) then return(0),
  AbstandPE(g[1],e)
  )$

Abstand zweier Ebenen

AbstandEE(e1,e2) := block(
  if not parallelEE(e1,e2) then return(0),
  AbstandPE(e1[1],e2)
  )$

Winkel zwischen zwei Geraden (Bogenmaß)

WinkelGG(g1,g2) := block(
  [w],
  if gleichGG(g1,g2) then return(0),
  if not schneidendGG(g1,g2) then return("Geraden schneiden sich nicht!"),
  w: Winkel(g1[2],g2[2]),
  min(w,float(%pi)-w)
  )$

Winkel zwischen zwei Geraden (Gradmaß)

WinkelGG_Grad(g1,g2) := block(
  [w],
  w: WinkelGG(g1,g2),
  if not floatnump(w) then return(w),
  float(w*180/%pi)
  )$

Winkel zwischen Gerade und Ebene (Bogenmaß)

WinkelGE(g,e) := block(
  [n,w],
  if enthaltenGE(g,e) then return(0),
  if parallelGE(g,e) then return("Gerade schneidet Ebene nicht!"),
  n: NormalenvektorE(e),
  w: Winkel(g[2],n),
  w: min(w,float(%pi)-w),
  float(%pi/2-w)
  )$

Winkel zwischen Gerade und Ebene (Gradmaß)

WinkelGE_Grad(g,e) := block(
  [w],
  w: WinkelGE(g,e),
  if not floatnump(w) then return(w),
  float(w*180/%pi)
  )$

Winkel zwischen zwei Ebenen (Bogenmaß)

WinkelEE(e1,e2) := block(
  [n1,n2,w],
  if gleichEE(e1,e2) then return(0),
  if parallelEE(e1,e2) then return("Ebenen schneiden sich nicht!"),
  n1: NormalenvektorE(e1),
  n2: NormalenvektorE(e2),
  w: Winkel(n1,n2),
  min(w,float(%pi)-w)
  )$

Winkel zwischen zwei Ebenen (Gradmaß)

WinkelEE_Grad(e1,e2) := block(
  [w],
  w: WinkelEE(e1,e2),
  if not floatnump(w) then return(w),
  float(w*180/%pi)
  )$

Flächeninhalt eines Dreiecks

FlaecheDreieckPPP(p1,p2,p3) := block(
  [kp],
  kp: Kreuzprodukt(p2-p1,p3-p1),
  Betrag(kp)/2
  )$

Volumen eines Tetraeders

VolumenTetraederPPPP(p1,p2,p3,p4) := block(
  [kp,sp],
  kp: Kreuzprodukt(p2-p1,p3-p1),
  sp: kp.(p4-p1),
  abs(sp)/6
  )$

Definitionen speichern

save("anageo3d",all);