Cross Product and Normalization in Multiple Languages
October 8, 2011 3 Comments
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
Lua arrays starts at 1 and functions can’t use referenced parameters. But nice try 🙂
Lua arrays can be indexed at any integer value: http://www.lua.org/pil/11.1.html
Thanks. Some minor character errors in the Java System.out call, but trivial to fix