Skip to content

Instantly share code, notes, and snippets.

@macrozone
Created October 17, 2017 19:23
Show Gist options
  • Save macrozone/46ad3c7b488cdbbc1b6dd9afc65dc6d6 to your computer and use it in GitHub Desktop.
Save macrozone/46ad3c7b488cdbbc1b6dd9afc65dc6d6 to your computer and use it in GitHub Desktop.
react-native-arkit Cylinder from a to b
import { ARKit } from 'react-native-arkit'
import React from 'react'
import type { Point3D } from '../../../types'
import { length, center, diff, distance } from '../libs/vectorUtils'
const PI_2 = Math.PI / 2
// thx https://stackoverflow.com/a/37948988/1463534
const eulerAnglesCylinder = (a, b) => {
const w = diff(a, b)
const l = length(w)
let pitchB
const lxz = Math.sqrt(w.x ** 2 + w.z ** 2)
if (w.y < 0) {
pitchB = Math.PI - Math.asin(lxz / l)
} else {
pitchB = Math.asin(lxz / l)
}
let pitch
if (w.z === 0) {
pitch = pitchB
} else {
pitch = Math.sign(w.z) * pitchB
}
let yaw
if (w.x === 0 && w.z === 0) {
yaw = 0
} else {
const inner = w.x / (l * Math.sin(pitch))
if (inner > 1) {
yaw = PI_2
} else if (inner < -1) {
yaw = PI_2
} else {
yaw = Math.asin(inner)
}
}
const roll = 0
return {
x: pitch || 0,
y: (yaw || 0) + 0.01, // small offset
z: roll || 0,
}
}
export default ({ from, to }) => (
<ARKit.Cylinder
position={center(from, to)}
eulerAngles={eulerAnglesCylinder(from, to)}
shape={{
height: distance(from, to),
radius: 0.01,
}}
material={{
lightingModel: ARKit.LightingModel.Constant,
color: "red"
}}
/>
)
// @flow
import type { Point3D } from '../../../types'
export const distance = (a: Point3D, b: Point3D): number =>
Math.sqrt((b.x - a.x) ** 2 + (b.y - a.y) ** 2 + (b.z - a.z) ** 2)
export const center = (a: Point3D, b: Point3D): Point3D => ({
x: (b.x + a.x) / 2,
y: (b.y + a.y) / 2,
z: (b.z + a.z) / 2,
})
export const diff = (a: Point3D, b: Point3D) => ({
x: b.x - a.x,
y: b.y - a.y,
z: b.z - a.z,
})
export const length = (a: Point3D) => Math.sqrt(a.x ** 2 + a.y ** 2 + a.z ** 2)
/**
* Returns the angle (rad) of the given line relative to the x axis.
*
* @param {Point} start
* @param {Point} end
*/
export const getLineAngle = (start: Point3D, end: Point3D) => {
const d = diff(end, start)
const theta = Math.atan2(d.z, d.x)
return Math.PI - theta
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment