Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

425
Views
Dibuje polígonos personalizados dinámicamente a partir de vértices agregados manualmente en tiempo real

Quiero crear una aplicación en la que pueda establecer puntos en el mundo real en la superficie detectada y, después de tener 4 o más puntos, cree un plano/polígono entre ellos con textura. Configuración básica del controlador:

 @IBOutlet weak var sceneView: ARSCNView! let configuration = ARWorldTrackingConfiguration() var vectors: [SCNVector3] = [] var mostBottomYAxis: Float? { didSet { for (index, _) in vectors.enumerated() { vectors[index].y = self.mostBottomYAxis ?? vectors[index].y } } } var identifier: UUID? override func viewDidLoad() { super.viewDidLoad() self.sceneView.debugOptions = [ARSCNDebugOptions.showFeaturePoints, ARSCNDebugOptions.showWorldOrigin] self.sceneView.showsStatistics = true self.configuration.worldAlignment = .gravity // Y axis is Up and Down self.configuration.planeDetection = .horizontal // Detect horizontal surfaces self.sceneView.session.run(configuration) self.sceneView.autoenablesDefaultLighting = true self.sceneView.delegate = self self.registerGestureRecognizers() }

Toque el método de gesto para agregar un vértice a la superficie:

 @objc func handleTap(sender: UITapGestureRecognizer) { let sceneView = sender.view as! ARSCNView let tapLocation = sender.location(in: sceneView) if let raycast = sceneView.raycastQuery(from: tapLocation, allowing: .estimatedPlane, alignment: .horizontal), let result = sceneView.session.raycast(raycast).first { self.addItem(raycastResult: result) } } func addItem(raycastResult: ARRaycastResult) { let transform = raycastResult.worldTransform let thirdColumn = transform.columns.3 let vector = SCNVector3(x: thirdColumn.x, y: mostBottomYAxis ?? thirdColumn.y, z: thirdColumn.z) self.vectors.append(vector) self.addItem(toPosition: vector) }

y métodos para dibujar polígonos:

 func getGeometry(forVectors vectors: [SCNVector3]) -> SCNGeometry { let polygonIndices = Array(0...vectors.count).map({ Int32($0) }) let indices: [Int32] = [Int32(vectors.count)] + /* We have a polygon with this count of points */ polygonIndices /* The indices for our polygon */ let source = SCNGeometrySource(vertices: vectors) let indexData = Data(bytes: indices, count: indices.count * MemoryLayout<Int32>.size) let element = SCNGeometryElement(data: indexData, primitiveType: .polygon, primitiveCount: 1, bytesPerIndex: MemoryLayout<Int32>.size) // MARK: - Texture let textureCoordinates = [ CGPoint(x: 0, y: 0), CGPoint(x: 1, y: 0), CGPoint(x: 0, y: 1), CGPoint(x: 1, y: 1) ] let uvSource = SCNGeometrySource(textureCoordinates: textureCoordinates) let geometry = SCNGeometry(sources: [source, uvSource], elements: [element]) return geometry } func getNode(forVectors vectors: [SCNVector3]) -> SCNNode { let polyDraw = getGeometry(forVectors: vectors) let material = SCNMaterial() material.isDoubleSided = true material.diffuse.contents = UIImage(named: "Altezo_colormix_brilant") material.diffuse.wrapS = .repeat material.diffuse.wrapT = .repeat polyDraw.materials = [material] let node = SCNNode(geometry: polyDraw) return node } extension PlacePointsForPlaneViewController: ARSCNViewDelegate { func renderer(_ renderer: SCNSceneRenderer, didUpdate node: SCNNode, for anchor: ARAnchor) { guard let planeAnchor = anchor as? ARPlaneAnchor else { return } let y = planeAnchor.transform.columns.3.y if mostBottomYAxis == nil { mostBottomYAxis = y identifier = planeAnchor.identifier } if mostBottomYAxis! > y { mostBottomYAxis = y identifier = planeAnchor.identifier } // Remove existing plane nodes node.enumerateChildNodes { (childNode, _) in childNode.removeFromParentNode() } if planeAnchor.identifier == self.identifier { if self.vectors.count > 3 { let modelNode = getNode(forVectors: self.vectors) node.addChildNode(modelNode) } } } }

Espero que sea mayormente autoexplicado. Tengo vectors que contienen puntos agregados manualmente. Quiero trabajar solo con una superficie que sea la más inferior (eso es lo que hace mostBottomYAxis e identifier ).

¿Qué estoy haciendo mal? ¿Por qué el polígono no se dibuja exactamente entre los puntos? Cuando traté de dibujar una línea entre dos puntos, funcionó.

Un problema más. ¿Cómo establecer las coordenadas de textura para dibujar correctamente la textura en el polígono y hacer que funcione no solo para 4 vértices sino para más (dinámicamente a medida que el usuario agrega más puntos y puede cambiar sus posiciones)?

Gracias por la ayuda

Resultado en aplicación de muestra

Editar: después de publicar la pregunta, probé diferentes nodos para agregar mi polígono personalizado y funciona bien si agregué a sceneView rootNode:

 sceneView.scene.rootNode.addChildNode(modelNode)

Así que esto ayuda con la posición del polígono. Pero todavía tengo problemas con la textura. ¿Cómo configurar la compensación/transformación de la textura para que funcione? Para que la textura rellene esta geometría personalizada y repita la textura en los bordes.

over 4 years ago · Santiago Trujillo
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!