Вызов функции atan в Blackberry 4.2 JDE - PullRequest
       45

Вызов функции atan в Blackberry 4.2 JDE

2 голосов
/ 21 сентября 2009

Мне нужно вычислить значение дуги загара из моего приложения Blackberry Java. К сожалению, API Blackberry 4.2 не имеет функции Math.atan (). Версия 4.6 Blackberry JDE имеет его, но не 4.2.

Кто-нибудь знает обходной путь для вычисления atan?

Ответы [ 5 ]

3 голосов
/ 21 сентября 2009

С Арктан в J2ME Стивеном Циммерманом :

// calculation functions
public class Calculation {

    // Because J2ME has no floating point numbers,
    // some sort of fixed point math is required.
    // My implementation is simply to shift 10 places.
    // for example, 1024 (>> 10) = 1
    // and 512 (>> 10) = 0.5


public static final int[] AtanTable = { 0, 1, 2, 3, 5, 6, 7, 8, 10, 11, 12,
            13, 14, 16, 17, 18, 19, 20, 21, 22, 23, 25, 26, 27, 28, 29, 
            30, 30,31, 32, 33, 34, 35, 36, 37, 37, 38, 39, 40, 40, 41, 
            42, 43, 43, 44, 45 };

    // / returns angle 0->359 in degrees
    public static int atan(int Y, int X) {
        boolean swap = false;

        int top = Math.abs(Y);
        int bottom = Math.abs(X);
        if (top > bottom) {
            int btemp = bottom;
            bottom = top;
            top = btemp;
            swap = true;
        } else if (bottom == 0)
            return -300;

        // this should keep index inbounds [0, 45]
        int index = (top * 45) / bottom;
        int angle = AtanTable[index];

        if (swap)
            angle = 90 - angle;

        // X & Y += 180
        // X & !Y = ...90
        // !X & Y = ... 270
        if ((X < 0) && (Y < 0))
            angle += 180;
        else if (Y < 0) {
            angle = 90 - angle;
            angle += 270;
        } else if (X < 0) {
            angle = 90 - angle;
            angle += 90;
        }

        if (angle == 360)
            angle = 0;

        return angle;
    }
}
2 голосов
/ 21 сентября 2009

Когда все остальное терпит неудачу, можно, вероятно, получить приличное значение, оценивая результат бесконечного ряда функции arctan.

Страница Википедии об обратных тригонометрических функциях содержит раздел о бесконечном ряду обратных тригонометрических функций, включая arctan. Чтобы получить оценку, нужно проводить бесконечные ряды, пока не будет достигнута желаемая точность.

Что касается причины, по которой функция arctan не включена, это, вероятно, связано с тем, что процессор в Blackberry не очень мощный и потребует много ресурсов процессора для выполнения вычислений.

Также, глядя на документацию по API Blackberry JDE 4.2, можно найти математическую библиотеку с фиксированной точкой под названием Fixed32, которая предлагает два варианта арктана. Они выполняют вычисления с 32-разрядными целыми числами, поэтому они, вероятно, предлагают некоторые преимущества в производительности по сравнению с выполнением арифметики с плавающей точкой.

1 голос
/ 22 февраля 2012

У меня была такая же проблема ... недостающие математические функции можно найти в следующем пакете:

net.rim.device.api.util.MathUtilities

1 голос
/ 22 сентября 2009

Вот функция, которую я использую (нет гарантий, что она очень быстрая):

/** Square root from 3 */
final static public double SQRT3 = 1.732050807568877294;

static public double atan(double x)
{
    boolean signChange=false;
    boolean Invert=false;
    int sp=0;
    double x2, a;
    // check up the sign change
    if(x<0.)
    {
        x=-x;
        signChange=true;
    }
    // check up the invertation
    if(x>1.)
    {
        x=1/x;
        Invert=true;
    }
    // process shrinking the domain until x<PI/12
    while(x>Math.PI/12)
    {
        sp++;
        a=x+SQRT3;
        a=1/a;
        x=x*SQRT3;
        x=x-1;
        x=x*a;
    }
    // calculation core
    x2=x*x;
    a=x2+1.4087812;
    a=0.55913709/a;
    a=a+0.60310579;
    a=a-(x2*0.05160454);
    a=a*x;
    // process until sp=0
    while(sp>0)
    {
        a=a+Math.PI/6;
        sp--;
    }
    // invertation took place
    if(Invert) a=Math.PI/2-a;
    // sign change took place
    if(signChange) a=-a;
    //
    return a;
}    
0 голосов
/ 27 января 2010

Сначала внедрить стандарт arctan(x), используя серию Тейлора (как описано в http://en.wikipedia.org/wiki/Inverse_trigonometric_functions#Infinite_series)

Выполните следующие действия перед вызовом arctan:

1) Сначала выполните эту проверку.

  if (x == 0) {
    return 0;        
  }

2) если |x| > 1, вычислите arctan(1/x) и, наконец, вычтите результат из Pi/2

3) если |x| близко к 1, вычислите арктан полуугольника, используя формулу полу угла arctan(x) = 2*arctan(x/(1+sqrt(1+x*x))). То есть сначала вычислите половину угла, а затем умножьте результат на 2. В противном случае, для |x|, близкого к 1, арктан сходится очень медленно.

...