Created
October 17, 2017 19:23
-
-
Save macrozone/46ad3c7b488cdbbc1b6dd9afc65dc6d6 to your computer and use it in GitHub Desktop.
react-native-arkit Cylinder from a to b
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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" | |
}} | |
/> | |
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// @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