DXFの基本図形を解析していくと、LINE、CIRCLE、ARCに続いて理解しておきたいのがELLIPSEです。
楕円は見た目だけなら単純ですが、DXF内部では「中心+長径+短径」という直接的な保存方法ではありません。
ELLIPSEエンティティでは主に、
- 中心点
- 中心から長軸端点へのベクトル
- 短軸と長軸の比
- 開始パラメータ
- 終了パラメータ
を組み合わせて形状を定義します。
AutodeskのDXF仕様では、これらがグループコード10、11、40、41、42などとして格納されます。
この記事では、DXFのELLIPSEをPythonや独自CADビューアで再利用できる形まで分解して考えます。
ELLIPSEの主要グループコード
Autodesk公式仕様で定義されている主要コードは次のとおりです。
| コード | 意味 |
|---|---|
10,20,30 | 中心点 |
11,21,31 | 中心から長軸端点までのベクトル |
40 | 短軸と長軸の比 |
41 | 開始パラメータ |
42 | 終了パラメータ |
210,220,230 | 押し出し方向 |
完全な楕円の場合、仕様上は、
となります。
一方、楕円弧の場合は41と42によって曲線の一部分だけを表現します。
コード11は「長軸の長さ」ではない
ELLIPSEで特に重要なのがコード11、21、31です。
これは長軸長そのものではなく、
中心から長軸端点へ向かうベクトル
です。
たとえば2次元で、
中心
(100, 50)
長軸ベクトル
(30, 0)
なら、長半径は、
です。
長径全体は、
になります。
つまりコード11の値をそのまま「長径」と解釈すると、寸法を2倍間違えることになります。
回転した楕円も同じ形式で表せる
長軸ベクトルが、
なら長軸はX方向です。
一方、
なら長軸は斜め方向になります。
その長半径は、
です。
長軸方向の単位ベクトルは、
として求められます。
2次元XY平面であれば、その90度方向、
を短軸方向として利用できます。
このためDXFは「回転角度」を別途保存しなくても、長軸ベクトル自体で楕円の向きを表現できます。
コード40は短長軸比
グループコード40は、
短軸と長軸の比
を表します。
長半径を、短半径を、コード40の値をとすると、
です。
したがって、
となります。
たとえば、
なら、
です。
つまり、
- 長半径:30
- 短半径:15
の楕円になります。
内部モデルとしては、
semi_major = 30.0
axis_ratio = 0.5
semi_minor = semi_major * axis_ratio
と変換できます。
楕円の座標を計算する
XY平面上の楕円なら、中心を、長軸方向を、短軸方向をとして、
で楕円上の点を求められます。
ここで、
- :長半径
- :短半径
- :パラメータ
です。
中心が、
長軸ベクトルが、
比率が、
なら、
なので、
となります。
完全な楕円なら、
を評価すれば形状を再現できます。
コード41・42は普通の角度とは限らない
ELLIPSEを読むときに最も注意したいのが、開始・終了パラメータです。
コード41と42はラジアンで表されますが、楕円弧の場合、単純な「中心から見た極角」と同一とは限りません。
Autodesk Developer Blogでも、コード41は楕円のparametric angleであり、描画された楕円弧の幾何学的な角度とは異なる場合があると説明されています。
楕円のパラメータ表示、
におけるが、このパラメトリック角です。
円の場合、
なので極角とパラメータ角は一致します。
しかし楕円では、
なので通常は一致しません。
したがって、
start_angle = group_code_41
として一般的なARCと同じ極角処理へ渡す実装は危険です。
PythonでELLIPSEを点列化する
簡易DXFビューアでは、ELLIPSEを一定間隔で評価して折れ線へ近似できます。
import math
def ellipse_points(
center: tuple[float, float],
major_axis: tuple[float, float],
axis_ratio: float,
start_param: float,
end_param: float,
segments: int = 128,
) -> list[tuple[float, float]]:
cx, cy = center
ax, ay = major_axis
semi_major = math.hypot(ax, ay)
if semi_major == 0:
raise ValueError("長軸ベクトルは0にできません")
if axis_ratio <= 0:
raise ValueError("短長軸比は0より大きい必要があります")
semi_minor = semi_major * axis_ratio
ux = ax / semi_major
uy = ay / semi_major
vx = -uy
vy = ux
points = []
for i in range(segments + 1):
t = start_param + (
end_param - start_param
) * i / segments
x = (
cx
+ semi_major * math.cos(t) * ux
+ semi_minor * math.sin(t) * vx
)
y = (
cy
+ semi_major * math.cos(t) * uy
+ semi_minor * math.sin(t) * vy
)
points.append((x, y))
return points
この例はXY平面上で押し出し方向が標準的な2D ELLIPSEを扱う簡易実装です。
任意の3次元姿勢まで扱う場合は、コード210/220/230の法線ベクトルを使って楕円面上の基底ベクトルを構成する必要があります。
完全楕円か楕円弧かを判定する
Autodesk仕様では完全な楕円の場合、
です。
したがって概念的には、
import math
is_full = (
math.isclose(start_param, 0.0)
and math.isclose(end_param, 2.0 * math.pi)
)
と判定できます。
浮動小数点なので、
start_param == 0.0
のような完全一致だけに依存しない方が安全です。
CIRCLEとはデータ構造が違う
円と楕円は見た目が近いため、同じデータ形式にまとめたくなることがあります。
しかしDXFではCIRCLEは、
- 中心
- 半径
を中心に定義されています。AutodeskのCIRCLE仕様ではコード40が半径です。
対してELLIPSEではコード40は短長軸比です。
つまり同じグループコード40でも、
CIRCLE
40 → radius
ELLIPSE
40 → minor / major ratio
と意味が異なります。
DXFパーサーでは、グループコードだけで処理を決定せず、
entity type
+
group code
の組み合わせで意味を解釈する必要があります。
内部モデルへ正規化する
DXF固有コードをアプリ全体へ持ち込むより、読み込み時に意味のある構造へ変換すると再利用しやすくなります。
from dataclasses import dataclass
@dataclass
class EllipseData:
center: tuple[float, float, float]
major_axis_vector: tuple[float, float, float]
axis_ratio: float
start_parameter: float
end_parameter: float
extrusion: tuple[float, float, float]
さらに計算プロパティとして、
@property
def semi_major_axis(self) -> float:
x, y, z = self.major_axis_vector
return (x*x + y*y + z*z) ** 0.5
を持たせられます。
この構造なら、
DXF
↓
EllipseData
↓
SVG
Canvas
幾何計算
CAD変換
検証
と展開できます。
データ検証ルールにもできる
ELLIPSEを構造化すると、異常なDXFを機械的に検出できます。
たとえば、
- 長軸ベクトルがゼロでないか
- 軸比が正か
- 開始・終了パラメータが数値か
- extrusion vectorが妥当か
- 必須コードが存在するか
などです。
def validate_ellipse(
major_length: float,
axis_ratio: float,
) -> None:
if major_length <= 0:
raise ValueError("長半径が不正です")
if axis_ratio <= 0:
raise ValueError("短長軸比が不正です")
といったルールは、単なる表示処理ではなくDXF検証機能へ発展させられます。
SVGへ変換する場合
WebでDXFを表示する場合、ELLIPSEをSVGのellipseやpathへ変換できます。
完全な楕円で単純な2D姿勢なら、
中心
長半径
短半径
回転角
へ変換してSVG ellipseとして描けます。
一方、楕円弧の場合はSVG pathのelliptical arcへ変換する方法があります。
つまりDXFの、
center
major axis vector
ratio
start parameter
end parameter
を一度正規化しておけば、特定CADへ依存せずWebレンダリングへ接続できます。
実装で起きやすい失敗
ELLIPSEでは特に次の誤解に注意が必要です。
コード11を長径だと思う
実際には中心から長軸端点へのベクトルです。
コード40を半径だと思う
ELLIPSEでは短長軸比です。CIRCLEのコード40とは意味が違います。
コード41・42をARCの開始角・終了角と同じ扱いにする
楕円ではパラメトリック角として扱う必要があります。
2D前提の垂直ベクトルを3Dデータにも使う
任意平面上のELLIPSEではextrusion directionを考慮する必要があります。
この違いをデータモデルの段階で分離しておくと、後のバグを減らせます。
まとめ
DXFのELLIPSEは、
中心点
+
長軸ベクトル
+
短長軸比
+
開始パラメータ
+
終了パラメータ
で理解すると構造が明確になります。
重要なグループコードは、
10/20/30:中心11/21/31:長軸ベクトル40:短長軸比41:開始パラメータ42:終了パラメータ210/220/230:押し出し方向
です。
特に重要なのは、コード41・42が単純な極角ではなく、楕円のパラメータ表示で使われる値だという点です。
DXFを、
グループコード → 幾何パラメータ → 正規化データ → 描画・計算
へ変換すれば、ELLIPSEはWebビューア、SVG変換、図形比較、CAD自動化へ再利用できるデータ資産になります。
参考情報
- Autodesk公式 DXF Reference — ELLIPSEエンティティ。
- Autodesk Developer Blog — 楕円弧の開始パラメータとparametric angleの解説。
- Autodesk公式 DXF Reference — CIRCLEとのコード40の意味の違い。

