0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

プリングルス方程式

Posted at

image.png
image.png

はじめに

プリングルス形状を数式で表現しました。
実測してないので、不正確です。
双曲放物面(hyperbolic paraboloid)の一部です。
スタックしやすく、割れにくい構造だそうです。
チップスターは円柱の一部に近いので、似た形だけれど、数学的には異なります。

環境

Processing 4.4.10
python 3.10.8

方程式

z(x,y)=
\left( \frac{x}{4} \right)^{2}
-
\left( \frac{y}{3} \right)^{2}
\qquad

for

\left( \frac{x}{4} \right)^{2}
+
\left( \frac{y}{3} \right)^{2}
\le 1

Processing

// プリングルス曲面(a=4, b=3)
// z = (x/4)^2 - (y/3)^2
// (x/4)^2 + (y/3)^2 <= 1 の範囲のみ描画
float a = 4.0;
float b = 3.0;

float angleX = 0;
float angleZ = 0;

void setup() {
  size(800, 800, P3D);
}

void draw() {
  background(255);
  lights();

  translate(width/2, height/2);

  // マウスで回転
  if (mousePressed) {
    angleX += (mouseY - pmouseY) * 0.01;
    angleZ += (mouseX - pmouseX) * 0.01;
  }

  rotateX(-angleX);
  rotateZ(-angleZ);

  float s = 50;
  scale(s, -s, s);

  float xmin = -a;
  float xmax =  a;
  float ymin = -b;
  float ymax =  b;

  float step = 0.02;

  // === XY平面グリッド ===
  stroke(128);
  strokeWeight(1.0/s);
  for (float gx = xmin; gx <= xmax; gx += 1.0) {
    line(gx, ymin, 0, gx, ymax, 0);
  }
  for (float gy = ymin; gy <= ymax; gy += 1.0) {
    line(xmin, gy, 0, xmax, gy, 0);
  }

  // === 曲面 ===
  noStroke();
  for (float y = ymin; y < ymax; y += step) {
    beginShape(TRIANGLE_STRIP);

    for (float x = xmin; x <= xmax; x += step) {
      if (sq(x/a) + sq(y/b) <= 1.0) {
        float z1 = sq(x/a) - sq(y/b);
        float z2 = sq(x/a) - sq((y+step)/b);

        float c = map(z1, -1, 1, 128, 255);
        fill(255, c, 255-c);

        vertex(x, y, z1);
        vertex(x, y+step, z2);
      }
    }

    endShape();
  }
}

Python + matplot

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.widgets import Slider

# ---------------------------------
# 初期パラメータ
# ---------------------------------
initial_a = 4.0
initial_b = 3.0
num = 100

# メッシュ座標
xmin, xmax = -4, 4
ymin, ymax = -4, 4
x = np.linspace(xmin, xmax, num)
y = np.linspace(ymin, ymax, num)
X, Y = np.meshgrid(x, y)

def calc_Z(a, b):
    Z = (X**2)/(a*a) - (Y**2)/(b*b)
    ellipse = (X**2)/(a*a) + (Y**2)/(b*b)
    return np.where(ellipse <= 1.0, Z, np.nan)

# ---------------------------------
# Figure
# ---------------------------------
fig = plt.figure(figsize=(8, 7))
plt.subplots_adjust(bottom=0.25)
ax = fig.add_subplot(111, projection='3d')

# ---- 初回描画 ----
Z0 = calc_Z(initial_a, initial_b)
surf = ax.plot_surface(X, Y, Z0, cmap='viridis', linewidth=0)

# ---- 外周の楕円(滑らか境界用)----
theta = np.linspace(0, 2*np.pi, 400)
ellipse_x = np.cos(theta) * initial_a
ellipse_y = np.sin(theta) * initial_b
ellipse_z = (ellipse_x**2)/(initial_a**2) - (ellipse_y**2)/(initial_b**2)
line = ax.plot(ellipse_x, ellipse_y, ellipse_z, color="k", linewidth=1.5)[0]

# ---- 軸設定 ----
ax.set_xlim(-4, 4)
ax.set_ylim(-4, 4)
ax.set_zlim(-4, 4)

# ★★ 等倍率(ここが重要) ★★
ax.set_box_aspect([1, 1, 1])

ax.view_init(30, -45)

# ---------------------------------
# スライダー
# ---------------------------------
ax_a = fig.add_axes([0.2, 0.10, 0.60, 0.03])
ax_b = fig.add_axes([0.2, 0.05, 0.60, 0.03])
slider_a = Slider(ax_a, 'a', 0.3, 4.0, valinit=initial_a, valstep=0.05)
slider_b = Slider(ax_b, 'b', 0.3, 4.0, valinit=initial_b, valstep=0.05)

# ---------------------------------
# 更新関数
# ---------------------------------
def update(val):
    a = slider_a.val
    b = slider_b.val

    ax.clear()

    # Z再計算
    Z = calc_Z(a, b)
    ax.plot_surface(X, Y, Z, cmap='viridis', linewidth=0)

    # 外周の滑らかな楕円
    ex = np.cos(theta) * a
    ey = np.sin(theta) * b
    ez = (ex*ex)/(a*a) - (ey*ey)/(b*b)
    ax.plot(ex, ey, ez, color="k", linewidth=1.5)

    # 軸設定
    ax.set_xlim(-4, 4)
    ax.set_ylim(-4, 4)
    ax.set_zlim(-4, 4)
    ax.set_box_aspect([1, 1, 1])
    ax.view_init(30, -45)

    fig.canvas.draw_idle()

slider_a.on_changed(update)
slider_b.on_changed(update)

plt.show()
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?