Cross Product and Normalization in Multiple Languages

Objective

Calculate the cross product (normal vector) of two vectors in 3D space by taking the cross product of those two vectors.  Vectors should be stored as an array type structure with index 0 holding the x component, index 1 holding the y component, and index 2 holding the z component.  Normalize this result so that it is a unit vector of length one.

Concepts

Passing arrays to methods

Math functions: square root, exponent

Print values to four decimal places

Constraints

Compiler or interpreter must be available in Ubuntu Software Center

bash script

# vi cross.sh

#!/bin/bash

function crossProduct {
  declare -a v1=("${!1}")
  declare -a v2=("${!2}") 

#Note:  Can't pass by reference, so the global variable must be used
  vectResult[0]=$(( (v1[1] * v2[2]) - (v1[2] * v2[1]) ))
  vectResult[1]=$(( - ((v1[0] * v2[2]) - (v1[2] * v2[0])) ))
  vectResult[2]=$(( (v1[0] * v2[1]) - (v1[1] * v2[0]) ))

}

function normalize {
  declare -a v1=("${!1}") 

  fMag=`echo "scale=4; sqrt( (${v1[0]}^2) + (${v1[1]}^2) + (${v1[2]}^2) )" | bc -l`

  vectNormal[0]=`echo "scale=4;${v1[0]} / $fMag" | bc -l`
  vectNormal[1]=`echo "scale=4;${v1[1]} / $fMag" | bc -l`
  vectNormal[2]=`echo "scale=4;${v1[2]} / $fMag" | bc -l`

}

vect1[0]=3
vect1[1]=-3
vect1[2]=1

vect2[0]=4
vect2[1]=9
vect2[2]=2

crossProduct vect1[@] vect2[@]
echo ${vectResult[0]} ${vectResult[1]} ${vectResult[2]}

normalize vectResult[@]
echo ${vectNormal[0]} ${vectNormal[1]} ${vectNormal[2]}

# chmod u+x cross.sh
# ./cross.sh

C

# vi cross.c

#include <stdio.h>
#include <math.h>

void crossProduct(float v1[], float v2[], float vR[]) {
  vR[0] =   ( (v1[1] * v2[2]) - (v1[2] * v2[1]) );
  vR[1] = - ( (v1[0] * v2[2]) - (v1[2] * v2[0]) );
  vR[2] =   ( (v1[0] * v2[1]) - (v1[1] * v2[0]) );
}

void normalize(float v1[], float vR[]) {
  float fMag;

  fMag = sqrt( pow(v1[0], 2) +
               pow(v1[1], 2) +
               pow(v1[2], 2)
             );

  vR[0] = v1[0] / fMag;
  vR[1] = v1[1] / fMag;
  vR[2] = v1[2] / fMag;
}

int main(void) {
  float vect1[3];
  float vect2[3];
  float vectResult[3];
  float vectNormal[3];

  vect1[0] = 3;
  vect1[1] = -3;
  vect1[2] = 1;

  vect2[0] = 4;
  vect2[1] = 9;
  vect2[2] = 2;

  crossProduct(vect1, vect2, vectResult);
  printf("x: %.4f, y: %.4f, z: %.4f\n",
         vectResult[0], vectResult[1], vectResult[2]); 

  normalize(vectResult, vectNormal);
  printf("x: %.4f, y: %.4f, z: %.4f\n",
         vectNormal[0], vectNormal[1], vectNormal[2]); 

  return 0;
}

# gcc cross.c -o cross -lm
#./cross

C++

# vi cross.cpp

#include <iostream>
#include <cmath>
#include <iomanip>

using namespace std;

class cross {
  public:
    void crossProduct(float v1[], float v2[], float vR[]);
    void normalize(float v1[], float vR[]);
};

void cross::crossProduct(float v1[], float v2[], float vR[]) {
  vR[0] =   ( (v1[1] * v2[2]) - (v1[2] * v2[1]) );
  vR[1] = - ( (v1[0] * v2[2]) - (v1[2] * v2[0]) );
  vR[2] =   ( (v1[0] * v2[1]) - (v1[1] * v2[0]) );
}

void cross::normalize(float v1[], float vR[]) {
  float fMag;

  fMag = sqrt( pow(v1[0], 2) +
               pow(v1[1], 2) +
               pow(v1[2], 2)
             );

  vR[0] = v1[0] / fMag;
  vR[1] = v1[1] / fMag;
  vR[2] = v1[2] / fMag;
}

int main(void) {
  float vect1[3];
  float vect2[3];
  float vectResult[3];
  float vectNormal[3];

  vect1[0] = 3;
  vect1[1] = -3;
  vect1[2] = 1;

  vect2[0] = 4;
  vect2[1] = 9;
  vect2[2] = 2;

  cross c;

  c.crossProduct(vect1, vect2, vectResult);

  cout << fixed << setprecision(4);

  cout << "x: " << vectResult[0]
       << ", y: " << vectResult[1]
       << ", z: " << vectResult[2]
       << endl; 

  c.normalize(vectResult, vectNormal);

  cout << "x: " << vectNormal[0]
       << ", y: " << vectNormal[1]
       << ", z: " << vectNormal[2]
       << endl; 

  return 0;
}

# g++ cross.cpp -o cross
# ./cross > out.txt

C Sharp

# vi Cross.cs

using System;

public class Cross {

  void crossProduct(float[] v1, float[] v2, float[] vR) {
    vR[0] =   ( (v1[1] * v2[2]) - (v1[2] * v2[1]) );
    vR[1] = - ( (v1[0] * v2[2]) - (v1[2] * v2[0]) );
    vR[2] =   ( (v1[0] * v2[1]) - (v1[1] * v2[0]) );
  }

  void normalize(float[] v1, float[] vR) {
    float fMag;

    fMag = (float) Math.Sqrt( Math.Pow(v1[0], 2) +
                              Math.Pow(v1[1], 2) +
                              Math.Pow(v1[2], 2)
                            );

    vR[0] = v1[0] / fMag;
    vR[1] = v1[1] / fMag;
    vR[2] = v1[2] / fMag;
  }

  public static void Main() {
    float[] vect1 = new float[3];
    float[] vect2 = new float[3];
    float[] vectResult = new float[3];
    float[] vectNormal = new float[3];

    vect1[0] = 3;
    vect1[1] = -3;
    vect1[2] = 1;

    vect2[0] = 4;
    vect2[1] = 9;
    vect2[2] = 2;

    Cross c = new Cross();

    c.crossProduct(vect1, vect2, vectResult);

    System.Console.WriteLine("x: " + vectResult[0].ToString("0.0000") +
                             ", y: " + vectResult[1].ToString("0.0000") +
                             ", z: " + vectResult[2].ToString("0.0000")
                            );

    c.normalize(vectResult, vectNormal);

    System.Console.WriteLine("x: " + vectNormal[0].ToString("0.0000") +
                             ", y: " + vectNormal[1].ToString("0.0000") +
                             ", z: " + vectNormal[2].ToString("0.0000")
                            );

  }
}

# gmcs Cross.cs
# mono Cross.exe

Forth

# vi cross.fth

fvariable vect1 3 cells allot
fvariable vect2 3 cells allot
fvariable vectResult 3 cells allot
fvariable vectNormal 3 cells allot
fvariable fMag

: crossProduct 

  vect1 1 cells + @
  vect2 2 cells + @
  *

  vect1 2 cells + @
  vect2 1 cells + @
  *
-
vectResult 0 cells + ! 

    vect1 0 cells + @
    vect2 2 cells + @
    *

    vect1 2 cells + @
    vect2 0 cells + @
    *
  -
-1
*
vectResult 1 cells + ! 

  vect1 0 cells + @
  vect2 1 cells + @
  *

  vect1 1 cells + @
  vect2 0 cells + @
  *
-
vectResult 2 cells + ! 

;

3 vect1 0 cells + !
-3 vect1 1 cells + !
1 vect1 2 cells + ! 

4 vect2 0 cells + !
9 vect2 1 cells + !
2 vect2 2 cells + ! 

crossProduct

." x: "
vectResult 0 cells + @ .
." , y: "
vectResult 1 cells + @ .
." , z: "
vectResult 2 cells + @ .
cr

# gforth cross.fth

Note:  Normalize not implemented, since crossProduct was implemented with integers and the square root function requires everything in floats

Fortran

# vi cross.f

      program cross

      real vect1(3)
      real vect2(3)
      real vectResult(3)
      real vectNormal(3) 

      vect1(1) = 3
      vect1(2) = -3
      vect1(3) = 1

      vect2(1) = 4
      vect2(2) = 9
      vect2(3) = 2

      call crossProduct(vect1, vect2, vectResult)

      write(*, 100) vectResult(1), vectResult(2), vectResult(3)

      call normalize(vectResult, vectNormal)

      write(*, 100) vectNormal(1), vectNormal(2), vectNormal(3)

 100  format('x: ', F0.4, ', y: ', F0.4, ', z: ', F0.4)

      stop
      end

      subroutine crossProduct(v1, v2, vR)
      real v1(3)
      real v2(3)
      real vR(3) 

      vR(1) =   ( (v1(2) * v2(3)) - (v1(3) * v2(2)) )
      vR(2) = - ( (v1(1) * v2(3)) - (v1(3) * v2(1)) )
      vR(3) =   ( (v1(1) * v2(2)) - (v1(2) * v2(1)) )  

      end  

      subroutine normalize(v1, vR)
      real v1(3)
      real vR(3) 

      real fMag

      fMag = sqrt( (v1(1) ** 2) + (v1(2) ** 2) + (v1(3) ** 2) )

      vR(1) = v1(1) / fMag
      vR(2) = v1(2) / fMag
      vR(3) = v1(3) / fMag 

      end

# gfortran cross.f -o cross
# ./cross

Java

# vi Cross.java

import java.text.DecimalFormat;

public class Cross {

  public Cross() {

  }

  public void crossProduct(float v1[], float v2[], float vR[]) {
    vR[0] =   ( (v1[1] * v2[2]) - (v1[2] * v2[1]) );
    vR[1] = - ( (v1[0] * v2[2]) - (v1[2] * v2[0]) );
    vR[2] =   ( (v1[0] * v2[1]) - (v1[1] * v2[0]) );
  }

  public void normalize(float v1[], float vR[]) {
    float fMag;

    fMag = (float) Math.sqrt( Math.pow(v1[0], 2) +
                              Math.pow(v1[1], 2) +
                              Math.pow(v1[2], 2)
                            ); 

    vR[0] = v1[0] / fMag;
    vR[1] = v1[1] / fMag;
    vR[2] = v1[2] / fMag;
  }

  public static void main(String args[]) {
    float[] vect1 = new float[3];
    float[] vect2 = new float[3];
    float[] vectResult = new float[3];
    float[] vectNormal = new float[3];

    vect1[0] = 3;
    vect1[1] = -3;
    vect1[2] = 1;

    vect2[0] = 4;
    vect2[1] = 9;
    vect2[2] = 2;

    Cross c = new Cross();

    c.crossProduct(vect1, vect2, vectResult);

    DecimalFormat df = new DecimalFormat("0.0000");
    System.out.println("x: " + df.format(vectResult[0]) +
                       ", y: " + df.format(vectResult[1]) +
                       ", z: " + df.format(vectResult[2]));

    c.normalize(vectResult, vectNormal);
    System.out.println("x: " + df.format(vectNormal[0]) +
                       ", y: " + df.format(vectNormal[1]) +
                       ", z: " + df.format(vectNormal[2]));

  }
}

# javac *.java
# java Cross

Javascript (Rhino)

# vi cross.js

function crossProduct(v1, v2, vR) {
  vR[0] =   ( (v1[1] * v2[2]) - (v1[2] * v2[1]) );
  vR[1] = - ( (v1[0] * v2[2]) - (v1[2] * v2[0]) );
  vR[2] =   ( (v1[0] * v2[1]) - (v1[1] * v2[0]) );
}

function normalize(v1, vR) {
  var fMag = Math.sqrt( Math.pow(v1[0], 2) +
                        Math.pow(v1[1], 2) +
                        Math.pow(v1[2], 2)
                      );

  vR[0] = v1[0] / fMag;
  vR[1] = v1[1] / fMag;
  vR[2] = v1[2] / fMag;

}

var vect1 = new Array(3);
var vect2 = new Array(3);
var vectResult = new Array(3);
var vectNormal = new Array(3);

vect1[0] = 3;
vect1[1] = -3;
vect1[2] = 1;

vect2[0] = 4;
vect2[1] = 9;
vect2[2] = 2;

crossProduct(vect1, vect2, vectResult);
print("x: " + vectResult[0].toFixed(4) +
      ", y: " + vectResult[1].toFixed(4) +
      ", z: " + vectResult[2].toFixed(4));

normalize(vectResult, vectNormal);
print("x: " + vectNormal[0].toFixed(4) +
      ", y: " + vectNormal[1].toFixed(4) +
      ", z: " + vectNormal[2].toFixed(4));

# js -f cross.js

LISP (GNU)

# vi cross.lisp

(defun crossProduct(v1 v2 vR)

  (setf (nth 0 vR)
    (-
      (* (nth 1 v1) (nth 2 v2))
      (* (nth 2 v1) (nth 1 v2))
    )
  )

  (setf (nth 1 vR)
    (*
      -1
      (-
        (* (nth 0 v1) (nth 2 v2))
        (* (nth 2 v1) (nth 0 v2))
      )
    )
  )

  (setf (nth 2 vR)
    (-
      (* (nth 0 v1) (nth 1 v2))
      (* (nth 1 v1) (nth 0 v2))
    )
  )

)

(defun normalize(v1 vR)
  (setf fMag
    (sqrt
      (+
        (expt (nth 0 v1) 2)
        (expt (nth 1 v1) 2)
        (expt (nth 2 v1) 2)
      )
    )
  )

  (setf (nth 0 vR)
    (/ (nth 0 v1) fMag)
  )

  (setf (nth 1 vR)
    (/ (nth 1 v1) fMag)
  )

  (setf (nth 2 vR)
    (/ (nth 2 v1) fMag)
  )

)

(set 'vect1 '(3 -3 1))
(set 'vect2 '(4 9 2))
(set 'vectResult '(nil nil nil))
(set 'vectNormal '(nil nil nil))

(crossProduct vect1 vect2 vectResult)
(format t "x: ~,4f, y: ~,4f, z: ~,4f~%"
          (nth 0 vectResult) (nth 1 vectResult) (nth 2 vectResult))

(normalize vectResult vectNormal)
(format t "x: ~,4f, y: ~,4f, z: ~,4f~%"
          (nth 0 vectNormal) (nth 1 vectNormal) (nth 2 vectNormal))

(quit)

# gcl -load cross.lisp

Lua

# vi cross.lua

function crossProduct(v1, v2, vR)
    vR[0] =   ( (v1[1] * v2[2]) - (v1[2] * v2[1]) )
    vR[1] = - ( (v1[0] * v2[2]) - (v1[2] * v2[0]) )
    vR[2] =   ( (v1[0] * v2[1]) - (v1[1] * v2[0]) )
end

function normalize(v1, vR)
    fMag = math.sqrt( math.pow(v1[0], 2) +
                      math.pow(v1[1], 2) +
                      math.pow(v1[2], 2)
                    )

    vR[0] = v1[0] / fMag
    vR[1] = v1[1] / fMag
    vR[2] = v1[2] / fMag

end

vect1 = {}
vect2 = {}
vectResult = {}
vectNormal = {}

vect1[0] = 3
vect1[1] = -3
vect1[2] = 1 

vect2[0] = 4
vect2[1] = 9
vect2[2] = 2 

crossProduct(vect1, vect2, vectResult)
print(string.format("x: %.4f, y: %.4f, z: %.4f",
                    vectResult[0], vectResult[1], vectResult[2]))

normalize(vectResult, vectNormal)
print(string.format("x: %.4f, y: %.4f, z: %.4f",
                    vectNormal[0], vectNormal[1], vectNormal[2]))

# lua cross.lua

Objective C

# vi Cross.m

#import <objc/objc.h>
#import <objc/Object.h>
#import <stdio.h>
#import <math.h>

@interface Cross : Object {
}

-(void) crossProduct:(float[3]) v1 and:(float[3]) v2 result:(float[3]) vR;
-(void) normalize:(float[3]) v1 result:(float[3]) vR;
@end

@implementation Cross : Object
-(void) crossProduct:(float[3]) v1 and:(float[3]) v2 result:(float[3]) vR {
  vR[0] =   ( (v1[1] * v2[2]) - (v1[2] * v2[1]) );
  vR[1] = - ( (v1[0] * v2[2]) - (v1[2] * v2[0]) );
  vR[2] =   ( (v1[0] * v2[1]) - (v1[1] * v2[0]) );

}

-(void) normalize:(float[3]) v1 result:(float[3]) vR {
  float fMag;

  fMag = sqrt( pow(v1[0], 2) +
               pow(v1[1], 2) +
               pow(v1[2], 2)
             );

  vR[0] = v1[0] / fMag;
  vR[1] = v1[1] / fMag;
  vR[2] = v1[2] / fMag;
}

@end

int main(void) {
  float vect1[3];
  float vect2[3];
  float vectResult[3];
  float vectNormal[3];

  vect1[0] = 3;
  vect1[1] = -3;
  vect1[2] = 1;

  vect2[0] = 4;
  vect2[1] = 9;
  vect2[2] = 2;

  Cross *c = [Cross new];

  [c crossProduct: vect1 and: vect2 result: vectResult];
  printf("x: %.4f, y: %.4f, z: %.4f\n",
         vectResult[0], vectResult[1], vectResult[2]);

  [c normalize: vectResult result: vectNormal];
  printf("x: %.4f, y: %.4f, z: %.4f\n",
         vectNormal[0], vectNormal[1], vectNormal[2]);

}

# gcc -x objective-c -o cross Cross.m -lobjc -lm
# ./cross

Perl

# vi cross.pl

sub crossProduct {
  ($v1, $v2, $vR) = @_;

  $$vR[0] =   ( ($$v1[1] * $$v2[2]) - ($$v1[2] * $$v2[1]) );
  $$vR[1] = - ( ($$v1[0] * $$v2[2]) - ($$v1[2] * $$v2[0]) );
  $$vR[2] =   ( ($$v1[0] * $$v2[1]) - ($$v1[1] * $$v2[0]) ); 

}

sub normalize {
  ($v1, $vR) = @_;

  $fMag = sqrt( ($$v1[0] ** 2) +
                ($$v1[1] ** 2) +
                ($$v1[2] ** 2)
              );

  $$vR[0] = $$v1[0] / $fMag;
  $$vR[1] = $$v1[1] / $fMag;
  $$vR[2] = $$v1[2] / $fMag;
} 

@vect1;
@vect2;
@vectResult;
@vectNormal;

$vect1[0] = 3;
$vect1[1] = -3;
$vect1[2] = 1;

$vect2[0] = 4;
$vect2[1] = 9;
$vect2[2] = 2;

crossProduct( \@vect1, \@vect2, \@vectResult);
printf("x: %.4f, y: %.4f, z: %.4f\n", $vectResult[0],
       $vectResult[1], $vectResult[2]); 

normalize( \@vectResult, \@vectNormal);
printf("x: %.4f, y: %.4f, z: %.4f\n", $vectNormal[0],
       $vectNormal[1], $vectNormal[2]);

# perl cross.pl

PHP

# vi cross.php

<?php

  function crossProduct(&$v1, &$v2, &$vR) {
    $vR[0] =   ( ($v1[1] * $v2[2]) - ($v1[2] * $v2[1]) );
    $vR[1] = - ( ($v1[0] * $v2[2]) - ($v1[2] * $v2[0]) );
    $vR[2] =   ( ($v1[0] * $v2[1]) - ($v1[1] * $v2[0]) );
  }

  function normalize(&$v1, &$vR) {
    $fMag = sqrt( (pow($v1[0], 2)) +
                  (pow($v1[1], 2)) +
                  (pow($v1[2], 2))
                );

    $vR[0] = $v1[0] / $fMag;
    $vR[1] = $v1[1] / $fMag;
    $vR[2] = $v1[2] / $fMag;

  }

  $vect1 = array(null, null, null);
  $vect2 = array(null, null, null);
  $vectResult = array(null, null, null);
  $vectNormal = array(null, null, null);

  $vect1[0] = 3;
  $vect1[1] = -3;
  $vect1[2] = 1;

  $vect2[0] = 4;
  $vect2[1] = 9;
  $vect2[2] = 2;

  crossProduct($vect1, $vect2, $vectResult);

  echo "x: " . number_format($vectResult[0], 4) .
       ", y: " . number_format($vectResult[1], 4) .
       ", z: " . number_format($vectResult[2], 4) .
       "\n";

  normalize($vectResult, $vectNormal);

  echo "x: " . number_format($vectNormal[0], 4) .
       ", y: " . number_format($vectNormal[1], 4) .
       ", z: " . number_format($vectNormal[2], 4) .
       "\n";

?>

# php cross.php

Python

# vi cross.py

import math

def crossProduct(v1, v2, vR):
  vR[0] =   ( (v1[1] * v2[2]) - (v1[2] * v2[1]) )
  vR[1] = - ( (v1[0] * v2[2]) - (v1[2] * v2[0]) )
  vR[2] =   ( (v1[0] * v2[1]) - (v1[1] * v2[0]) )

def normalize(v1, vR):
  fMag = math.sqrt( (v1[0] ** 2) + (v1[1] ** 2) + (v1[2] ** 2) )
  vR[0] = v1[0] / fMag
  vR[1] = v1[1] / fMag
  vR[2] = v1[2] / fMag

vect1 = [ None, None, None ]
vect2 = [ None, None, None ]
vectResult = [ None, None, None ]
vectNormal = [ None, None, None ]

vect1[0] = 3
vect1[1] = -3
vect1[2] = 1 

vect2[0] = 4
vect2[1] = 9
vect2[2] = 2

crossProduct(vect1, vect2, vectResult)

print "x: " + ("%.4f" % vectResult[0]) + \
      ", y: " + ("%.4f" % vectResult[1]) + \
      ", z: " + ("%.4f" % vectResult[2]) 

normalize(vectResult, vectNormal)

print "x: " + ("%.4f" % vectNormal[0]) + \
      ", y: " + ("%.4f" % vectNormal[1]) + \
      ", z: " + ("%.4f" % vectNormal[2])

# python cross.py

Ruby

# vi cross.rb

class Cross

  def crossProduct(v1, v2, vR)
    vR[0] =   ( (v1[1] * v2[2]) - (v1[2] * v2[1]) )
    vR[1] = - ( (v1[0] * v2[2]) - (v1[2] * v2[0]) )
    vR[2] =   ( (v1[0] * v2[1]) - (v1[1] * v2[0]) )
  end

  def normalize(v1, vR)
    fMag = Math.sqrt( (v1[0] ** 2) +
                      (v1[1] ** 2) +
                      (v1[2] ** 2)
                    )

    vR[0] = v1[0] / fMag
    vR[1] = v1[1] / fMag
    vR[2] = v1[2] / fMag
  end

end

vect1 = Array.new
vect2 = Array.new
vectResult = Array.new
vectNormal = Array.new

vect1[0] = 3
vect1[1] = -3
vect1[2] = 1 

vect2[0] = 4
vect2[1] = 9
vect2[2] = 2 

c = Cross.new()

c.crossProduct(vect1, vect2, vectResult)
printf("x: %.4f, y: %.4f, z: %.4f\n", vectResult[0],
       vectResult[1], vectResult[2]) 

c.normalize(vectResult, vectNormal)
printf("x: %.4f, y: %.4f, z: %.4f\n", vectNormal[0],
       vectNormal[1], vectNormal[2])

# ruby cross.rb

Scala

# vi Cross.scala

object Cross {

  def crossProduct(v1: Array[Float], v2: Array[Float], vR: Array[Float]) = {
    vR(0) =   ( (v1(1) * v2(2)) - (v1(2) * v2(1)) )
    vR(1) = - ( (v1(0) * v2(2)) - (v1(2) * v2(0)) )
    vR(2) =   ( (v1(0) * v2(1)) - (v1(1) * v2(0)) )
  }

  def normalize(v1: Array[Float], vR: Array[Float]) = {
    var fMag = (Math.sqrt( Math.pow(v1(0), 2) +
                          Math.pow(v1(1), 2) +
                          Math.pow(v1(2), 2)
                        )
               ).toFloat

    vR(0) = v1(0) / fMag
    vR(1) = v1(1) / fMag
    vR(2) = v1(2) / fMag
  }

  def main(args: Array[String]) {
    var vect1 = new Array[Float](3)
    var vect2 = new Array[Float](3)
    var vectResult = new Array[Float](3)
    var vectNormal = new Array[Float](3)

    vect1(0) = 3
    vect1(1) = -3
    vect1(2) =1 

    vect2(0) = 4
    vect2(1) = 9
    vect2(2) = 2 

    this.crossProduct(vect1, vect2, vectResult)
    printf("x: %.4f, y: %.4f, z: %.4f\n", vectResult(0),
           vectResult(1), vectResult(2));

    this.normalize(vectResult, vectNormal)
    printf("x: %.4f, y: %.4f, z: %.4f\n", vectNormal(0),
           vectNormal(1), vectNormal(2));
  }
}

# scalac Cross.scala
# scala Cross

Scheme (GNU/MIT)

# vi cross.scm

(define (crossProduct v1 v2 vR)

  (vector-set! vR 0
    (-
      (* (vector-ref v1 1) (vector-ref v2 2))
      (* (vector-ref v1 2) (vector-ref v2 1))
    )
  ) 

  (vector-set! vR 1
    (*
     -1
      (-
        (* (vector-ref v1 0) (vector-ref v2 2))
        (* (vector-ref v1 2) (vector-ref v2 0))
      )
    )
  ) 

  (vector-set! vR 2
    (-
      (* (vector-ref v1 0) (vector-ref v2 1))
      (* (vector-ref v1 1) (vector-ref v2 0))
    )
  ) 

)

(define (normalize v1 vR)
  (define fMag)
  (set! fMag
    (sqrt
      (+
        (expt (vector-ref v1 0) 2)
        (expt (vector-ref v1 1) 2)
        (expt (vector-ref v1 2) 2)
      )
    )
  )

  (vector-set! vR 0
    (/
      (vector-ref v1 0)
      fMag
    )
  ) 

  (vector-set! vR 1
    (/
      (vector-ref v1 1)
      fMag
    )
  ) 

  (vector-set! vR 2
    (/
      (vector-ref v1 2)
      fMag
    )
  ) 

)

(define vect1 #(3 -3 1))
(define vect2 #(4 9 2))
(define vectResult #(null null null))
(define vectNormal #(null null null))

(newline)

(crossProduct vect1 vect2 vectResult)
(display "x: ")(display (vector-ref vectResult 0))
(display ", y: ")(display (vector-ref vectResult 1))
(display ", z: ")(display (vector-ref vectResult 2))
(newline)

(normalize vectResult vectNormal)
(display "x: ")(display (vector-ref vectNormal 0))
(display ", y: ")(display (vector-ref vectNormal 1))
(display ", z: ")(display (vector-ref vectNormal 2))
(newline)

# scheme –load cross.scm

Smalltalk (Squeak)

crossProduct: v1 and: v2 result: vR

  vR at: 1 put: ( ((v1 at: 2) * (v2 at: 3)) - ((v1 at: 3) * (v2 at: 2)) ).
  vR at: 2 put: ( ((v1 at: 1) * (v2 at: 3)) - ((v1 at: 3) * (v2 at: 1)) ).
  vR at: 3 put: ( ((v1 at: 1) * (v2 at: 2)) - ((v1 at: 2) * (v2 at: 1)) ).

normalize: v1 result: vR
  | fMag |

  fMag := ( ((v1 at: 1) raisedTo: 2) +
              ((v1 at: 2) raisedTo: 2) +
              ((v1 at: 3) raisedTo: 2)
            ) sqrt.

  vR at: 1 put: ((v1 at: 1) / fMag).
  vR at: 2 put: ((v1 at: 2) / fMag).
  vR at: 3 put: ((v1 at: 3) / fMag).

| vect1 vect2 vectResult vectNormal c |

vect1 := Array new: 3.
vect2 := Array new: 3.
vectResult := Array new: 3.
vectNormal := Array new: 3.

vect1 at: 1 put: 3.
vect1 at: 2 put: -3.
vect1 at: 3 put: 1.

vect2 at: 1 put: 4.
vect2 at: 2 put: 9.
vect2 at: 3 put: 2.

c := Cross new.
c crossProduct: vect1 and: vect2 result: vectResult.

Transcript show: 'x: '.
Transcript show: ((vectResult at: 1) roundTo: 0.0001).
Transcript show: ', y: '.
Transcript show: ((vectResult at: 2) roundTo: 0.0001).
Transcript show: ', z: '.
Transcript show: ((vectResult at: 3) roundTo: 0.0001).
Transcript cr.

c normalize: vectResult result: vectNormal.

Transcript show: 'x: '.
Transcript show: ((vectNormal at: 1) roundTo: 0.0001).
Transcript show: ', y: '.
Transcript show: ((vectNormal at: 2) roundTo: 0.0001).
Transcript show: ', z: '.
Transcript show: ((vectNormal at: 3) roundTo: 0.0001).
Transcript cr.

Note:  Must be entered into the Squeak environment.  Add the two methods to a class, and then paste the commands in a Transcript windows, select the text, and then “Do-It”

Tcl

# vi cross.tcl

proc crossProduct { v1p v2p vRp } {
  upvar $v1p v1
  upvar $v2p v2
  upvar $vRp vR

  set vR(0) [expr {  ( ($v1(1) * $v2(2)) - ($v1(2) * $v2(1)) ) }]
  set vR(1) [expr { -( ($v1(0) * $v2(2)) - ($v1(2) * $v2(0)) ) }]
  set vR(2) [expr {  ( ($v1(0) * $v2(1)) - ($v1(1) * $v2(0)) ) }]
}

proc normalize { v1p vRp } {
  upvar $v1p v1
  upvar $vRp vR

  set fMag [expr { sqrt( pow($v1(0), 2) + pow($v1(1), 2) + pow($v1(2), 2) ) }]

  set vR(0) [expr { $v1(0) / $fMag }]
  set vR(1) [expr { $v1(1) / $fMag }]
  set vR(2) [expr { $v1(2) / $fMag }]
}

array set vect1 { }
array set vect2 { }
array set vectResult { }
array set vectNormal { }

set vect1(0) 3
set vect1(1) -3
set vect1(2) 1

set vect2(0) 4
set vect2(1) 9
set vect2(2) 2

crossProduct vect1 vect2 vectResult

puts [format "x: %.4f, y: %.4f, z: %.4f" \
      $vectResult(0) $vectResult(1) $vectResult(2) ]

normalize vectResult vectNormal

puts [format "x: %.4f, y: %.4f, z: %.4f" \
      $vectNormal(0) $vectNormal(1) $vectNormal(2) ]

# tclsh cross.tcl

Output

x: -15.0000, y: -2.0000, z: 39.0000
x: -0.3586, y: -0.0478, z: 0.9323

3 Responses to Cross Product and Normalization in Multiple Languages

  1. gui says:

    Lua arrays starts at 1 and functions can’t use referenced parameters. But nice try 🙂

  2. Anonymous says:

    Thanks. Some minor character errors in the Java System.out call, but trivial to fix

Leave a reply to gui Cancel reply