- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我正在制作一个应用程序来计算距离和面积,现在问题是我制作了一个数组并在其中附加了我的节点。
func calculate () {
let start = dotNodes[0]
let end = dotNodes[1]
let a = end.position.x - start.position.x
let b = end.position.y - start.position.y
let c = end.position.z - start.position.z
let distance = sqrt(pow(a,2) + pow(b,2) + pow(c, 2))
updateText(text:"\(abs( distance))", atPosition: (end.position))
}
现在起点是 0 索引,结束点是索引 1 但这只是两个点。我怎样才能计算出从 2 到 3 和 3 到 4 等等的距离,最后当最后一个点接触到点 1 时它应该给我面积?
最佳答案
正如@Maxim 所说,您可以从简化计算开始^______^。
不过,我会尝试使用 GLK 数学辅助方法来回答您的问题,如果您有兴趣,可以在此处阅读更多相关信息:GLK Documentation .
本质上,您需要做的是遍历您的位置数组,并以 2 为单位计算这些位置之间的距离。当您的最后一次迭代只有一个元素时,您将计算它与第一个元素之间的位置.
由于我的数学不是很好,所以我在 StackOverflow 上进行了快速搜索以找到解决方案,并利用了@Gasim 在帖子 Iterate Over Collections Two At A Time In Swift 中提供的答案。 .
由于我的尝试很长,我没有一步一步地完成每个部分,而是提供了完整评论的答案,希望能为您指明正确的方向。
一如既往,如果其他人可以帮助重构和/或改进代码,请随意:
//
// ViewController.swift
// Measuring Example
//
// Created By Josh Robbins (∩`-´)⊃━☆゚.*・。゚* on 27/04/2019.
// Copyright © 2019 BlackMirrorz. All rights reserved.
//
import UIKit
import ARKit
class ViewController: UIViewController {
@IBOutlet weak var augmentedRealityView: ARSCNView!
var augmentedRealityConfiguration = ARWorldTrackingConfiguration()
var augmentedRealitySession = ARSession()
var markerNodes = [SCNNode]()
typealias NodeNameData = (name: String, node: SCNNode)
typealias DistanceData = (distance: Float, positionA: GLKVector3, positionB: GLKVector3)
//---------------------
//MARK:- Initialization
//---------------------
override func viewDidLoad() {
super.viewDidLoad()
setupARSession()
}
/// Sets Up Our ARSession
func setupARSession(){
augmentedRealityView.session = augmentedRealitySession
augmentedRealitySession.run(augmentedRealityConfiguration, options: [.removeExistingAnchors, .resetTracking])
}
/// Creates A Node To Mark The Touch Position In The Scene
///
/// - Returns: SCNNode
func markerNode() -> SCNNode{
let node = SCNNode(geometry: SCNSphere(radius: 0.01))
node.geometry?.firstMaterial?.diffuse.contents = UIColor.cyan
return node
}
//------------------------
//MARK:- Marker Placemenet
//------------------------
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
//1. Get The Users Current Touch Point & Check We Have A Valid HitTest Result
guard let touchPoint = touches.first?.location(in: self.augmentedRealityView),
let hitTest = self.augmentedRealityView.hitTest(touchPoint, types: .featurePoint).first
else { return }
//2. Get The World Transorm & Create An SCNNode At The Converted Touch Position
let transform = hitTest.worldTransform
let node = markerNode()
node.position = SCNVector3(transform.columns.3.x, transform.columns.3.y, transform.columns.3.z)
self.augmentedRealityView.scene.rootNode.addChildNode(node)
//3. Add The Node To Our Markers Array So We Can Calculate The Distance Later
markerNodes.append(node)
//4. If We Have 5 Marker Nodes Then Calculate The Distances Between Them & Join Them Together
if markerNodes.count == 5{
calculateMarkerNodeDistances()
markerNodes.removeAll()
}
}
//-------------------
//MARK:- Calculations
//-------------------
/// Enemurates Our Marker Nodes & Creates A Joining Node Between Them
func calculateMarkerNodeDistances(){
var index = 0;
while index < markerNodes.count {
let nodeA = markerNodes[index];
var nodeB : SCNNode? = nil;
if index + 1 < markerNodes.count {
nodeB = markerNodes[index+1];
}
//1. Create A Joining Node Between The Two Nodes And Calculate The Distance
if let lastNode = nodeB{
let nodeA = NodeNameData("Node \(index)", nodeA)
let nodeB = NodeNameData("Node \(index+1)", lastNode)
self.augmentedRealityView.scene.rootNode.addChildNode(joiningNode(between: [nodeA, nodeB]))
}else{
//2. Here We Can Assume The We Have Reached The Last Node So We Calculate The Distance Between The 1st & Last Nodes
guard let initialNode = markerNodes.first, let lastNode = markerNodes.last else { return }
let nodeA = NodeNameData("Node 0 ", initialNode)
let nodeB = NodeNameData("Node \(markerNodes.count)", lastNode)
self.augmentedRealityView.scene.rootNode.addChildNode(joiningNode(between: [nodeA, nodeB]))
}
//Increment By 1 So We Join The Nodes Together In The Correct Sequence e.g. (1, 2), (3, 4) And Not (1, 2), (3, 4)
index += 1;
}
}
/// Creates A Joining Node Between Two Names
///
/// - Parameter nodes: [NodeNameData]
/// - Returns: MeasuringLineNode
func joiningNode(between nodes: [NodeNameData]) -> MeasuringLineNode{
let distance = calculateDistanceBetweenNodes([nodes[0], nodes[1]])
let joiner = MeasuringLineNode(startingVector: distance.positionA, endingVector: distance.positionB)
return joiner
}
/// Calculates The Distance Between Two SCNNodes
///
/// - Parameter nodes: [NodeNameData]
/// - Returns: DistanceData
func calculateDistanceBetweenNodes(_ nodes: [NodeNameData]) -> DistanceData{
//1. Calculate The Distance
let positionA = GLKVectorThreeFrom(nodes[0].node.position)
let positionB = GLKVectorThreeFrom(nodes[1].node.position)
let distance = GLKVector3Distance(positionA, positionB)
let meters = Measurement(value: Double(distance), unit: UnitLength.meters)
print("Distance Between Markers [ \(nodes[0].name) & \(nodes[1].name) ] = \(String(format: "%.2f", meters.value))m")
//2. Return The Distance A Positions Of The Nodes
return (distance, positionA, positionB)
}
/// Creates A GLKVector3 From An SCNVectore3
///
/// - Parameter vector3: SCNVector3
/// - Returns: GLKVector3
func GLKVectorThreeFrom(_ vector3: SCNVector3) -> GLKVector3 { return GLKVector3Make(vector3.x, vector3.y, vector3.z) }
}
//-------------------------
//MARK:- Mesuring Line Node
//-------------------------
class MeasuringLineNode: SCNNode{
/// Creates A Line Between Two SCNNodes
///
/// - Parameters:
/// - vectorA: GLKVector3
/// - vectorB: GLKVector3
init(startingVector vectorA: GLKVector3, endingVector vectorB: GLKVector3) {
super.init()
let height = CGFloat(GLKVector3Distance(vectorA, vectorB))
self.position = SCNVector3(vectorA.x, vectorA.y, vectorA.z)
let nodeVectorTwo = SCNNode()
nodeVectorTwo.position = SCNVector3(vectorB.x, vectorB.y, vectorB.z)
let nodeZAlign = SCNNode()
nodeZAlign.eulerAngles.x = Float.pi/2
let box = SCNBox(width: 0.001, height: height, length: 0.001, chamferRadius: 0)
let material = SCNMaterial()
material.diffuse.contents = UIColor.white
box.materials = [material]
let nodeLine = SCNNode(geometry: box)
nodeLine.position.y = Float(-height/2)
nodeZAlign.addChildNode(nodeLine)
self.addChildNode(nodeZAlign)
self.constraints = [SCNLookAtConstraint(target: nodeVectorTwo)]
}
required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) }
}
基于这个简单的(希望是准确的答案)结果是这样的:
Distance Between Markers [ Node 0 & Node 1 ] = 0.14m
Distance Between Markers [ Node 1 & Node 2 ] = 0.09m
Distance Between Markers [ Node 2 & Node 3 ] = 0.09m
Distance Between Markers [ Node 3 & Node 4 ] = 0.05m
Distance Between Markers [ Node 0 & Node 5 ] = 0.36m
在我的示例中,我正在计算五个节点的距离,但您可以将其称为任意点。当然,您随后还需要使用公式来计算面积本身。然而,这应该足以为您指明正确的方向。
希望对你有帮助
关于ios - 如何使用 ARKit 计算点 2 到点 3 和点 3 到点 4 的距离?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55834972/
我正在尝试绘制一个可以帮助某人了解元素尺寸的盒子,但我一直遇到一个问题,因为当我将物理元素放在飞机顶部时,我首先需要识别飞机,所以我的盒子被画了进去项目的前面。 是否有可能以某种方式克服这一点? 最佳
我正在用 swift 4 制作一个简单的标尺 ARKit 应用。 但我遇到的问题是,有时我的措施有一点偏差或完全偏差。我认为,这可能是因为 ARkit 校准不当,没有正确检测到我的表面。 我目前在 3
我一直在用 ARKit 构建一个门户,虽然构建一个虚拟环境很容易创建和移动,但我想让我进入一个重复播放 360 度视频的环境。我认为可以通过将 360 度视频作为纹理包装到球体来完成,但 ARKit
我正在尝试向场景中的每个节点添加动画。我的一个问题是,在层次结构中 - 我应该将动画添加到哪个节点。我认为它是由您实际看到的内容所代表的节点,这将是网格对象...但我有一个持有两个灯和网格对象的节点.
关闭。这个问题需要details or clarity .它目前不接受答案。 想改进这个问题吗? 通过 editing this post 添加细节并澄清问题. 关闭 2 年前。 Improve t
我正在使用 ARKit 进行 AR 项目。 我想添加一个 UIView 到 ARKit 场景。当我点击一个对象时,我想获取该对象旁边的“弹出窗口”信息。此信息位于 UIView 中。 是否可以将此 U
我想使用 Vuforia 检测标记并在其上放置一个 3d 对象。从那时起,我想在我的应用程序中使用 ARKit。我如何知道检测到的标记或 3d 对象的 ARKit 世界变换? 我正在使用相同的 Vie
我上下阅读了所有 ARKit 类的完整文档。我没有看到任何描述实际获取用户面部纹理的能力的地方。 ARFaceAnchor 包含 ARFaceGeometry(由顶点组成的拓扑和几何)和 BlendS
我正在使用 ARKit 2 和 ARWorldMapData 我创建了一个 AR 世界,它可以使用来自 link here 的 map 数据等识别您的周围环境.现在我正在尝试弄清楚如何获取所有特征点并
我正在使用 ARKit 将虚拟对象放置在真实环境中。它在 Xcode 9 和 iOS 11 中运行良好。但是当我更新 Xcode 和 iOS 时,如果我将虚拟对象放在检测到的平面上,它就会卡住,如果我
我收到关于 init() 的错误消息不适用于 ARLightEstimate . 代码: class LightSensorManager { let lightEstimate = ARLi
我需要使用 ARKit 检测虚拟对象何时与现实世界对象接触。 有什么办法可以查出来吗? 最佳答案 首先您需要创建一个符合OptionSet 协议(protocol)并具有bitset 类型属性的碰撞类
我想实现类似的东西 ARCore's raycast method它采用世界空间坐标中的任意光线而不是屏幕空间点: List hitTest (float[] origin3, int originO
嗨,我正在尝试在节点周围产生发光效果。我使用了 SCNNode 过滤器属性并设置为 CIFilter 数组。 仅当节点后面没有我不理解的节点时,它才起作用并呈现。我尝试设置渲染顺序和 readDept
我正在尝试重现 ARCamera 的项目点函数,但由于某种原因,这些值没有正确匹配。我正在使用 ARCamera 的投影矩阵和 View 矩阵并应用基本的 CG 透视变换数学,(PV) * p,但 N
我想获得所有三个轴的旋转度数。我正在尝试用横向模式来实现。当从左向右旋转设备(Y 旋转)时,我希望一旦用户设置左端并向右旋转即可覆盖度数。所以当它到达起点时我们需要 360 度。所以对于y轴旋转,使用
我正在使用新的 ARKit,并且能够创建一个名为 SphereNode 的新文件,该文件能够在 View 上创建可放置的 Sphere。 重点是我真的想添加一个自定义对象而不是标准球体。一些建议?这是
我一直在使用 ARkit 并且很喜欢它,但我注意到在负载跟踪期间可能会有点跳动(突然物体从它们的位置跳出一点点,比如 1-3 厘米)。我一直在想是否有一种方法可以平滑这些跳跃,这样就不会那么分散注意力
我正在尝试从以下内容中检索 string=Gate。 | geometryIndex=0 node= | no child> bone=(null)> MyCode 访问几何并且工作正常,如下 l
我正在尝试使用 ARKit 构建家具放置 AR 应用程序,我的项目中有 .scn 椅子及其 PNG 纹理,我的应用程序应该检测水平面,然后当用户点击时,将对象放置在点击的位置。 但是当我点击时,该对象
我是一名优秀的程序员,十分优秀!