Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

421
Vistas
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
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda