You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

请求解释d3.js 3D图表拖拽旋转功能背后的数学原理

Hey there! Let’s break down the math behind that D3 3D drag-to-rotate example step by step — it’s not as scary as it looks once you connect mouse movements to 3D space logic.

Core Idea: 2D Mouse → 3D "Virtual Sphere" Rotation

The core intuition here is that when you drag the mouse across the canvas, you’re essentially twisting a virtual unit sphere that encloses your 3D objects. The mouse’s 2D position maps directly to a point on this sphere, and dragging between two points translates to rotating the sphere (and your objects) around an axis defined by those two points.

Step 1: Convert Mouse Coordinates to Spherical Angles

First, we need to translate raw mouse screen positions into something that makes sense for 3D rotation:

  1. Normalize mouse position: Subtract the canvas center coordinates from the mouse’s x/y to get a position relative to the center (dx = mouseX - centerX, dy = mouseY - centerY). Since D3’s canvas y-axis points downward, we flip the sign of dy to match standard 3D coordinate systems where y points up.
  2. Clamp to unit sphere: If the mouse is outside the canvas’s "virtual sphere" (i.e., sqrt(dx² + dy²) exceeds the canvas radius), we normalize dx and dy to keep the point on the unit sphere.
  3. Calculate spherical angles:
    • Azimuth angle (θ): This is the horizontal rotation angle around the vertical (y) axis, calculated with θ = Math.atan2(dx, -dy) (sign adjustments align with how we expect dragging left/right to rotate the scene).
    • Polar angle (φ): This is the vertical rotation angle around the horizontal (x) axis, calculated with φ = Math.acos(Math.max(-1, Math.min(1, dy / radius))) (clamping ensures we don’t get invalid values for acos when the mouse is at the edge).
Step 2: Track Rotation with Quaternions (Avoiding Gimbal Lock)

Instead of using Euler angles (which suffer from gimbal lock — that annoying "stuck" rotation when axes align), the example uses quaternions to represent and update rotation. Here’s how that works:

  • A quaternion is a 4-dimensional value (w, x, y, z) that encodes a rotation around an axis by a specific angle. It’s perfect for smooth, cumulative rotations.
  • When you start dragging, we capture the initial spherical angles. As you drag, we calculate the difference (delta) between the current angles and the initial ones.
  • This delta translates to a rotation around two axes: horizontal drags rotate around the y-axis, vertical drags rotate around the x-axis. We convert each of these small rotations into quaternions, then multiply them together to get the total rotation delta quaternion.
  • We multiply this delta quaternion with the current scene rotation quaternion to update the overall rotation state.
Step 3: Apply Rotation to 3D Objects

Once we have the final rotation quaternion, we convert it into a 3x3 rotation matrix (using standard quaternion-to-matrix formulas). Then, for every 3D point in your scene:

  • Multiply the point’s coordinates (x, y, z) by this rotation matrix to get the rotated coordinates (x', y', z').
  • Project these rotated 3D coordinates onto the 2D canvas (the example likely uses a simple orthogonal projection for simplicity).
Quick Recap of the Math Flow
  1. Mouse position → relative center position → spherical angles
  2. Angle delta → rotation quaternion delta
  3. Delta quaternion × current quaternion → updated rotation quaternion
  4. Quaternion → rotation matrix
  5. Matrix × 3D points → rotated points → 2D projection

That’s the gist of it! The key is mapping the 2D mouse input to a 3D rotation that feels intuitive, using quaternions to keep rotations smooth and avoid gimbal lock.

内容的提问来源于stack exchange,提问作者Sam

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:16:44