# Math to rotate according to gravity

**URL:** <https://forum.electromage.com/t/math-to-rotate-according-to-gravity/3600>\
**Category:** Patterns and Code\
**Created:** [June 14, 2024, 6:56pm UTC](https://forum.electromage.com/t/math-to-rotate-according-to-gravity/3600 "2024-06-14T18:56:48Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![nick](https://forum.electromage.com/letter_avatar_proxy/v4/letter/n/f9ae1b/32.png) [@nick](https://forum.electromage.com/u/nick)\
**Post date:** [June 14, 2024, 6:56pm UTC](https://forum.electromage.com/t/math-to-rotate-according-to-gravity/3600/1 "2024-06-14T18:56:48Z")

</div>

Does anyone have the math ready written to work out what to pass to `rotate()` so that `render2D()` output visually appears static regardless of rotation of the device? (Using SB 1.0 data)

In other words, I’d like to display a 2D pattern where gravity orients the pattern.

I started to read through [glowflow/Accelerometer Tilt 3D at master · Roger-random/glowflow · GitHub](https://github.com/Roger-random/glowflow/blob/master/Accelerometer%20Tilt%203D) which seems to be the most complete example of reacting to gravity, but, it’s a 3D pattern and maybe is specifically for tubes rather than planes, so I’m worried even if I do manage to understand it, it won’t apply to what I’m doing in a way that I myself can convert over.

---

<div class="post-metadata">

**Author:** ![GeekMomProjects](https://forum.electromage.com/user_avatar/forum.electromage.com/geekmomprojects/32/749_2.png) [@GeekMomProjects](https://forum.electromage.com/u/GeekMomProjects)\
**Post date:** [June 15, 2024, 6:28am UTC](https://forum.electromage.com/t/math-to-rotate-according-to-gravity/3600/2 "2024-06-15T06:28:37Z")

</div>

How many degrees of freedom does your matrix have? Will it be pivoting around a single axis only, or can it rotate around more than one axis?

---

<div class="post-metadata">

**Author:** ![nick](https://forum.electromage.com/letter_avatar_proxy/v4/letter/n/f9ae1b/32.png) [@nick](https://forum.electromage.com/u/nick)\
**Post date:** [June 15, 2024, 9:10am UTC](https://forum.electromage.com/t/math-to-rotate-according-to-gravity/3600/3 "2024-06-15T09:10:07Z")

</div>

It’s a flat panel wearable on a necklace - actually using a battery system inspired by you! - but held in position against the body so it can rotate around Z as the person leans left and right. Rotation around Y and X can be ignored. This means that X, Y, or between them will be pointing downwards. X at `0.020` (1g) when that’s pointing down, or Y when that is ([https://electromage.com/docs/sensor-expansion-board#accelerometer](https://electromage.com/docs/sensor-expansion-board#accelerometer))

I can probably go from [javascript - Trigonometry calculate tilt angle from accelerometer data - Stack Overflow](https://stackoverflow.com/questions/72946477/trigonometry-calculate-tilt-angle-from-accelerometer-data) to what I need, so I’ll give that a go today or tomorrow and see if I can work it out (if anyone has it ready-to-go in a copy/paste format, I’d still gratefully accept that and leave my learning for some other part!)

---

<div class="post-metadata">

**Author:** ![wizard](https://forum.electromage.com/user_avatar/forum.electromage.com/wizard/32/4_2.png) [@wizard](https://forum.electromage.com/u/wizard)\
**Post date:** [June 15, 2024, 3:43pm UTC](https://forum.electromage.com/t/math-to-rotate-according-to-gravity/3600/4 "2024-06-15T15:43:07Z")

</div>

Hi @nick ,  
The `atan2(y, x)` function has 90% what you need. It will return an angle in rads.

```auto
export var accelerometer
var angleCorrectionRads

//show a gauge as a level
export function gaugeLevel() {
  return 1 - abs(angleCorrectionRads / PI)
}

export function beforeRender(delta) {
  //measure the angle of the current accelerometer force
  var currentAngleRads = atan2(accelerometer[0], accelerometer[1])
  
  //you may need to reverse this angledepending on the 
  //sensor board orientation relative to the LEDs
  currentAngleRads = -currentAngleRads
  
  //smooth this out a little to reduce noise in the accelerometer samples
  angleCorrectionRads = mix(angleCorrectionRads, currentAngleRads, .02)
  
  //apply this angle as a rotation
  //first reset the transform
  resetTransform()
  //center coordinates so we rotate around the center, not the corner
  translate(-.5, -.5) 
  //rotate by the correction angle
  rotate(angleCorrectionRads)
}

export function render2D(index, x, y) {
  //draw a vertical line
  var v = clamp(1 - abs(y*5), 0, 1)
  hsv(x + .5, 1, v*v)
}

```

[Accelerometer level example.epe](https://forum.electromage.com/uploads/short-url/9hBrAtnxNe627x55dauo3KjVIlQ.epe) (7.5 KB)

---

<div class="post-metadata">

**Author:** ![nick](https://forum.electromage.com/letter_avatar_proxy/v4/letter/n/f9ae1b/32.png) [@nick](https://forum.electromage.com/u/nick)\
**Post date:** [June 15, 2024, 10:07pm UTC](https://forum.electromage.com/t/math-to-rotate-according-to-gravity/3600/5 "2024-06-15T22:07:27Z")

</div>

Thank you @wizard , and especially this pattern has a few tips in that are very useful to know about! The `mix()` for smoothing is great, and useful to be reminded of the gauge feature to help debugging. I also hadn’t realised (read properly) that a `resetTransform()` and `translate()` would be necessary so useful to see that.

It’s working well, thank you!
