Apps WebApp

005-ComputeSphere|RhinoComputeで球体を作成しReactで表示

ReactとThree.jsを活用して、RhinoComputeから取得したデータをもとに3Dの球を描画する方法をご紹介します。このチュートリアルでは、RhinoComputeから2点の頂点データを取得し、それを基に球の中心と半径を計算して描画します。

1. 背景

RhinoComputeは、Rhinoの強力な3Dモデリング機能をREST APIとして提供するツールです。今回のプロジェクトでは、以下のようなデータをAPIから取得したと仮定します。

{
  "vertices": [
    { "x": 0, "y": 0, "z": -50 },
    { "x": 0, "y": 0, "z": 50 }
  ]
}

このデータは球を描画するための2つの頂点を表しています。この2点を利用して、球の中心と半径を計算し、Three.jsで3Dモデルとして可視化します。

2. 球の描画ロジック

まず、2点から以下を計算します。

  1. 球の中心: 2点の中点
    中心=点1+点22\text{中心} = \frac{\text{点1} + \text{点2}}{2}
  2. 球の半径: 2点間の距離の半分
    半径=距離2\text{半径} = \frac{\text{距離}}{2}

これらの情報を使って、Three.jsで球体を生成し描画します。

3. 実装コード

以下のコードでは、ReactとThree.jsを使って、RhinoComputeのデータを基に球を描画する方法を示します。

Sphere.js コンポーネント

import React, { useEffect, useRef } from 'react';
import * as THREE from 'three';

function Sphere({ data }) {
  const mountRef = useRef(null);

  useEffect(() => {
    // データがない場合は描画しない
    if (!data || !data.vertices || data.vertices.length !== 2) return;

    // シーン、カメラ、レンダラーをセットアップ
    const scene = new THREE.Scene();
    const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
    const renderer = new THREE.WebGLRenderer();
    renderer.setSize(window.innerWidth, window.innerHeight);
    const mountNode = mountRef.current;
    mountNode.appendChild(renderer.domElement);

    // 2点から球の中心と半径を計算
    const vertices = data.vertices;
    const p1 = new THREE.Vector3(vertices[0].x, vertices[0].y, vertices[0].z);
    const p2 = new THREE.Vector3(vertices[1].x, vertices[1].y, vertices[1].z);

    // 球の中心を計算(2点の中点)
    const center = new THREE.Vector3().addVectors(p1, p2).multiplyScalar(0.5);

    // 球の半径を計算(2点間の距離の半分)
    const radius = p1.distanceTo(p2) / 2;

    // 球のジオメトリを作成
    const geometry = new THREE.SphereGeometry(radius, 32, 32);
    const material = new THREE.MeshBasicMaterial({ color: 0x0077ff, wireframe: true });
    const sphere = new THREE.Mesh(geometry, material);

    // 球の位置を設定
    sphere.position.copy(center);

    scene.add(sphere);

    // カメラの初期位置を設定
    camera.position.z = 500;

    // アニメーションループ
    const animate = function () {
      requestAnimationFrame(animate);
      sphere.rotation.x += 0.01; // 回転
      sphere.rotation.y += 0.01;
      renderer.render(scene, camera);
    };
    animate();

    // ウィンドウリサイズ時にカメラアスペクト比を更新
    const handleResize = () => {
      camera.aspect = window.innerWidth / window.innerHeight;
      camera.updateProjectionMatrix();
      renderer.setSize(window.innerWidth, window.innerHeight);
    };
    window.addEventListener('resize', handleResize);

    // クリーンアップ
    return () => {
      window.removeEventListener('resize', handleResize);
      mountNode.removeChild(renderer.domElement);
    };
  }, [data]);

  return <div ref={mountRef} style={{ width: '100%', height: '100vh' }} />;
}

export default Sphere;

4. データの取得と表示

Sphere.js コンポーネントを使うページは以下のように作成できます。

PythonSpherePage.js

import React, { useEffect, useState } from 'react';
import Sphere from '../components/Sphere';

const PythonSpherePage = () => {
  const [sphereData, setSphereData] = useState(null);
  const [error, setError] = useState(false);

  useEffect(() => {
    fetch('http://localhost:5000/sphere')
      .then(response => {
        if (!response.ok) {
          throw new Error('Network response was not ok');
        }
        return response.json();
      })
      .then(data => {
        setSphereData(data);
      })
      .catch(error => {
        console.error('Error fetching sphere data:', error);
        setError(true);
      });
  }, []);

  return (
    <div>
      <h1>Python Sphere</h1>
      <p>このページではPythonを使用して生成された球の情報を表示します。</p>
      {error ? (
        <p>データを取得できませんでした。サーバーを確認してください。</p>
      ) : !sphereData ? (
        <p>Loading Sphere Data...</p>
      ) : (
        <Sphere data={sphereData} />
      )}
    </div>
  );
};

export default PythonSpherePage;

5. 実行結果

このコードを実行すると、RhinoComputeから取得したデータに基づき、画面に3Dの球が描画されます。さらに、球は回転してアニメーションもつけられます。

6. まとめ

今回の例では、ReactとThree.jsを組み合わせ、RhinoComputeから提供されるデータをもとに3D球を描画しました。このアプローチを活用すれば、他の形状や複雑なモデルの可視化にも応用できます。ぜひ、試してみてください!

-Apps, WebApp
-,