2017-08-22 6 views
-1

Je suis en train de dessiner quelques lignes courbes parallèles, l'une à côté de l'autre, mais si je les sépare en modifiant/traduisant leur position dans un axe, le résultat n'est pas ce que je cherche. Le code est simple, un bezier pour faire le chemin central et les clones avec d'autres matériaux pour les côtés.Comment faire des courbes parallèles dans three.js pour le marquage routier?

var bezier = new THREE.CubicBezierCurve3(
       new THREE.Vector3(initx, inity, 0), 
       new THREE.Vector3(cp1x, cp1y, 0), 
       new THREE.Vector3(cp2x, cp2y, 0), 
       new THREE.Vector3(finalx, finaly, 0) 
       ); 

var curvePath = new THREE.CurvePath(); 
curvePath.add(bezier); 

var path = curvePath.createPointsGeometry(5); 
path.computeLineDistances(); 

var lineMat = new THREE.LineDashedMaterial({ color: 0xFFFFFF, 
              dashSize: 3, 
              gapSize: 2, 
              linewidth: 10}); 

var curveLine = new THREE.Line(path, lineMat); 

curveLine.rotation.set(-Math.PI/2,0,0); 
curveLine.position.y = 0.1; 

var leftLine = curveLine.clone(); 
leftLine.material = matLine; 

var rightLine = curveLine.clone(); 
rightLine.material = matLine; 

leftLine.translateX(-3.5); 
rightLine.position.set(3.5,0,0); 

scene.add(curveLine); 
scene.add(leftLine); 
curveLine.add(rightLine); 

Ceci est le résultat: enter image description here

Ce sont quelques exemples de ce que je cherche:

dsource: https://pomax.github.io/bezierjs/source: https://pomax.github.io/bezierjs/

Les deux dernières images sont de la bibliothèque Bezier.js.

Je pense que l'application d'un décalage à la ligne courbe, ou dessin une autre ligne en utilisant les Normales de la première pourrait être la solution, mais je ne peux pas trouver quelque chose d'utile à faire dans la Documentation. Je pense que cela pourrait aussi être fait en traçant une ligne à une distance de l'axe tangent ou quelque chose comme ça, mais cela peut être une façon plus facile, des idées?

Je jetais un oeil sur this mais c'est pour les lignes droites.

+2

Il y a un stylo de code avec un exemple de travail [ici] (https://codepen.io/brunoimbrizi/pen/VYEWgY). Les explications sont [ici] (http://brunoimbrizi.com/unbox/2015/03/offset-curve/). La plupart des ajouts de vector2 sur le codepen sont déjà disponibles dans le cadre de three.js. – Radio

+0

@Radio C'est génial. –

+0

@Radio C'est vraiment génial, mais je cherchais un moyen plus "natif" de le faire avec three.js, bien que j'y jette un oeil et que j'essaie de le résoudre en faisant les opérations comme ça. – soiber

Répondre

0

En fin de compte, je l'ai fait par moi-même.

je calcule la tangente et la normale de la courbe principal sur ses points en utilisant getTangent() et en le tournant de 90 degrés pour obtenir la normal. J'ai créé plus de sommets pour cette normale en multipliant ses valeurs par un scalaire. Ensuite, je obtenu ce que je voulais des Normales en coordonnées monde et se connecter les créer un CatmullRomCurve3 Géométrie:

for(var i = 0.0; i <= 1.0; i += 0.2){ 

    var point = curvePath.getPointAt(i); 

    var tangent = curvePath.getTangent(i); 
    var extension1 = new THREE.Vector3(tangent.x*2, tangent.y*2, 0); 
    var extension2 = new THREE.Vector3(extension1.x*2, extension1.y*2, 0); 

    var tangentGeometry = new THREE.Geometry(); 
    tangentGeometry.vertices.push(tangent, extension1, extension2); 

    var tangentLine = new THREE.Line(tangentGeometry,greenMaterial); 
    tangentLine.position.set(point.x, point.y, point.z); 

    normal.updateMatrixWorld(); // VERY IMPORTANT 

    var normal = tangentLine.clone(); 
    normal.rotateZ(Math.PI/2); 

    var normalLastVertex = normal.geometry.vertices[2].clone(); 
    normalLastVertex.applyMatrix4(normal.matrixWorld); //convert to world coords. 

    pointsArray.push(normalLastVertex); //for using them out of the loop 

    curveLine.add(tangentLine); 
    curveLine.add(normal); 
} 

Ici, j'ai derniers sommets normals dans le tableau de points, donc je dois créer la spline les reliant hors de la boucle.

var splineCurveOffsetLeft = new THREE.CatmullRomCurve3([ 

     new THREE.Vector3((pointsArray[0].x), pointsArray[0].y, 0), 
     new THREE.Vector3((pointsArray[1].x), pointsArray[1].y, 0), 
     new THREE.Vector3((pointsArray[2].x), pointsArray[2].y, 0), 
     new THREE.Vector3((pointsArray[3].x), pointsArray[3].y, 0), 
     new THREE.Vector3((pointsArray[4].x), pointsArray[4].y, 0), 
     new THREE.Vector3((pointsArray[5].x), pointsArray[5].y, 0)   
    ]); 
splineCurveOffsetLeft.type = 'catmullrom'; 
splineCurveOffsetLeft.closed = false; 

var offsetGeometry = new THREE.Geometry(); 
offsetGeometry.vertices = splineCurveOffsetLeft.getPoints(6); 

var offsetLine = new THREE.Line(offsetGeometry, cyanMaterial); 

offsetLine.rotation.set(-Math.PI/2, 0, 0); 
offsetLine.position.y=0.1; 

scene.add(offsetLine); 

I fait la même chose pour l'autre ligne de décalage seulement inversant sa rotation, ce qui est le résultat:

Offset curve

Vert = tangentes, rouge = Normales, cyan = courbe parallèle