frequently ask ? : Science : Physics : Mechanics : Dynamics : 3D

+ Search
Add Entry AlertManage Folder Edit Entry Add page to http://del.icio.us/
Did You Find This Entry Useful?

Entry

Physics:Dynamics:3D:Rotation:Can you give BBCBASIC program to get principal axes:Mass:Point:Discrete

Jan 28th, 2006 20:50
Knud van Eeden,


----------------------------------------------------------------------
--- Knud van Eeden --- 29 January 2021 - 02:22 am --------------------
Physics:Dynamics:3D:Rotation:Can you give BBCBASIC program to get 
principal axes:Mass:Point:Discrete
Overview
->-[DATA]->[inertia array]->[eigenvalues]->-[eigenvectors]->-[axes]->-
===
Steps: Overview:
 1. -Input data
     1. mass
     2. distance mass to the x-axis
     3. distance mass to the y-axis
     4. distance mass to the z-axis
        1. -E.g.
            1. -Mass of 1 unit at
                x distance 2
                y distance -1
                z distance -2
            2. -Mass of 2 units at
                x distance 2
                y distance 1/2
                z distance 1/2
            3. -Mass of 3 units at
                x distance -3
                y distance 1
                z distance 1
 2. -Get the given data and put it in the DATA statements
     1. -For first to last mass
         1. -Put mass in DATA statement in DATA
         2. -Put distance mass to x-axis in DATA
         3. -Put distance mass to y-axis in DATA
         4. -Put distance mass to z-axis in DATA
     2. -Next mass
         1. -E.g.
             First the masses
             DATA 1
             DATA 2
             DATA 3
             :
             Then their x, y, z distance respectively
             DATA  2,   -1,  -2
             DATA  2, 1/2,  1/2
             DATA -3,   1,    1
 3. -Get the given data and put it in array
     1. -For first to last mass
         1. -Get mass from DATA statement in array
         2. -Get distance mass to x-axis, from DATA statement, in array
         3. -Get distance mass to y-axis, from DATA statement, in array
         4. -Get distance mass to z-axis, from DATA statement, in array
     2. -Next mass
 4. -Calculate the moments and products of inertia
     1. -For first to last mass
         1. -Calculate Ixx = sum of ( mass . x . x )
         2. -Calculate Ixy = sum of ( mass . x . y )
         3. -Calculate Ixz = sum of ( mass . x . z )
         4. -Calculate Iyx = sum of ( mass . y . x )
         5. -Calculate Iyy = sum of ( mass . y . y )
         6. -Calculate Iyz = sum of ( mass . y . z )
         7. -Calculate Izx = sum of ( mass . z . x )
         8. -Calculate Izy = sum of ( mass . z . y )
         9. -Calculate Izz = sum of ( mass . z . z )
     2. -Next mass
 5. -Put this moments and products of inertia in a 3 x 3 matrix
       [  Ixx  -Ixy  -Ixz  ]
       [                   ]
       [ -Iyx   Iyy  -Iyz  ]
       [                   ]
       [ -Izx  -Izy   Izz  ]
     1. -E.g.
       [  39    9     11   ]
       [                   ]
       [   9    4.5   -5.5 ]
       [                   ]
       [  11   -5.5    7.5 ]
 6. -Calculate the eigenvalues and eigenvectors of this 3 x 3 matrix
     1. -Calculate the 3 eigenvalues by solving for the zeroes
         of a 3rd degree cubic polynomial
         (similar to solving an equation like this)
         1 . x^3 - 51 . x^2 + 269.5 . x + 2104.5 = 0
     2. -Calculate the 3 eigenvectors, by solving 2 linear
         equations in 2 unknowns
         (similar to solving an equation like this)
          3 . x + 5 . y = 8
          4 . x + 2 . y = 6
 7. -This found 3 eigenvectors form the principal axes
     1. -This 3 eigenvectors are orthogonal to each other (and thus
         linear independent), distinct and real
===
--- cut here: begin --------------------------------------------------
REM --- MAIN --- REM
printB% = TRUE
dimB% = TRUE
*SPOOL c:\temp\ddd.ddd
PROCPhysicsCalculateRotation( 3, 3, 3, 3, 3, 3, 10, 10, TRUE, TRUE )
REM
REM if you run this program it will show
REM
REM 1*2*2
REM 2*2*2
REM 3*-3*-3
REM inertiaSumR ( 1,1) = 39
REM 1*2*-1
REM 2*2*0.5
REM 3*-3*1
REM inertiaSumR ( 2,1) = -9
REM 1*2*-2
REM 2*2*0.5
REM 3*-3*1
REM inertiaSumR ( 3,1) = -11
REM 1*-1*2
REM 2*0.5*2
REM 3*1*-3
REM 1*-1*-1
REM 2*0.5*0.5
REM 3*1*1
REM inertiaSumR ( 2,2) = 4.5
REM 1*-1*-2
REM 2*0.5*0.5
REM 3*1*1
REM inertiaSumR ( 3,2) = 5.5
REM 1*-2*2
REM 2*0.5*2
REM 3*1*-3
REM 1*-2*-1
REM 2*0.5*0.5
REM 3*1*1
REM 1*-2*-2
REM 2*0.5*0.5
REM 3*1*1
REM inertiaSumR ( 3,3) = 7.5
REM
REM [                 39         9        11]
REM [                  9       4.5      -5.5]
REM [                 11      -5.5       7.5]
REM 
REM  ( 1 ) . x^3 + ( -51 ) . x^2 + ( 269.5 ) . x + ( 2104.5 ) = 0
REM
REM solution: 3 roots:
REM
REM 3 real unequal roots
REM
REM real1 = -4.19849745
REM imag1 = 0
REM real2 = 43.7382629
REM imag2 = 0
REM real3 = 11.4602345
REM imag3 = 0
REM
REM
REM result of filling in root1 in given equation gives: -9.53674317E-7
REM
REM result of filling in root2 in given equation gives: 7.62939453E-6
REM
REM result of filling in root3 in given equation gives: 0
REM
REM -----------------------------
REM normalized eigenvector = 0.308651776 -0.715574822 -0.626647233
REM normalized eigenvector = 0.948377638 0.181027113 0.26040169
REM normalized eigenvector = 0.0728967611 0.674671674 -0.734509493
REM
REM 1 -2.3183888 -2.03027257 1 0.190880832 0.274575949 1 9.25516667 -
10.0760237
REM
a11 = inertiaTensorAR( 1, 1 )
a12 = inertiaTensorAR( 1, 2 )
a13 = inertiaTensorAR( 1, 3 )
a21 = inertiaTensorAR( 2, 1 )
a22 = inertiaTensorAR( 2, 2 )
a23 = inertiaTensorAR( 2, 3 )
a31 = inertiaTensorAR( 3, 1 )
a32 = inertiaTensorAR( 3, 2 )
a33 = inertiaTensorAR( 3, 3 )
PRINT
PRINT "[", a11, a12, a13, "]"
PRINT "[", a21, a22, a23, "]"
PRINT "[", a31, a32, a33, "]"
PRINT FNStringGetPhysicsCalculateEigenvectorGivenMatrix3DS( a11, a12, 
a13, a21, a22, a23, a31, a32, a33, dimB%, printB% )
*SPOOL
END
:
:
:
REM library:
DEF PROCPhysicsCalculateRotation( rowMassMaxI%, columnMassMaxI%, 
rowInertiaTensorMaxI%, columnInertiaTensorMaxI%, 
dimRowInertiaTensorMaxAbsoluteI%, dimColumnInertiaTensorMaxAbsoluteI%, 
dimRowMassMaxAbsoluteI%, dimColumnMassMaxAbsoluteI%, dataB%, dimB% )
IF dimB% THEN PROCPhysicsCalculateRotationDim( 
dimRowMassMaxAbsoluteI%, dimColumnMassMaxAbsoluteI%, 
dimRowInertiaTensorMaxAbsoluteI%, dimColumnInertiaTensorMaxAbsoluteI% )
IF dataB% THEN PROCPhysicsCalculateRotationData( rowMassMaxI%, 
columnMassMaxI% )
PROCPhysicsCalculateRotationInertiaTensor( rowMassMaxI%, 
columnMassMaxI% )
ENDPROC
:
REM library:
DEF PROCPhysicsCalculateRotationDim( dimRowMassMaxAbsoluteI%, 
dimColumnMassMaxAbsoluteI%, dimRowInertiaTensorMaxAbsoluteI%, 
dimColumnInertiaTensorMaxAbsoluteI% )
DIM massValueAR( dimRowMassMaxAbsoluteI% )
DIM massRadiusAR( dimRowMassMaxAbsoluteI%, dimColumnMassMaxAbsoluteI% )
DIM inertiaTensorAR( dimRowInertiaTensorMaxAbsoluteI%, 
dimColumnInertiaTensorMaxAbsoluteI% )
ENDPROC
:
REM library:
DEF PROCPhysicsCalculateRotationData( rowMaxI%, columnMaxI% )
PROCPhysicsCalculateRotationDataReadMassValue( rowMaxI% )
PROCPhysicsCalculateRotationDataReadMassRadius( rowMaxI%, columnMaxI% )
ENDPROC
:
REM library:
DEF PROCPhysicsCalculateRotationDataReadMassValue( rowMaxI% )
LOCAL rowI%
LOCAL massR
rowMinI% = 1
FOR rowI% = rowMinI% TO rowMaxI%
  READ massR
  massValueAR( rowI% ) = massR
NEXT rowI%
ENDPROC
:
REM library:
DEF PROCPhysicsCalculateRotationDataReadMassRadius( rowMaxI%, 
columnMaxI% )
LOCAL rowI%
LOCAL columnI%
LOCAL rowMinI%
LOCAL columnMinI%
LOCAL radiusR
rowMinI% = 1
columnMinI% = 1
FOR rowI% = rowMinI% TO rowMaxI%
  FOR columnI% = columnMinI% TO columnMaxI%
    READ radiusR
    massRadiusAR( rowI%, columnI% ) = radiusR
  NEXT columnI%
NEXT rowI%
ENDPROC
:
REM library:
DEF PROCPhysicsCalculateRotationDataInitialize( dimRowMaxAbsoluteI%, 
dimColumnMaxAbsoluteI% )
DATA 1
DATA 2
DATA 3
:
DATA  2,   -1,  -2
DATA  2, 1/2,  1/2
DATA -3,   1,    1
ENDPROC
:
REM library:
DEF PROCPhysicsCalculateRotationInertiaTensor( rowMassMaxI%, 
columnMassMaxI% )
LOCAL rowMassI%
LOCAL columnMass1I%
LOCAL columnMass2I%
LOCAL rowMassMinI%
LOCAL columnMassMinI%
:
LOCAL inertiaSumR
:
rowMassMinI% = 1
columnMassMin1I% = 1
columnMassMin2I% = 1
:
FOR columnMass1I% = columnMassMin1I% TO columnMassMaxI%
  FOR columnMass2I% = columnMassMin1I% TO columnMassMaxI%
    inertiaSumR = 0
    FOR rowMassI% = rowMassMinI% TO rowMassMaxI%
      inertiaSumR = inertiaSumR + massValueAR( rowMassI% ) * 
massRadiusAR( rowMassI%, columnMass1I% ) * massRadiusAR( rowMassI%, 
columnMass2I% )
      PRINT; massValueAR( rowMassI% ); "*"; massRadiusAR( rowMassI%, 
columnMass1I% ); "*"; massRadiusAR( rowMassI%, columnMass2I% ) : 
REPEAT UNTIL GET
    NEXT rowMassI%
    IF ( columnMass1I% = columnMass2I% ) THEN inertiaTensorAR( 
columnMass1I%, columnMass2I% ) = inertiaSumR : PRINT "inertiaSumR ( "; 
columnMass1I%; ","; columnMass2I%; ") = "; inertiaSumR
    REM
    REM ---
    REM
    REM also store result in transpose symmetric position, because the 
inertia matrix is a symmetric matrix,
    REM so you only have to calculate the values in the upper diagonal,
    REM after you can stored it in the corresponding lower diagonal 
position
    REM
    IF ( columnMass1I% < columnMass2I% ) THEN inertiaTensorAR( 
columnMass1I%, columnMass2I% ) = -inertiaSumR : inertiaTensorAR( 
columnMass2I%, columnMass1I% ) = -inertiaSumR : PRINT "inertiaSumR 
( "; columnMass2I%; ","; columnMass1I%; ") = "; inertiaSumR
    REM
  NEXT columnMass2I%
NEXT columnMass1I%
ENDPROC
:
REM --- LIBRARY --- REM
:
REM library: string: get: physics: calculate: eigenvector: given: 
matrix3 [kn, ri, su, 22-01-2021 21:43:22]
DEF FNStringGetPhysicsCalculateEigenvectorGivenMatrix3DS( a11, a12, 
a13, a21, a22, a23, a31, a32, a33, dimB%, printB% )
REM e.g. printB% = TRUE
REM e.g. dimB% = TRUE
REM e.g. a11 = 1
REM e.g. a12 = 2
REM e.g. a13 = 3
REM e.g. a21 = 4
REM e.g. a22 = 5
REM e.g. a23 = 6
REM e.g. a31 = 7
REM e.g. a32 = 8
REM e.g. a33 = 9
REM e.g. PRINT FNStringGetPhysicsCalculateEigenvectorGivenMatrix3DS( 
a11, a12, a13, a21, a22, a23, a31, a32, a33, dimB%, printB% )
REM e.g. END
REM e.g. :
REM e.g. :
REM e.g. :
REM
REM
REM ---
REM
REM Running this example shows
REM
REM     [ 1  2  3 ]
REM     [         ]
REM A = [ 4  5  6 ]
REM     [         ]
REM     [ 7  8  9 ]
REM
REM
REM  ( 1 ) . x^3 + ( -15 ) . x^2 + ( -18 ) . x + ( 0 ) = 0
REM
REM solution: 3 roots:
REM
REM 3 real unequal roots
REM
REM real1 = -1.11684397
REM imag1 = 0
REM real2 = 16.116844
REM imag2 = 0
REM real3 = 0
REM imag3 = 0
REM
REM
REM result of filling in root1 in given equation gives: 8.94069672E-8
REM
REM result of filling in root2 in given equation gives: 8.34465027E-7
REM
REM result of filling in root3 in given equation gives: 0
REM
REM -----------------------------
REM
REM normalized eigenvector1 = 0.785830239 8.67513391E-2 -0.61232756
REM
REM normalized eigenvector2 = 0.231970691 0.525322093 0.818673499
REM
REM normalized eigenvector3 = 0.408248291 -0.816496581 0.408248291
REM
REM -----------------------------
REM
REM The resulting eigenvectors are stored in a string in the format
REM
REM  eigenvector1x eigenvector1y eigenvector1z eigenvector2x 
eigenvector2y eigenvector2z eigenvector3x eigenvector3y eigenvector3z
REM
REM which is then returned from the function
REM you can then use some string extract function
REM (searching e.g. for the space separator)
REM to get the individual roots out of that string
REM
REM -----------------------------
REM
REM The 3 eigenvectors are
REM
REM 1 0.110394504 -0.779210992 1 2.26460546 3.52921093 1 -2 1
REM
:
LOCAL s$
LOCAL rootRealR1
LOCAL rootImagR1
LOCAL rootRealR2
LOCAL rootImagR2
LOCAL rootRealR3
LOCAL rootImagR3
LOCAL x11R
LOCAL x12R
LOCAL x13R
LOCAL x21R
LOCAL x22R
LOCAL x23R
LOCAL x31R
LOCAL x32R
LOCAL x33R
LOCAL result$
s$ = FNStringGetPhysicsCalculateEigenvalueGivenMatrix3DS( a11, a12, 
a13, a21, a22, a23, a31, a32, a33, dimB%, printB% )
:
lambdaRealR1 = FNMathGetNumberCarFirstR( s$ )
lambdaImagR1 = FNMathGetNumberCarSecondR( s$ )
lambdaRealR2 = FNMathGetNumberCarThirdR( s$ )
lambdaImagR2 = FNMathGetNumberCarFourthR( s$ )
lambdaRealR3 = FNMathGetNumberCarFifthR( s$ )
lambdaImagR3 = FNMathGetNumberCarSixthR( s$ )
:
s$ = FNStringGetMathEigenVector3DS( a11, a12, a13, a21, a22, a23, a31, 
a32, a33, lambdaRealR1, lambdaImagR1 )
result$ = FNStringGetConsS( result$, s$ )
x11R = FNMathGetNumberCarFirstR( s$ )
x12R = FNMathGetNumberCarSecondR( s$ )
x12R = FNMathGetNumberCarThirdR( s$ )
:
s$ = FNStringGetMathEigenVector3DS( a11, a12, a13, a21, a22, a23, a31, 
a32, a33, lambdaRealR2, lambdaImagR2 )
result$ = FNStringGetConsS( result$, s$ )
x21R = FNMathGetNumberCarFirstR( s$ )
x22R = FNMathGetNumberCarSecondR( s$ )
x23R = FNMathGetNumberCarThirdR( s$ )
:
s$ = FNStringGetMathEigenVector3DS( a11, a12, a13, a21, a22, a23, a31, 
a32, a33, lambdaRealR3, lambdaImagR3 )
result$ = FNStringGetConsS( result$, s$ )
x31R = FNMathGetNumberCarFirstR( s$ )
x32R = FNMathGetNumberCarSecondR( s$ )
x33R = FNMathGetNumberCarThirdR( s$ )
:
= result$
:
REM library: physics: calculate: eigenvalue: given: matrix3 
(filenamemacro=calcphgm.bbc) [kn, ri, su, 22-01-2021 19:39:17]
DEF FNStringGetPhysicsCalculateEigenvalueGivenMatrix3DS( a11, a12, 
a13, a21, a22, a23, a31, a32, a33, dimB%, printB% )
REM e.g. printB% = TRUE
REM e.g. dimB% = TRUE
REM e.g. a11 = 1
REM e.g. a12 = 2
REM e.g. a13 = 3
REM e.g. a21 = 4
REM e.g. a22 = 5
REM e.g. a23 = 6
REM e.g. a31 = 7
REM e.g. a32 = 8
REM e.g. a33 = 9
REM e.g. PRINT FNStringGetPhysicsCalculateEigenvalueGivenMatrix3DS( 
a11, a12, a13, a21, a22, a23, a31, a32, a33, dimB%, printB% )
REM e.g. END
REM e.g. :
REM e.g. :
REM e.g. :
REM
REM
REM ---
REM
REM Running this example shows
REM
REM
REM  ( 1 ) . x^3 + ( -15 ) . x^2 + ( -18 ) . x + ( 0 ) = 0
REM
REM solution: 3 roots:
REM
REM 3 real unequal roots
REM
REM real1 = -1.11684397
REM imag1 = 0
REM real2 = 16.116844
REM imag2 = 0
REM real3 = 0
REM imag3 = 0
REM
REM
REM result of filling in root1 in given equation gives: 8.94069672E-8
REM
REM result of filling in root2 in given equation gives: 8.34465027E-7
REM
REM result of filling in root3 in given equation gives: 0
REM
REM -----------------------------
REM
REM The resulting roots are stored in a string in the format
REM
REM  root1real root1image root2real root2imag root3real root3imag
REM
REM which is then returned from the function
REM you can then use some string extract function
REM (searching e.g. for the space separator)
REM to get the individual roots out of that string
REM
REM -----------------------------
REM
REM -1.11684397 0 16.116844 0 0 0
:
LOCAL a
LOCAL b
LOCAL c
LOCAL d
:
a = 1
b = - (a11 + a22 + a33)
c = (a22 * a33 - a12 * a21 + a22 * a11 + a11 * a33 - a23 * a32 - a31 * 
a13)
d = (- a23 * a12 * a31 - a32 * a21 * a13 + a12 * a21 * a33 - a22 * a11 
* a33 + a23 * a32 * a11 + a22 * a31 * a13)
:
= FNStringGetMathEquationPolynomDegree3RootS( a, b, c, d, dimB%, 
printB% )
:
REM library: math: get: number: car: first (filenamemacro=getmafr.bbc) 
[kn, ri, su, 22-01-2021 22:20:34]
DEF FNMathGetNumberCarFirstR( s$ )
REM e.g. PRINT; FNMathGetNumberCarFirstR( "1.1 2.2 3.3 4.4 5.5 6.6 7.7 
8.8 9.9" ) : REM gives 1.1
REM e.g. END
REM e.g. :
REM e.g. :
REM e.g. :
= FNMathGetNumberCarCentralR( s$, 1 )
:
REM library: math: get: number: car: second 
(filenamemacro=getmasr.bbc) [kn, ri, su, 22-01-2021 22:20:38]
DEF FNMathGetNumberCarSecondR( s$ )
REM e.g. PRINT FNMathGetNumberCarSecondR( "1.1 2.2 3.3 4.4 5.5 6.6 7.7 
8.8 9.9" ) : REM gives 2.2
REM e.g. END
REM e.g. :
REM e.g. :
REM e.g. :
= FNMathGetNumberCarCentralR( s$, 2 )
:
REM library: math: get: number: car: third (filenamemacro=getmatr.bbc) 
[kn, ri, su, 22-01-2021 22:20:42]
DEF FNMathGetNumberCarThirdR( s$ )
REM e.g. PRINT FNMathGetNumberCarThirdR( "1.1 2.2 3.3 4.4 5.5 6.6 7.7 
8.8 9.9" ) : REM gives 3.3
REM e.g. END
REM e.g. :
REM e.g. :
REM e.g. :
= FNMathGetNumberCarCentralR( s$, 3 )
:
REM library: math: get: number: car: fourth 
(filenamemacro=getmafs.bbc) [kn, ri, su, 22-01-2021 22:20:45]
DEF FNMathGetNumberCarFourthR( s$ )
REM e.g. PRINT FNMathGetNumberCarFourthR( "1.1 2.2 3.3 4.4 5.5 6.6 7.7 
8.8 9.9" ) : REM gives 4.4
REM e.g. END
REM e.g. :
REM e.g. :
REM e.g. :
= FNMathGetNumberCarCentralR( s$, 4 )
:
REM library: math: get: number: car: fifth (filenamemacro=getmaft.bbc) 
[kn, ri, su, 22-01-2021 22:20:47]
DEF FNMathGetNumberCarFifthR( s$ )
REM e.g. PRINT FNMathGetNumberCarFifthR( "1.1 2.2 3.3 4.4 5.5 6.6 7.7 
8.8 9.9" ) : REM gives 5.5
REM e.g. END
REM e.g. :
REM e.g. :
REM e.g. :
= FNMathGetNumberCarCentralR( s$, 5 )
:
REM library: math: get: number: car: sixth (filenamemacro=getmass.bbc) 
[kn, ri, su, 22-01-2021 22:20:50]
DEF FNMathGetNumberCarSixthR( s$ )
REM e.g. PRINT FNMathGetNumberCarSixthR( "1.1 2.2 3.3 4.4 5.5 6.6 7.7 
8.8 9.9" ) : REM gives 6.6
REM e.g. END
REM e.g. :
REM e.g. :
REM e.g. :
= FNMathGetNumberCarCentralR( s$, 6 )
:
REM library: math: get: eigen: vector3 (filenamemacro=getmadr.bbc) 
[kn, ri, su, 22-01-2021 22:31:52]
DEF FNStringGetMathEigenVector3DS( a11, a12, a13, a21, a22, a23, a31, 
a32, a33, lambdaRealR, lambdaImagR )
REM e.g. printB% = TRUE
REM e.g. dimB% = TRUE
REM e.g. a11 = 1
REM e.g. a12 = 2
REM e.g. a13 = 3
REM e.g. a21 = 4
REM e.g. a22 = 5
REM e.g. a23 = 6
REM e.g. a31 = 7
REM e.g. a32 = 8
REM e.g. a33 = 9
REM e.g. lambdaRealR = -1.11684397
REM e.g. lambdaImagR = 0
REM e.g. PRINT FNStringGetMathEigenVector3DS( a11, a12, a13, a21, a22, 
a23, a31, a32, a33, lambdaRealR, lambdaImagR )
REM e.g. END
REM
REM ----
REM
REM for the moment only the real parts are taken, not the more general 
complex solution
REM because it is meant to calculate inertia tensor rotations in 3D, 
where real, symmetric matrices
REM will give 3 distinct real eigenvectors anyhow
REM
REM ---
REM
REM this value for lambda gives as a result
REM
REM   1 0.110394504 -0.779210992
REM
REM if normalized by dividing by the length of the vector, the answer 
is 0.785830239  0.0992619116 -0.701294448
REM
LOCAL x1R
LOCAL x2R
LOCAL x3R
LOCAL denominatorR
LOCAL lengthR
:
denominatorR = ( a22 * a33 - a22 * lambdaRealR - lambdaRealR * a33 + 
lambdaRealR^2 - a23 * a32 )
:
x1R = 1
x2R = x1R * ( a31 * a23 - a33 * a21 + lambdaRealR * a21 ) / 
denominatorR
x3R = x1R * ( a21 * a32 - a22 * a31 + lambdaRealR * a31 ) / 
denominatorR
:
xNormalize1R = FNMathGetVectorUnit3DXR( x1R, x2R, x3R ) : REM 
normalized value for x1R
xNormalize2R = FNMathGetVectorUnit3DYR( x1R, x2R, x3R ) : REM 
normalized value for x2R
xNormalize3R = FNMathGetVectorUnit3DZR( x1R, x2R, x3R ) : REM 
normalized value for x3R
:
PRINT "normalized eigenvector = "; FNStringGetCons3S( 
FNStringGetMathGetNumberRealToStringS( xNormalize1R ), 
FNStringGetMathGetNumberRealToStringS( xNormalize2R ), 
FNStringGetMathGetNumberRealToStringS( xNormalize3R ) )
:
= FNStringGetCons3S( FNStringGetMathGetNumberRealToStringS( x1R ), 
FNStringGetMathGetNumberRealToStringS( x2R ), 
FNStringGetMathGetNumberRealToStringS( x3R ) )
:
REM library: string: token: concatenate two strings to one, with one 
extra space in between [kn, ri, th, 10-05-2021 14:33:30]
DEF FNStringGetConsS( s1$, s2$ )
IF s1$ = "" THEN = s2$
IF s2$ = "" THEN = s1$
= s1$ + " " + s2$
:
REM library: math: equation: polynom: degree: 3: root 
(filenamemacro=solveqp3.bbc) [kn, ri, sa, 09-02-2021 00:22:52]
DEF FNStringGetMathEquationPolynomDegree3RootS( k3R, k2R, k1R, k0R, 
dimB%, printB% )
REM e.g. PRINT FNStringGetMathEquationPolynomDegree3RootS( 1, -7, 0, 
28, FNMathCheckLogicTrueB, FNMathCheckLogicTrueB )
REM e.g. END
REM
REM Running this program gives the following results
REM
REM  ( 1 ) . x^3 + ( -7 ) . x^2 + ( 0 ) . x + ( 28 ) = 0
REM
REM solution: 3 roots:
REM
REM 3 real unequal roots
REM
REM real1 = -1.78526086
REM imag1 = 0
REM real2 = 6.29295138
REM imag2 = 0
REM real3 = 2.49230949
REM imag3 = 0
REM
REM
REM result1 = 8.19563866E-8
REM
REM result2 = -5.96046448E-8
REM
REM result3 = -3.7252903E-8
REM
REM -----------------------------
REM
REM The resulting roots are stored in a string in the format
REM
REM  root1real root1image root2real root2imag root3real root3imag
REM
REM which is then returned from the function
REM you can then use some string extract function
REM (searching e.g. for the space separator)
REM to get the individual roots out of that string
REM
REM -----------------------------
REM
REM -1.78526086 0 6.29295138 0 2.49230949 0
REM
REM Press any key to continue . . .
REM
REM -----------------------------
LOCAL info$
LOCAL discriminantR
IF dimB% THEN PROCMathEquationPolynomDegree3RootDim( 3 )
discriminantR = FNMathEquationPolynomDegree3DeterminantR( k3R, k2R, 
k1R, k0R )
info$ = FNMathEquationPolynomDegree3RootCaseS( discriminantR )
IF printB% THEN PROCMathEquationPolynomDegree3Print( k3R, k2R, k1R, 
k0R ) : PROCMathEquationPolynomDegree3Test( k3R, k2R, k1R, k0R )
= FNStringGetMathEquationPolynomDegree3RootSolutionAllS( 3 )
ENDPROC
:
REM library: math: get: number: car: central 
(filenamemacro=getmacr.bbc) [kn, ri, su, 22-01-2021 22:20:52]
DEF FNMathGetNumberCarCentralR( inS$, I% )
LOCAL s$
s$ = FNStringGetCarCentralS( inS$, I% )
= FNStringGetToNumberF( s$ )
END
:
REM library: math: VEKTOR: 3D: operatie unair: EENHEIDSVEKTOR
DEF FNMathGetVectorUnit3DXR( xR, yR, zR )
REM e.g. PRINT FNMathGetVectorUnit3DXR( 1, 1, 1 ) : REM gives 1 / 
SquareRoot( 1^2 + 1^2 + 1^2 ) = 1 / SquareRoot( 3 ) = 0.577350269...
REM e.g. END
= FNNumberGetMathDivideR( xR, FNMathGetVectorLength3DR( xR, yR, zR ) )
:
DEF FNMathGetVectorUnit3DYR( xR, yR, zR )
REM e.g. PRINT FNMathGetVectorUnit3DYR( 1, 2, 1 ) : REM gives 2 / 
SquareRoot( 2^2 + 1^2 + 1^2 ) = 2 / SquareRoot( 6 ) = 0.816496581...
REM e.g. END
= FNNumberGetMathDivideR( yR, FNMathGetVectorLength3DR( xR, yR, zR ) )
:
DEF FNMathGetVectorUnit3DZR( xR, yR, zR )
REM e.g. PRINT FNMathGetVectorUnit3DZR( 1, 2, 3 ) : REM gives 3 / 
SquareRoot( 1^2 + 2^2 + 3^2 ) = 3 / SquareRoot( 14 ) = 0.801783726...
REM e.g. END
= FNNumberGetMathDivideR( zR, FNMathGetVectorLength3DR( xR, yR, zR ) )
:
REM library: string: concatenation: 3 strings [kn, ri, th, 10-05-2021 
16:44:45]
DEF FNStringGetCons3S( s1$, s2$, s3$ )
REM e.g. PRINT; FNStringGetCons3S( "1", "2", "3" )
REM e.g. END
= FNStringGetConsS( FNStringGetConsS( s1$, s2$ ), s3$ )
REM variation = FNStringGetConsSeparatorS( s1$, s2$, s3$, 
FNStringGetEmptyS )
:
REM library: math: get: number: real: to: string 
(filenamemacro=getmatst.bbc) [kn, ri, su, 22-01-2021 20:21:52]
DEF FNStringGetMathGetNumberRealToStringS( x )
REM e.g. PRINT "'" + FNStringGetMathGetNumberRealToStringS( 3.14 ) 
+ "'"
REM e.g. END
REM :
REM :
REM :
= STR$( x )
:
REM library: math: logic: true: wrapper [kn, ri, mo, 04-02-2021 
23:46:06]
DEF FNMathCheckLogicTrueB
= TRUE
:
REM library: math: equation: polynom: degree: 3: root: dim [kn, ri, 
sa, 09-02-2021 01:20:59]
DEF PROCMathEquationPolynomDegree3RootDim( maxT% )
DIM xRA( maxT%, 1 )
ENDPROC
:
REM library: math: equation: polynom: degree: 3: root [kn, ri, sa, 09- 
02-2002 00:22:52]
DEF FNMathEquationPolynomDegree3DeterminantR( k3R, k2R, k1R, k0R )
LOCAL hR
LOCAL p1R
LOCAL p2R
LOCAL q1R
LOCAL q2R
LOCAL q3R
hR = 3 * k3R
p1R = k1R / hR
p2R = - ( FNMathPowerR( k2R / hR, 2 ) )
q1R = FNMathPowerR( k2R / hR, 3 )
q2R = - ( k2R * k1R ) / ( 6 * FNMathPowerR( k3R, 2 ) )
q3R = k0R / ( 2 * k3R )
pR = p1R + p2R
qR = q1R + q2R + q3R
= ( FNMathPowerR( pR, 3 ) + FNMathPowerR( qR, 2 ) )
:
REM library: math: equation: polynom: degree: 3: root [kn, ri, sa, 09- 
02-2002 00:22:52]
DEF FNMathEquationPolynomDegree3RootCaseS( discriminantR )
IF FNMathCheckNumberPositiveB( discriminantR ) THEN = 
FNMathEquationPolynomDegree3Root1Real2ComplexS( discriminantR ) : 
ENDPROC
IF FNMathCheckNumberEqualZeroB( discriminantR ) THEN = 
FNMathEquationPolynomDegree3Root3RealEqualS( discriminantR ) : ENDPROC
IF FNMathCheckNumberNegativeB( discriminantR ) THEN = 
FNMathEquationPolynomDegree3Root3RealEqualNotS( discriminantR ) : 
ENDPROC
ENDPROC
:
REM library: math: equation: polynom: degree: 3: root [kn, ri, sa, 09- 
02-2002 00:22:52]
DEF PROCMathEquationPolynomDegree3Print( k3R, k2R, k1R, k0R )
LOCAL T%
PRINT
PRINT;" ( "; k3R; " ) . x^3 + ( "; k2R; " ) . x^2 + ( "; k1R; " ) . x 
+ ( "; k0R; " ) = 0"
PRINT
PRINT "solution: 3 roots: "
PRINT
PRINT info$
PRINT
FOR T% = 1 TO 3
  PRINT "real"; T%; " = "; xRA( T%, 0 )
  PRINT "imag"; T%; " = "; xRA( T%, 1 )
NEXT T%
PRINT
ENDPROC
:
DEF PROCMathEquationPolynomDegree3Test( k3R, k2R, k1R, k0R )
LOCAL result
LOCAL T%
FOR T% = 1 TO 3
  result = k3R * FNMathPowerR( xRA( T%, 0 ), 3 ) + k2R * FNMathPowerR( 
xRA( T%, 0 ), 2 ) + k1R * FNMathPowerR( xRA( T%, 0 ), 1 ) + k0R
  PRINT
  PRINT "result of filling in root"; T%; " in given equation gives: "; 
result
NEXT T%
PRINT
PRINT "-----------------------------"
ENDPROC
:
REM library: string: get: math: equation: polynom: degree3: root: 
solution: all (filenamemacro=getstas.bbc) [kn, ri, su, 22-01-2021 
20:26:43]
DEF FNStringGetMathEquationPolynomDegree3RootSolutionAllS( maxI% )
REM e.g. DIM xRA( 3, 1 )
REM e.g.
REM e.g. xRA( 1, 0 ) = 1
REM e.g. xRA( 1, 1 ) = 2
REM e.g. xRA( 2, 0 ) = 3
REM e.g. xRA( 2, 1 ) = 4
REM e.g. xRA( 3, 0 ) = 5
REM e.g. xRA( 3, 1 ) = 6
REM e.g. PRINT FNStringGetMathEquationPolynomDegree3RootSolutionAllS( 
3 )
REM e.g. END
LOCAL s$
LOCAL I%
LOCAL minI%
minI% = 1
FOR I% = minI% TO maxI%
  s$ = FNStringGetCons3S( s$, FNStringGetMathGetNumberRealToStringS( 
xRA( I%, 0 ) ), FNStringGetMathGetNumberRealToStringS( xRA( I%, 1 ) ) )
NEXT I%
= s$
:
REM library: string: get: car: central (filenamemacro=getstcce.bbc) 
[kn, ri, su, 22-01-2021 22:00:42]
DEF FNStringGetCarCentralS( s$, I% )
= FNStringGetTokenFirstNS( s$, FNStringGetCharacterSymbolSpaceS, I% )
END
:
REM library: string: conversion: string to real [kn, ri, we, 16-05- 
2001 18:14:40]
DEF FNStringGetToNumberF( s$ )
IF s$ = "" THEN PROCError( "string to integer : string may not be 
empty" ) : = 0
= EVAL s$
:
REM library: math: number: DIVIDE + test on denominator = 0 : English 
[kn, zoe, tu, 07-11-2020 20:59:26]
DEF FNNumberGetMathDivideR( numerator, denominator ) : REM version 
with infinity external
LOCAL zero, denominatorzeroB%
denominatorzeroB% = ( denominator = 0 )
IF numerator = 0 AND denominatorzeroB% THEN PRINT; "0/0 = undefined, 
every number satisfies this equation. E.g. 1000 * 0 = 0, but also 3 * 
0 = 0, ..." : STOP
IF denominator = 0 THEN PROCError( "division by zero" ) : STOP
= numerator / denominator
:
REM library: math: get: vector: length3 (filenamemacro=getmads.bbc) 
[kn, ri, su, 22-01-2021 22:59:45]
DEF FNMathGetVectorLength3DR( xR, yR, zR )
REM e.g. PRINT FNMathGetVectorLength3DR( 3, 4, 5 ) : REM gives 
SquareRoot( 3^2 + 4^2 + 5^2 ) = SquareRoot( 9 + 16 + 25 ) = SquareRoot 
( 50 ) = 7.07106781
REM e.g. END
= FNMathGetVectorDistance3DR( 0, 0, 0, xR, yR, zR )
REM = SQR( x ^ 2 + y ^ 2 + z ^ 2 ) : REM variant
:
REM library: string: token: concatenate two strings to one, with one 
separator, with one extra space in between [kn, ri, fr, 11-05-2021 
12:40:25]
DEF FNStringGetConsSeparatorS( s1$, s2$, separator$ )
= FNStringGetConsS( FNStringGetConcatS( s1$, separator$ ), s2$ )
:
REM library: string: return an empty string [kn, ri, we, 09-05-2021 
19:53:53]
DEF FNStringGetEmptyS
= ""
:
REM library: math: power (with test for 0^power): real number as 
result [kn, ri, sa, 09-02-2021 01:11:08]
DEF FNMathPowerR( xR, powerR )
= FNMathPowerF( xR, powerR )
:
REM library: math: number: positive? [kn, ri, su, 10-02-2021 16:06:00]
DEF FNMathCheckNumberPositiveB( xR )
= FNMathCheckNumberGreaterZeroB( xR )
:
REM library: math: equation: polynom: degree: 3: root [kn, ri, sa, 09- 
02-2002 00:22:52]
DEF FNMathEquationPolynomDegree3Root1Real2ComplexS( discriminantR )
PROCMathEquationPolynomDegree3DiscriminantGreaterOrEqualZero( 
discriminantR )
= "1 real and 2 complex roots"
:
REM library: math: number equal to ZERO? [kn, ri, th, 03-05-2021 
14:19:57]
DEF FNMathCheckNumberEqualZeroB( xR )
= ( xR = 0 )
:
REM library: math: equation: polynom: degree: 3: root [kn, ri, sa, 09- 
02-2002 00:22:52]
DEF FNMathEquationPolynomDegree3Root3RealEqualS( discriminantR )
LOCAL info$
IF FNMathLogicAndB( FNMathCheckNumberEqualZeroB( pR ), 
FNMathCheckNumberEqualZeroB( qR ) ) THEN info$ = "3 real roots equal 
to zero" ELSE info$ = "2 real equal roots, 1 root real and unequal"
PROCMathEquationPolynomDegree3DiscriminantGreaterOrEqualZero( 
discriminantR )
= info$
:
REM library: math: number: negative? [kn, ri, su, 10-02-2021 16:06:06]
DEF FNMathCheckNumberNegativeB( xR )
= FNMathCheckNumberSmallerZeroB( xR )
:
REM library: math: equation: polynom: degree: 3: root [kn, ri, sa, 09- 
02-2002 00:22:52]
DEF FNMathEquationPolynomDegree3Root3RealEqualNotS( discriminantR )
REM [book: see also: Bronshtein - guidebook of mathematics - pR^3+qR^2 
<= 0 - page 162]
LOCAL angleR
LOCAL cosphiR
LOCAL hR
LOCAL phiR
LOCAL rR
LOCAL radiusR
LOCAL sixtydegreesR
LOCAL yreal1R
LOCAL yimag1R
LOCAL yreal2R
LOCAL yimag2R
LOCAL yreal3R
LOCAL yimag3R
rR = FNMathSquareRootR( FNMathNumberAbsoluteR( pR ) )
cosphiR = qR / FNMathPowerR( rR, 3 )
phiR = FNMathTrigonometryCosToAngleR( cosphiR )
angleR = 1 / 3 * phiR
radiusR = 2 * rR
sixtydegreesR = FNMathPiR / 3
yreal1R = - radiusR * FNMathTrigonometryCosR( angleR )
yimag1R = 0
yreal2R = + radiusR * FNMathTrigonometryCosR( sixtydegreesR - angleR )
yimag2R = 0
yreal3R = + radiusR * FNMathTrigonometryCosR( sixtydegreesR + angleR )
yimag3R = 0
hR = k2R / ( 3 * k3R )
PROCMathEquationPolynomDegree3Result( yreal1R - hR, yimag1R, yreal2R - 
hR, yimag2R, yreal3R - hR, yimag3R )
= "3 real unequal roots"
:
REM library: string: Nth token: get: separator [kn, zoe, th, 09-11- 
2000 20:30:12]
DEF FNStringGetTokenFirstNS( s$, separator$, nrT% )
LOCAL T%
LOCAL first$
FOR T% = 1 TO nrT%
  first$ = FNStringGetTokenFirstS( s$, separator$ )
  s$ = FNStringGetTokenRestS( s$, separator$ )
NEXT T%
= first$
:
REM library: character: " [kn, ri, fr, 11-05-2021 14:43:25]
DEF FNStringGetCharacterSymbolSpaceS
= CHR$( 32 )
:
REM library: error [kn, zoe, mo, 06-11-2020 20:35:48]
DEF PROCError( info$ )
PRINT "Error: "; info$
errorB% = TRUE
ENDPROC
:
REM library: math: VECTOR: 3D: operation binary: DISTANCE between 2 
vektors ( both vektors from same origin ) [kn, ri, mo, 23-01-2021 
01:29:19]
DEF FNMathGetVectorDistance3DR( x1R, y1R, z1R, x2R, y2R, z2R )
REM e.g. PRINT FNMathGetVectorDistance3DR( 0, 0, 0, 3, 4, 5 ) : REM 
gives 7.07106781
REM e.g. END
= FNMathSquareRootR( ( x2R - x1R ) ^ 2 + ( y2R - y1R ) ^ 2 + ( z2R - 
z1R ) ^ 2 )
:
REM library: string: concatenate: two strings [kn, ri, th, 10-05-2021 
14:32:25]
DEF FNStringGetConcatS( s1$, s2$ )
= s1$ + s2$
:
REM library: math: power (with test for 0^power): float [kn, ri, tu, 
10-07-2021 14:53:07]
DEF FNMathPowerF( xR, powerR )
IF xR = 0 THEN = 0
= xR ^ powerR
:
REM library: math: number: number greater than zero? [kn, ri, su, 10- 
02-2002 17:21:09]
DEF FNMathCheckNumberGreaterZeroB( xR )
= FNMathCheckNumberGreaterB( xR, 0 )
:
REM library: math: equation: polynom: degree: 3: root [kn, ri, sa, 09- 
02-2002 00:22:52]
DEF PROCMathEquationPolynomDegree3DiscriminantGreaterOrEqualZero( 
discriminantR )
REM [book: see also: van der Linden, C. - mathematical vademecum for 
technicians - page 42 'Method of Cardano']
LOCAL discriminantsquarerootR
LOCAL h1R
LOCAL hR
LOCAL uR
LOCAL vR
LOCAL yreal1R
LOCAL yimag1R
LOCAL yreal2R
LOCAL yimag2R
LOCAL yreal3R
LOCAL yimag3R
discriminantsquarerootR = FNMathSquareRootR( discriminantR )
uR = FNMathThirdRootR( - qR + discriminantsquarerootR )
vR = FNMathThirdRootR( - qR - discriminantsquarerootR )
hR = FNMathSquareRootR( 3 ) / 2
yreal1R = uR + vR
yimag1R = 0
yreal2R = - (1/2) * yreal1R
yimag2R = hR * ( uR - vR )
yreal3R = yreal2R
yimag3R = - yimag2R
h1R = k2R / ( 3 * k3R )
PROCMathEquationPolynomDegree3Result( yreal1R - h1R, yimag1R, yreal2R -
 h1R, yimag2R, yreal3R - h1R, yimag3R )
ENDPROC
:
REM library: math: logic: and [kn, ri, mo, 04-02-2021 23:47:07]
DEF FNMathLogicAndB( B1%, B2% )
REM e.g. <F12> PROCMessage( FNMathLogicAndB( FNMathCheckNumberEqualB( 
employeepayD, hourlyD ), FNMathCheckNumberGreaterB( employee_hoursD, 
40.0 ) ) ) REM gives ...
= ( B1% AND B2% )
:
REM library: math: number: compare: number1 SMALLER THAN or EQUAL THAN 
zero? [kn, ri, tu, 05-02-2021 22:28:14]
DEF FNMathCheckNumberSmallerZeroB( xR )
= FNMathCheckNumberSmallerB( xR, 0 )
:
REM library: math: squareroot [kn, zoe, mo, 06-11-2020 20:35:33]
DEF FNMathSquareRootR( xR )
IF FNMathCheckNumberNegativeB( xR ) THEN PROCError( FNStringGetConsS 
( "root from a negative number is not possible :", 
FNMathGetIntegerToStringS( xR ) ) )
= SQR( xR )
:
REM library: math: funktion: ABSOLUTE VALUE [kn, ri, mo, 04-02-2021 
23:28:09]
DEF FNMathNumberAbsoluteR( x )
= ABS( x )
:
REM library: math: trigonometry: cos: to: angle [kn, ri, sa, 09-02- 
2002 02:22:16]
DEF FNMathTrigonometryCosToAngleR( cosR )
= ACS cosR
:
REM library: math: number: PI (=3.1415...) [kn, ri, sa, 09-02-2021 
00:57:14]
DEF FNMathPiR
= PI
:
REM library: math: trigonometry: cos [kn, ri, su, 10-02-2021 16:26:57]
DEF FNMathTrigonometryCosR( angleR )
= COS angleR
:
REM library: math: equation: polynom: degree: 3R: root [kn, ri, sa, 09-
 02-2002 00:22:52]
DEF PROCMathEquationPolynomDegree3Result( real1R, imag1R, real2R, 
imag2R, real3R, imag3R )
xRA( 1, 0 ) = real1R
xRA( 1, 1 ) = imag1R
xRA( 2, 0 ) = real2R
xRA( 2, 1 ) = imag2R
xRA( 3, 0 ) = real3R
xRA( 3, 1 ) = imag3R
ENDPROC
:
REM library: string: token: get: first: separator [kn, zoe, th, 09-11- 
2000 20:34:07]
DEF FNStringGetTokenFirstS( s$, separator$ )
REM e.g. PRINT; FNStringGetTokenFirstS( "24:22:00", ":" )
REM e.g. END
REM s$ = FNSpaceS( s$ ) : REM changed [kn, ri, fr, 25-05-2021 15:09:47]
LOCAL posT%
posT% = INSTR( s$, separator$ )
IF posT% <= 0 THEN = s$
= LEFT$( s$, posT% - 1 )
:
REM library: string: token: get: rest: separator [kn, zoe, th, 09-11- 
2000 20:37:06]
DEF FNStringGetTokenRestS( s$, separator$ )
LOCAL posT%
REM s$ = FNSpaceS( s$ ) : REM changed [kn, ri, fr, 25-05-2021 15:09:07]
posT% = INSTR( s$, separator$ )
IF posT% = 0 THEN = ""
REM = FNSpaceS( MID$( s$, posT% + 1 ) ) : REM changed [kn, ri, fr, 25- 
05-2001 15:09:35]
= MID$( s$, posT% + 1 )
:
REM library: math: number: number1 GREATER THAN number2? [kn, ri, th, 
03-05-2021 12:50:03]
DEF FNMathCheckNumberGreaterB( x1R, x2R )
= ( x1R > x2R )
:
REM library: math: third: root [kn, ri, su, 10-02-2021 16:10:32]
DEF FNMathThirdRootR( xR )
LOCAL thirdrootR
IF FNMathCheckNumberEqualZeroB( xR ) THEN = 0
thirdrootR = FNMathPowerR( FNMathNumberAbsoluteR( xR ), 1/3 )
IF FNMathCheckNumberPositiveB( xR ) THEN = thirdrootR
= -thirdrootR
:
REM library: math: number: number1 EQUAL TO number2? [kn, ri, th, 03- 
05-2001 12:51:27]
DEF FNMathCheckNumberEqualB( x1, x2 )
IF x1 = x2 THEN = TRUE ELSE = FALSE
:
REM library: math: number: number1 SMALLER THAN getal2? [kn, ri, th, 
03-05-2021 13:59:36]
DEF FNMathCheckNumberSmallerB( x1R, x2R )
= ( x1R < x2R )
:
REM library: string: CONVERSION: NUMBER to STRING ( inverse of string 
to number ) [kn, ri, th, 10-05-2021 18:04:38]
DEF FNMathGetIntegerToStringS( x )
REM e.g. PRINT "'" + FNMathGetIntegerToStringS( 3 ) + "'"
REM e.g. END
REM :
REM :
REM :
REM = STR$ x
= FNStringGetMathGetNumberRealToStringS( x )
:
REM library: string: SPACE: REMOVE: FRONT: RETURN: END [kn, ri, fr, 06-
 07-2001 12:53:45]
DEF FNSpaceS( s$ )
IF LEFT$( s$, 1 ) <> " " THEN = s$ ELSE = FNSpaceS( RIGHT$( s$, LEN 
s$ - 1 ) )
:
--- cut here: end ----------------------------------------------------
---
---
Internet: see also:
---
Physics: Dynamics: 3D: Link: Overview: Can you give an overview of 
links?
http://www.faqts.com/knowledge_base/view.phtml/aid/39259/fid/1857
----------------------------------------------------------------------