# More efficent ways to get PVector heading or atan2

**URL:** <https://discourse.processing.org/t/more-efficent-ways-to-get-pvector-heading-or-atan2/4706>\
**Category:** Coding Questions\
**Created:** [October 21, 2018, 8:40am UTC](https://discourse.processing.org/t/more-efficent-ways-to-get-pvector-heading-or-atan2/4706 "2018-10-21T08:40:35Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![Sarah](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/sarah/32/1675_2.png) [@Sarah](https://discourse.processing.org/u/Sarah)\
**Post date:** [October 21, 2018, 8:40am UTC](https://discourse.processing.org/t/more-efficent-ways-to-get-pvector-heading-or-atan2/4706/1 "2018-10-21T08:40:35Z")

</div>

Hi,

I’ve been experimenting on some steering behaviors, and some of the functions need the velocities heading, but it seemed that `PVector.heading()` takes up a lot of CPU as it uses `atan2()` and makes the sketch run slower.

In a sketch with 5000 boids, `.heading()` uses over 30% of the CPU (based on profiler info). Is there any way to optimize the function, or to have it more efficient with around the same results? (It doesn’t need it to be so accurate)

Any questions or advice are welcome,  
Thanks!

---

<div class="post-metadata">

**Author:** ![GoToLoop](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/gotoloop/32/86_2.png) [@GoToLoop](https://discourse.processing.org/u/GoToLoop)\
**Post date:** [October 21, 2018, 10:24am UTC](https://discourse.processing.org/t/more-efficent-ways-to-get-pvector-heading-or-atan2/4706/2 "2018-10-21T10:24:17Z")

</div>

> [@Sarah](#):
>
> (It doesn’t need it to be so accurate)

I’ve found this supposedly faster but inaccurate **atan2()** alternative at: 👨‍🔬

> <https://github.com/libgdx/libgdx/blob/gdx-parent-1.9.8/gdx/src/com/badlogic/gdx/math/MathUtils.java#L84-L100>

And adapted it as a custom subclass named VecFast, which `@Override` PVector::**heading()** method: 🤩

```java
/**
 * Atan2Fast() for PVector::heading() (v1.0.4)
 * GoToLoop (2018/Oct/21)
 *
 * https://Discourse.Processing.org/t/
 * more-efficent-ways-to-get-pvector-heading-or-atan2/4706/2
 */

//import processing.core.VecFast;

void setup() {
  final PVector vecFast = new VecFast(THIRD_PI, TAU);
  final PVector vecSlow = vecFast.get();

  println("Fast:", vecFast.heading()); // Fast: 1.405416
  println("Slow:", vecSlow.heading()); // Slow: 1.4056476

  exit();
}

//package processing.core; // Comment this out in "VecFast.java".

static // Comment this keyword if this class is placed in "VecFast.java".
  public final class VecFast extends PVector {
  public VecFast() {
  }

  public VecFast(final float x, final float y) {
    super(x, y);
  }

  public VecFast(final float x, final float y, final float z) {
    super(x, y, z);
  }

  @Override public final float heading() {
    return atan2Fast(y, x);
  }

  /*
   * Apache 2 (2011): https://libGDX.BadLogicGames.com/source.html
   *
   * https://GitHub.com/libgdx/libgdx/blob/gdx-parent-1.9.8/
   * gdx/src/com/badlogic/gdx/math/MathUtils.java#L84-L100
   *
   * Mod: GoToLoop (v1.0) (2018/Oct/21)
   * https://Discourse.Processing.org/t/
   * more-efficent-ways-to-get-pvector-heading-or-atan2/4706/2
   */

  /**
   * Returns atan2 in radians, faster but less accurate than Math.atan2.
   * Average error of 0.00231 radians (0.1323 degrees),
   * largest error of 0.00488 radians (0.2796 degrees).
   */
  static public final float atan2Fast(final float y, final float x) {
    if (x == 0f) return HALF_PI * Math.signum(y);

    final float z = y / x, atan;

    if (Math.abs(z) < 1f) {
      atan = z / (z * z * .28f + 1f);
      return x >= 0f? atan : atan + (y < 0f? -PI : PI);
    }

    atan = HALF_PI - z / (z * z + .28f);
    return y >= 0f? atan : atan - PI;
  }
}

```

---

<div class="post-metadata">

**Author:** ![Sarah](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/sarah/32/1675_2.png) [@Sarah](https://discourse.processing.org/u/Sarah)\
**Post date:** [October 21, 2018, 11:23am UTC](https://discourse.processing.org/t/more-efficent-ways-to-get-pvector-heading-or-atan2/4706/3 "2018-10-21T11:23:41Z")

</div>

Thanks so much, it works perfectly! Also never knew you could override classes like that. 🙂
