2017-06-03 1 views
0

Ich verwende Three.js, um Punktwolkendaten aufzubereiten, die von einem Server abgerufen wurden.Hinzufügen von Punkten zu einer Punktwolke mit Mausklicks für Benutzer

Für jeden Datensatz, ich Schleife über die Datenpunkte und erstellen Sie ein Three.js Vector3-Objekt mit x, y & z Werte für jeden Datenpunkt. Ich schiebe jeden dieser Scheitelpunkte auf eine Liste, die ich dann in die Scheitelpunkt-Stütze meiner Geometriekomponente innerhalb meiner Punktkomponente übertrage.

render() { 
    this.pointCloudVertices = []; 
    if (this.props.points) { 
     const points = this.props.points 
     for (let i = 0; i < points.x.length; i++) { 
      const vertex = new THREE.Vector3(); 

      vertex.x = points.x[i] 
      vertex.y = points.y[i] 
      vertex.z = points.z[i] 

      this.pointCloudVertices.push(vertex); 
     } 
    } 
    return (<points> 
     <geometry vertices={this.pointCloudVertices}/> 
     <pointsMaterial 
      color={ (Math.floor(Math.random()*16777215)) } 
      size={ 0.2 } 
     /> 
    </points>); 
} 

https://github.com/caseysiebel/pc-client/blob/master/src/components/PointCloud.js

würde ich der Benutzer möchte in der Lage sein, ihre Maus zu verwenden, um Punkte zu einem anderen Punkt Wolke (Punkte-Komponente) hinzufügen, indem Sie innerhalb der Leinwand klicken.

Ich habe eine Menge Ressourcen gefunden, die auf den Raycaster von Three.js verweisen, aber dieses Tool scheint mehr für die Auswahl von Objekten zu sein, die sich bereits im Canvas befinden. In meinem Fall möchte ich, dass der Benutzer in der Lage ist, auf die Leinwand, die nicht von einem Objekt belegt ist, zu klicken und den x, y & z-Koordinaten dieses Klicks auszuarbeiten und dann einen Eckpunkt mit diesen x hinzuzufügen/y/z-Werte zu einer Punktkomponente (wahrscheinlich leer, bis der Benutzer über diese Modalität Punkte hinzufügt).

Ich bin ein wenig verwirrt, wie ich 2D-Mausereignisse in einen 3D-Eckpunktwert umwandeln wird. Wenn irgendjemand gute Quellen zu diesem Thema kennt, würde ich es gerne sehen.

+1

"Ich bin ein wenig verwirrt, wie ich 2D-Mausereignisse in einen 3D-Vertex-Wert konvertieren wird" 'new THREE.Vector (mouseX, mouseY, 0)' wäre die einfachste Lösung, obwohl wahrscheinlich nicht befriedigend. Ich würde sagen, an diesem Punkt ist das eher ein Designproblem als Mathe. Wie ** willst du ** diese 2D-Ebene in den 3D-Raum umwandeln? Stellen Sie sich vor, Sie sitzen in Ihrem Wohnzimmer, auf dem Sofa und zeigen in eine Richtung. Wo soll dieser Punkt hinzugefügt werden? Vor allem in welcher Tiefe/Entfernung von dir? Wie entscheidet man sich für den/die ersten Punkt (e)? Wie für die späteren? – Thomas

+0

Danke für die Antwort. Basierend auf Ihrem Kommentar, denke ich, gibt es zwei Fragen hier. Du hast Recht, wenn ich einen Punkt in einer 2D-Ebene auswähle, wirklich definiere ich einen Strahl, der sich von dort aus erstreckt, wo ich sitze (die Kameraposition) entlang der dritten Achse, die sich unendlich erstreckt. Die Frage, wo ich möchte, dass mein neuer Punkt auf diesem Strahl sitzt, ist eine Designfrage. Die Frage, wie sich die aktuelle Position der Kamera und der Ursprung, die von den Datensätzen definiert werden, auf die Ebene auswirkt, die ich betrachte, ist eine mathematische. – Casey

+0

Im Matheteil sollte die [projectionMatrix] (https://threejs.org/docs/#api/cameras/Camera.projectionMatrix) der Kamera die sein, an der Sie interessiert sind, um den Strahl zu bestimmen; aber es ist eine Weile her, dass ich THREE.js – Thomas

Antwort

1

Mit THREE.Raycaster(), sehe ich mehrere Lösungen:

1. Verwenden Sie die .at() Methode der .ray Eigenschaft. Wie folgt aus:

raycaster.ray.at(100 + Math.random() * 150, rndPoint); 

Hier können Sie die Einschränkungen für die Entfernung von dem Ursprung des Strahls eingestellt werden, und es wird so aussehen von der Original-Kamera:

front camera view

und wie es sieht aus wie von der Seite:

free camera view

jsfiddle Beispiel. Sie können die Linien dort ausschalten.

2. Verwenden Sie die .intersectObjects() Methode. Wo sich überschneidende Objekte Ebenen von Beschränkungen sind. Zum Beispiel haben wir Ebenen in Form eines Würfels. Wenn wir einen Strahl durch sie werfen, schneiden wir immer zwei Ebenen, und die Anordnung der intersektierten Objekte wird nach Entfernung vom Ursprung des Strahls sortiert. Somit ist das erste Element in diesem Array die nächste Ebene. Also, wenn wir es wissen, können wir ihre Schnittpunkte und unter Punkt1 von Punkt2, einen neuen Vektor (seine Länge und Richtung) bekommen.Und dann werden wir setzen nur einen Punkt, an einem zufälligen Ort entlang des Vektors von point1-point2:

intersected = raycaster.intersectObjects(planes.children); 
    if (intersected.length > 0){ 
    var point1 = intersected[0].point; 
    var point2 = intersected[1].point; 
    var diff = point2.clone().sub(point1); 
    var diffLength = diff.length(); 
    rndPoint = point1.clone().addScaledVector(diff.normalize(), Math.random() * diffLength); 
    . . . 
    } 

Es ist wie diese von der Frontkamera aussehen:

front camera view

und von der Seite:

free camera view

jsfiddle Beispiel. Linien sind auch hier schaltbar.

Oder Sie können THREE.Raycaster() with THREE.OrthographicCamera() verwenden. Was ist einfacher)

Verwandte Themen