Реалізація AR-вимірювання відстаней та площ
AR-рулетка — одна з небагатьох AR-юзкейсів, де користувач одразу розуміє цінність. Але точність вимірювання в production виявляється болючою темою: на iPhone 11 без LiDAR похибка може досягати 5-8%, а на iPad Pro з LiDAR — менше 1%. Цю різницю потрібно чесно донести до клієнта ще на етапі проектування.
LiDAR проти SLAM-вимірювань: реальна різниця
Без LiDAR (ARKit Visual SLAM): ARKit визначає відстань через триангуляцію feature points. Точність сильно залежить від текстури поверхні, освітлення та пройденого пути камери. На відстані до 2 метрів — 2-4% похибки при гарному освітленні. На 5+ метрів — 5-10%. Монотонні поверхні (білий стіл, однотонний пол) дають +3-5% до похибки.
З LiDAR (iPhone 12 Pro+, iPad Pro): дальномер бьє прямим інфрачервоним променем, похибка — 0.5-1.5% на дистанції до 5 метрів. ARKit з sceneReconstruction: .meshWithClassification будує плотний mesh, з якого можна вибирати точки без raycast по площині.
Для додатку, де потрібна сертифікаційна точність (будівництво, страхування, нерухомість), LiDAR — не опція, а вимога. Для побутового використання SLAM достатньо.
Як будується вимірювання відстані
Користувач тапає по екрану — створюється точка в мировых координатах через raycast. Відстань між двома точками — евклідово відстань в 3D-просторі:
func distance(_ a: simd_float3, _ b: simd_float3) -> Float {
return simd_distance(a, b)
}
Для відображення лінії між точками в RealityKit — ModelEntity з MeshResource.generateBox(size:) вытянутым по вектору між точками та повернутим через simd_look(at:from:up:relativeTo:). Альтернатива — SCNGeometry з двома вершинами та примітивом .line в SceneKit.
Текстовий лейбл з відстанню — ModelEntity з MeshResource.generateText() або billboard SCNNode з SCNBillboardConstraint щоб завжди дивилася на камеру.
Вимірювання площі
Площа полігона через точки, розставлені користувачем по периметру. Алгоритм Гаусса (shoelace formula) для 2D-проекції:
func polygonArea(_ points: [simd_float3]) -> Float {
// Проецюємо на горизонтальну площину (XZ)
var area: Float = 0
let n = points.count
for i in 0..<n {
let j = (i + 1) % n
area += points[i].x * points[j].z
area -= points[j].x * points[i].z
}
return abs(area) / 2
}
Важливий нюанс: якщо точки розставлені на поверхні з уклоном (наприклад, сходинки), проекція на XZ дає занижену площу. Для нахилених поверхонь потрібна 3D-площа через cross product.
UI-паттерн для точного попадання
Crosshair в центрі екрана з індикатором confidence — користувач повинен розуміти, коли точка зафіксована достатньо точно. Якщо ARKit повертає ARRaycastResult з .estimatedPlane — показувати попередження «наведіть на поверхню». Якщо .existingPlaneGeometry — все в порядку.
Снеппинг до вже поставлених точок на відстані < 5 см в екранному просторі — обов'язковий для замикання полігона при вимірюванні площі. Без цього користувач не може точно замкнути контур.
Експорт результатів
Типові вимоги: зберегти скриншот з нанесеними вимірюваннями, експортувати дані в PDF або JSON. ARView.snapshot(saveToHDR:completion:) в RealityKit. Для PDF — UIGraphicsPDFRenderer з накладеним ARView.snapshot на схематичний план помещення.
Терміни
Лінійне вимірювання відстані з двома точками — 4-6 днів. Багатоточечне вимірювання площі з експортом — 10-14 днів. Підтримка LiDAR mesh picking — додатково 3-4 дня. Вартість розраховується індивідуально.







