2016-04-04 4 views
0

3つの座標、つまりstart、mid、endを指定することで、three.jsでスプラインを描くことができます。そうすると、カーブは 'start'の座標から始まり、途中まで上がり、 'end'の座標まで下がります。これは同じもののjsbinです。three.jsでスプラインの下がり半分だけを描画する方法

しかし、ここではスプラインの下半分、つまり '中'から '終わり'の部分だけを描画したいと思います。

これは伝統的なスプラインです。 enter image description here

ただし、以下のように、下半分しか取得しませんが、シーンに合わせたいと思います。 enter image description here

編集:私は「シーンに合わせ」するだけ落ちる部分を望むについて言及

<html> 
<body> 
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r75/three.js"></script> 

<script> 
    // global variables 
    var renderer; 
    var scene; 
    var camera; 
    var geometry; 

    var control; 

    var count = 0; 
    var animationTracker; 

    init(); 
    drawSpline(); 

    function init() 
    { 
     // create a scene, that will hold all our elements such as objects, cameras and lights. 
     scene = new THREE.Scene(); 

     // create a camera, which defines where we're looking at. 
     camera = new THREE.PerspectiveCamera(45, window.innerWidth/window.innerHeight, 0.1, 1000); 

     // create a render, sets the background color and the size 
     renderer = new THREE.WebGLRenderer(); 
     renderer.setClearColor(0x000000, 1.0); 
     renderer.setSize(window.innerWidth, window.innerHeight); 

     // position and point the camera to the center of the scene 
     camera.position.x = 0; 
     camera.position.y = 40; 
     camera.position.z = 40; 
     camera.lookAt(scene.position); 

     // add the output of the renderer to the html element 
     document.body.appendChild(renderer.domElement); 
    } 

    function drawSpline(numPoints) 
    { 
     var numPoints = 100; 
//  var start = new THREE.Vector3(-5, 0, 20); 
     var start = new THREE.Vector3(-5, 0, 20); 
     var middle = new THREE.Vector3(0, 35, 0); 
     var end = new THREE.Vector3(5, 0, -20); 

     var curveQuad = new THREE.QuadraticBezierCurve3(start, middle, end); 

     var tube = new THREE.TubeGeometry(curveQuad, numPoints, 0.5, 20, false); 
     var mesh = new THREE.Mesh(tube, new THREE.MeshNormalMaterial({ 
      opacity: 0.9, 
      transparent: true 
     })); 

     scene.add(mesh); 
     renderer.render(scene, camera); 
    } 
</script> 
</body> 
</html> 

以下のコードを追加します。私が意味していたのは、画像全体が占有しているほど、落ちる部分だけが占めることです。さもなければ、スプラインから「中間」の後に頂点だけを切り取ると、下の2番目の画像(塗料を使用して切り取ったもの)のように、スプラインの一部が非常に小さくなります。

+0

あなたのjsBinは出力を生成しません。また、jsBinはinit、drawLine、drawSplineの3つの関数を定義していますが、drawLineは呼び出されない/呼び出されることはありません。 –

+0

@AndrewWillems、あなたは出力を見ることができなかったことをお詫びします。私はもう一度点検し、私はそれを見ることができる。上記のコードを投稿してください。はい、drawLine()は不要ですが、無視することができます。 – PepperBoy

+0

あなたのコメント/レスポンスの後にチェックしたところ、あなたのjsBinはFirefox(v45.0.1)では動作しませんが、Chromeでは動作します(v49.0.2623.87)。 –

答えて

1

以下に、3D二次ベジェ曲線の半分(または任意の割合)を描く方法を示します。数学はDeCasteljauのアルゴリズムに基づいています(私が正しく理解していれば)。数式は、コードに含まれている余分な関数、つまりsplitQuadraticBezierCurvegetPointAtTに表示されます。 THREE.jsには、getPointAtT、特にgetPointと似たような機能があり、getTangent機能もあります。しかし、私はまだgetTangentの使い方を知らないので、数学を自分で実装するだけでした。とにかくそれほど難しいことではありません。

enter image description here

ベクトル(またはポイント)のためvスタンド、およびv0v1v2があなたの初期から取得されています

曲線を分割するの背後にある基本的な原理は、より良い次の図で理解することができます元のstart,middleおよびendポイントです。 v01v12の距離はt(あなたの場合は0.5)です。v012の距離はtで、v01v12の間です。この関数は、元の2次曲線の最初の(要素0)と2番目の(要素1)「半分」の2要素配列を返します。最初の「ハーフ」曲線の開始点、中間点および終了点は、v0,v01 & v012です。第2の「ハーフ」曲線の開始点、中間点および終了点は、v012,v12 & v2です。

コードは、第二の「半分」曲線は、次の画像を生成する:

enter image description here

この画像は、手動でトリミングされます。画面を「塗りつぶす」形を得ることは手動で行われました。これを行うには、プログラマチックに「塗りつぶし」することは、あなたが変更しようとしていること、および/または変更することに関心のあるもの、すなわちカメラの位置に依存します。カメラの角度?カメラの視野?オブジェクトの位置?ビューの幅/高さ/比率?したがって、私はここでそれを扱っていない。しかし、この答えが少なくとも二次ベジェ曲線を分割する方法を示してくれることを願っています。

// global variables 
var renderer; 
var scene; 
var camera; 
var geometry; 

var control; 

var count = 0; 
var animationTracker; 

init(); 
drawSpline(); 

function init() 
{ 
    // create a scene, that will hold all our elements such as objects, cameras and lights. 
    scene = new THREE.Scene(); 

    // create a camera, which defines where we're looking at. 
    camera = new THREE.PerspectiveCamera(20, window.innerWidth/window.innerHeight, 0.1, 1000); 

    // create a render, sets the background color and the size 
    renderer = new THREE.WebGLRenderer(); 
    renderer.setClearColor(0x000000, 1.0); 
    renderer.setSize(window.innerWidth, window.innerHeight); 

    // position and point the camera to the center of the scene 
    camera.position.set(0, 40, 40); 
    camera.lookAt(new THREE.Vector3(0, 15, 0)); 

    // add the output of the renderer to the html element 
    document.body.appendChild(renderer.domElement); 
} 

function getPointAtT(vA, vB, t) { 
    return new THREE.Vector3(
     vA.x + (vB.x - vA.x) * t, 
     vA.y + (vB.y - vA.y) * t, 
     vA.z + (vB.z - vA.z) * t 
    ); 
} 

function splitQuadraticBezierCurve(quad, t) { 
    var v0 = quad.v0; 
    var v1 = quad.v1; 
    var v2 = quad.v2; 
    var v01 = getPointAtT(v0, v1, t); 
    var v12 = getPointAtT(v1, v2, t); 
    var v012 = getPointAtT(v01, v12, t); 
    var firstHalf = new THREE.QuadraticBezierCurve3(v0, v01, v012); 
    var secondHalf = new THREE.QuadraticBezierCurve3(v012, v12, v2 ); 
    return [firstHalf, secondHalf]; 
} 

function drawSpline() 
{ 
    var numPoints = 100; 
    var start = new THREE.Vector3(-5, 0, 20); 
    var middle = new THREE.Vector3(0, 30, 0); 
    var end = new THREE.Vector3(5, 0, -20); 

    var curveQuad = new THREE.QuadraticBezierCurve3(start, middle, end); 
    var FIRST_HALF = 0; 
    var SECOND_HALF = 1; 
    var curveProportion = 0.5; 
    var secondHalfCurveQuad = splitQuadraticBezierCurve(curveQuad, curveProportion)[SECOND_HALF]; 
    var tube = new THREE.TubeGeometry(secondHalfCurveQuad, numPoints, 0.5, 20, false); 
    var mesh = new THREE.Mesh(tube, new THREE.MeshNormalMaterial({ 
     opacity: 0.9, 
     transparent: true 
    })); 

    scene.add(mesh); 
    renderer.render(scene, camera); 
} 
+0

Andrewに感謝します。これは非常に便利で気の利いたものでした。 – PepperBoy

関連する問題