Shop OBEX P1 Docs P2 Docs Learn Events
Arccos?! — Parallax Forums

Arccos?!

JacEJacE Posts: 6
edited 2010-03-12 09:37 in General Discussion
Hi Guys,

for my autopilot i have do make some arccos and SQRT Operations (Navigation), but i dont know how to.

I could write arccos as 1/cos(...) but i think this doesnt work.

I still use the yahoo Integermath class for other operations.

Edit:
Is there any possibility for making divisions which could return floating point results?

Division and Arccos is used by this: cos(w)=(dz*dlong)/(|dz|*|dlong|) I need w for my traveldirection.

Post Edited (JacE) : 11/18/2009 4:27:18 PM GMT

Comments

  • Peter VerkaikPeter Verkaik Posts: 3,956
    edited 2009-11-18 18:31
    Go here
    http://tech.groups.yahoo.com/group/JavelinCode/files/Javelin%20Stamp%20IDE/lib/stamp/math/

    and get Trig.java (for arccos) and UnsignedIntMath.java (for sqrt)

    Both files must be placed in the folder ...\lib\stamp\math

    regards peter
  • JacEJacE Posts: 6
    edited 2009-11-25 15:03
    Thanks Peter, that helps me a lot.

    Even now my problem is: dividing x and y for deg=arctan(y/x). Y and x are both a part of the position coordinates (i only remove the degree(x=long, y=lat))

    Abrasive i try to get the angle, which points towards my target.

    I've got my present position in latitude and longitude, and i've got the target position in the same way. Now i try to get the angle between my y-axis and the target with 90-deg.

    Certainly i could multiply x and y with big integers, but that wouldn't fix the problem that i get double results.

    I've no idea how to deal with this problem.

    Okay, i've tried a first solution. it works, but only with small and positive digits:
    public static int divide(int denom, int numer)
      {
       result=0;
       denom=denom*100;
       while(denom-numer>=0) {
        denom=denom-numer;
        result++;
       }
       return result;
      }
    

    Post Edited (JacE) : 11/25/2009 4:51:50 PM GMT
  • Peter VerkaikPeter Verkaik Posts: 3,956
    edited 2009-11-25 17:09
    You can use deg = atan2(y,x)
    then x and y are scaled and then the division y/x is done.

    regards peter
  • JacEJacE Posts: 6
    edited 2009-11-25 22:03
    Thank you very much peter, it works fine [noparse]:)[/noparse]
  • StereoPonyzStereoPonyz Posts: 82
    edited 2009-12-11 17:01
    Hi peter, i will need this library to calculate some angles too. I had followed ur instruction by placing Trig and Unsigned into math folder. But how to compile the their test files? i got err when compiled
    793 x 814 - 91K
  • Peter VerkaikPeter Verkaik Posts: 3,956
    edited 2009-12-11 18:22
    Place attached file in ...\lib\stamp\util\text folder.
    Create text folder first if it does not exist.

    regards peter
  • StereoPonyzStereoPonyz Posts: 82
    edited 2010-03-11 08:23
    Hi Peter, may i know how to print floating number?

    I have used your Trigo file to do some computation, and i divide all the results by 10000 to obtain the exact values. But in doing so, i truncated all the decimal values.

    So, I have checked on the net and found that to print floating number can to use: "%7.2f",
    However, using Format.printf("%7.2f ",y0); resulted in compiling error.

    import stamp.math.*;
    import stamp.util.text.*;

    public class f {

    static void main() {
    int h,i,j,value;
    int sine, cosine;
    int R = 35;
    float x0, y0;

    Format.printf("sin(x)\n");
    for (i=0; i<=3600; i+=45) {
    Format.printf("%6d ",i/10);
    sine = Trig.sin(i);
    Format.printf("%6d ",sine);
    x0 = R*(sine/10000);
    Format.printf("%7.2f ",x0);

    cosine = Trig.cos(i);
    Format.printf("%6d ",cosine);
    y0 = R*(sine/10000);
    Format.printf("%7.2f ",y0);

    Format.printf("\n");
    }
    }

    }
    502 x 510 - 19K
    724 x 572 - 23K
  • Peter VerkaikPeter Verkaik Posts: 3,956
    edited 2010-03-11 08:56
    The trig class does not use floating point variables (because Javelin does not support it),
    rather it uses integers to represent real numbers.
    You need to split the printing to an integer part and fractional part.

    For example,·a result in range -1800 to +1799 representing -180.0 to +179.9 degrees

    int integerpart = result/10; //signed integer part
    int fraction = (result < 0) ? (-result) % 10 : result % 10; //unsigned fraction
    Format.printf("%d.",integerpart);
    Format.printf("%01d",fraction); //the fraction must be printed with padded zeroes

    regards peter
  • StereoPonyzStereoPonyz Posts: 82
    edited 2010-03-11 09:11
    Hi Peter, i have multiply all my sine and cosine terms with 35. I noticed that if the values are started off as a big number it wil have computational error like in the case for COS(X). But once cos(x) reduce to -0 and start counting up the mutiplication goes correct again.

    for (i=0; i<=3600*4; i+=45) {
    Format.printf("%6d ",i/10);

    sine = Trig.sin(i/4); //Calculation Up to 1 Decimal pt ONLY
    Format.printf("%6d ",sine);
    x0 = R*(sine);
    Format.printf("%8d ",x0);

    cosine = Trig.cos(i/4);
    Format.printf("%6d ",cosine);
    y0 = R*(cosine);
    Format.printf("%8d ",y0);
    371 x 504 - 78K
  • Peter VerkaikPeter Verkaik Posts: 3,956
    edited 2010-03-11 09:34
    Not sure what you are trying to do
    but R*(sine) might overflow for R>3 because sine has range -10000 to +10000
    representing -1.0000 to +1.0000

    The UnsignedIntMath class provides the methods to do this multiplication
    without overflow.

    //sine is 10000 based fraction
    boolean·negative = (sine < 0);
    int sine16 = UnsignedIntMath.dec2frac(UnsignedIntMath.abs(sine)); //convert to 65536 based fraction
    //multiply integer by usigned fraction
    int result = UnsignedIntMath.umulf(UnsignedIntMath.abs(R),sine16);·//calculate·R*fraction, result is smaller than·R
    if (negative) result = -result;
    if (R < 0) result = -result; //only if R is signed value

    regards peter
    ·
  • StereoPonyzStereoPonyz Posts: 82
    edited 2010-03-12 08:16
    Thank you Peter. Using this method, the answer will always round off to the nearest whole number?

    Post Edited (StereoPonyz) : 3/12/2010 8:36:04 AM GMT
    354 x 593 - 19K
  • Peter VerkaikPeter Verkaik Posts: 3,956
    edited 2010-03-12 09:37
    You may want to change the code a little

    int result;
    //sine is 10000 based fraction
    boolean·negative = (sine < 0);
    int sine16 = UnsignedIntMath.dec2frac(UnsignedIntMath.abs(sine)); //convert to 65536 based fraction
    //multiply integer by unsigned fraction
    switch (sine) {
    · case -10000:
    · case 10000:
    ··· result = UnsignedIntMath.abs(R); //calculate·R*1
    ··· break;
    · default:
    ····result = UnsignedIntMath.umulf(UnsignedIntMath.abs(R),sine16);·//calculate·R*fraction, result is smaller than·R
    }
    if (negative) result = -result;
    if (R < 0) result = -result; //only if R is signed value

    If you specify R with decimals, for example R = 4000 representing 4.000
    then you will get a result 0 to 4000 representing 0.000 to 4.000

    regards peter
Sign In or Register to comment.