Processing is my Whetstone

I’m not the sharpest tool in the shed, but I try to exercise what I got and Processing has been my whetstone.

I recently tried out some vector math, cross product, dot product, etc. with good results after some typos slowed me up. This forum proved helpful again, thanks. What I want to do now is apply something I saw after searching “Inverse of a cross product”. The majority of answers were NO, except for One. A professor from the Polytechnica of Equador gave an answer that was very interesting and explained how it is possible using four-vectors. Here’s his answer:

Diego Saa’s Answer

What I want to do is solve this problem and use Processing to show it. I figure I should start by implementing his answer and proving his numbers, but I cant decipher the notation. It looks simple but…

I already have some functions for dot product, cross product and I think Processing has these too.

Suppose C = A X B. If I already have B and C, I want to derive A. Apparently, this is the holy grail of vector algebra and Diego Saa makes it sound simple.

I still don’t know where to start. The first question I have about the notation is he says A = [a,a] = {0,3,4,7}
with a = (3.4.7). So, that means the other a = 0?

He then says, B = {0,-2,2,-3} , so that would be B = [b,b} ?

Then he shows how to multiply,

A∗B=[a,a]∗[b,b]=[ab+a⋅b,ab−ba+a×b]
If the unbold a and unbold b are zeros, then wouldn’t that be the dot product of a and b is the first element and the cross product of a and b is the other 3 elements?

Well, Processing is oriented towards visual solutions and this is not much to look at being just numbers.

I duplicated his numbers though. One thing that makes me wonder is there a way to round a number. I used (int) and it truncated one of the numbers that was essentially correct and it looks wrong by 1 now.

Here’s the butchery:

double A[] = {0,3,4,7};  //new double[4];
double B[] = {0,-2,2,-3};  //new double[4];
double C[] = new double[4]; //{-19,-26,-5,14};  //new double[4];

double a[] = {3,4,7};
double b[] = {-2,2,-3};
double c[] = {-26,-5,14};

double D[] = new double[4];




//   void setup() {
//     size(127, 75, OPENGL);
     
//   }
   
   void draw() {
  

    
   C = Mult(A,B,a,b);
   
   println((int)C[0],(int)C[1],(int)C[2],(int)C[3]);

   
println(Mod(a));

D = InvConj(A,a);
double d[] = new double[3];

d[0] = D[1];
d[1] = D[2];
d[2] = D[3];



B = Mult(D,C,d,c);

println((int)B[0],(int)B[1],(int)B[2],(int)B[3]);
   

    
    
     
     
   }
   
   double[] InvConj(double A[], double a[]){
     
     double res[] = new double[4];
 res[0] = 1/(Mod(a) * -1) * 0;
 res[1] = (1/Mod(a) * -1) * a[0];
 res[2] = (1/Mod(a) * -1) * a[1];
 res[3] = (1/Mod(a) * -1) * a[2];
 
// println(res[0],res[1],res[2],res[3]);
 
 
     return res;
   }
   
   double[] Mult(double A[], double B[], double a[], double b[]){
     
    double ab[] = new double[3];

  double acrossb[] = new double[3];

    double ba[] = new double[3];
    double AB[] = new double[4];
   
    ab = aVector(A[0],b);
    ba = aVector(B[0],a);
    
   double adotb = Dot(a,b);
    acrossb = Cross(a,b);
    
    double I = Dot(a,b);
    double J[] = Subtract(ab,ba);
    double K[] = Add(J, acrossb);
    AB[0] = I;
    AB[1] = K[0];
    AB[2] = K[1];
    AB[3] = K[2];
    
    return AB;
     
     
   }
   
   double Mod(double x[]) {

    return((x[0] * x[0] + x[1] * x[1] + x[2] * x[2]));
   
   }
   
  double[] Add(double x[], double y[]) {
  double z[] = new double[3];
  for (int i = 0; i < 3; i++) {
       z[i] = x[i] + y[i];
       
      } 
    return z;
  }
  

      
  double[] Subtract(double x[], double y[]) {
  double z[] = new double[3];
  for (int i = 0; i < 3; i++) {
       z[i] = x[i] - y[i];
      } 
      return z;
  }
     
 double[] aVector(double a, double x[]) {
   double z[] = new double[3];
   z[0] = a * x[0];
   z[1] = a * x[1];
   z[2] = a * x[2];
  // z[3] = a * x[3];
   
   return (z);
   
 }
 

 
  double Dot(double x[], double y[])
 {
   return (x[0]*y[0]+x[1]*y[1]+x[2]*y[2]);
   
 }
 
 double[] Cross(double x[], double y[]){
  
   double z[] = new double[3];
   z[0] = (x[1]*y[2]) - (x[2]*y[1]);
   z[1] = (x[2]*y[0]) - (x[0]*y[2]);
   z[2] = (x[0]*y[1]) - (x[1]*y[0]);
   
   return (z);
   
 }

@HackinHarry – a tip: if you want to do a sketch that prints some computations only once, then you can put your code in setup rather than draw – or you can call noLoop() in setup or draw so that the calculations won’t run over and over.

Am I right that you are looking for a geometrically intuitive idea of an inverse cross product, as with visualizing arrows floating in a 3D space? I am assuming by inverse you do not mean the moment the example we see in this video of the red arrow changing direction.

This is NOT an area of expertise for me, but I am skeptical that there is a major missing method in the field that is solved in a Quara post. There might be some misunderstanding that resolved partly revolves around disciplinary uses of the word “inverse”? For your second question, I think you want something like this?

Finding a Missing Component of a Cross Product Given One Vector and Unknown Vector

2 Likes

Yes, sir, thank you. I put noLoop() in there. I’m just a hair less sloppy than I was a few months ago when I dove into making a star globe and you gave me a link to “spherical trigonometry”.

What I was trying to solve is given C = A X B, B and C known, find A. The second video answers that. All that four-vector stuff worked, but is like using a sledge hammer when a feather duster will do.

If you are interested in getting deeper into playing with quaternions then you might want to play with PeasyCam and check out the PeasyCam source code. I believe it uses quaternions for its internal representation of orientation.

1 Like

Yup, I’ve been playing with the source code for Peasy, actually the underlying Apache\math source. I found that has the functions I was using, so that wheel shall not be rewritten by me. I tested some and see there is some difference that I’m trying to resolve. I get complements and reverse signs, etc., so something is slightly awry.

Anyway, here’s something vaguely related that I tried today. On one of my favorite links, Navigational Algorithms , there is a further link to : http://www.yrvind.com/ Yrvind is a Swedish solo sailor who invented a fixed angle sextant he calls the Bris Sextant. I made one rather than pay $200. After getting the welder’s shade no.12 cut by a local glass company, I cut the microscope slides without much trouble and then glued it all together with epoxy. I taped it to the camera of my tablet and took some shots to see what the heck I made.

Here they are:

About an hour later, I got something very different.

1 Like

It’s getting cleaner and simpler by using the Vector3D class from apache\math that’s used by peasycam.

double Z;
double alt;

/*  double GHA = Math.toRadians(162.3366651);
 double dec = Math.toRadians(45.99798965);
 double Be = Math.toRadians(35.4000);
 double Le = Math.toRadians(26.452837);  */

double GHA = Math.toRadians(166.829);
double dec = Math.toRadians(19.335);
double Be = Math.toRadians(42.98208);
double Le = Math.toRadians(89.56648); 

void setup() {
  size(127, 75, OPENGL);
}

void draw() {
  //  AltitudeAzimuth( GHA, dec, Be, Le);

  Vector3D NP = new Vector3D(0, 0, 1);
  Vector3D U2 = new Vector3D();

  Vector3D GP = new Vector3D(GHA, dec);
  Vector3D AP = new Vector3D(Le, Be);

  Vector3D U1 = new Vector3D(); //(u1[0],u1[1],u1[2]);

  U1 = (U1.crossProduct(AP, NP));
  println("U1:   ", U1.getX(), U1.getY(), U1.getZ());

  U1 = U1.normalize();
  println("U1:   ", U1.getX(), U1.getY(), U1.getZ());

  U2 = (U2.crossProduct(U1, AP));
  //  U2 = U2.negate();
  println("U2:  ", U2.getX(), U2.getY(), U2.getZ());

  Vector3D U3 = new Vector3D();
  U3 = (U3.crossProduct(AP, GP));
  U3 = U3.normalize();

  println("U3:  ", U3.getX(), U3.getY(), U3.getZ());

  Vector3D AZ = new Vector3D( U3.crossProduct(U3, AP).getX(), 
    U3.crossProduct(U3, AP).getY(), U3.crossProduct(U3, AP).getZ()) ;
  double Z = Math.toDegrees(AZ.angle(U2, AZ));

  if (U1.dotProduct(U1, AZ) < 0.0) {
    println(Math.toDegrees(U1.dotProduct(U1, AZ)));
    Z = 360.0 - Z;
  }

  println(Z);

  // alt =  Math.toDegrees(U3.dotProduct(AP,GP));
  //  println(alt);
  alt = 90.0 - Math.toDegrees(U1.angle(AP, GP));
  println(alt);

  noLoop();
}
1 Like