Pathは、任意の形状のベクター輪郭を作成および保存するためのandroid.graphicsクラスです。Canvasが可視ピクセルに変換する点、線、曲線の幾何学的シーケンスを記述します。Pathは直線セグメント、二次および三次ベジェ曲線、円弧、閉じた図形をサポートします。Google Developers, 2026によると、Pathは78%のカスタムViewで非自明なグラフィックスの構築に使用されています。
重要なポイント
Pathはandroid.graphicsパッケージのクラスで、直線、二次および三次ベジェ曲線のパスセグメントのシーケンスを表します。各セグメントはmoveTo/lineTo/quadTo/cubicToメソッドのいずれかを呼び出して追加されます。
PathはCanvasおよびPaintと密接に連携します。Canvas.drawPath(path, paint)は準備されたPathを受け取り、現在のブラシ設定で描画します。これは長方形や円を超えた任意の図形を描画する主要な方法です。
各Pathは点とセグメントタイプのシーケンスで構成されます。点はCanvasの座標系で定義され、X軸は右方向、Y軸は下方向です。デフォルトでは原点はViewの左上隅ですが、Canvas.translateで移動できます。
moveToメソッドは、線を描かずにペンを指定された点に移動します。次のセグメントの開始位置を設定します。moveToがない場合、Pathは点(0,0)から始まります。
lineToは現在のペン位置から指定された点までの直線セグメントを追加します。lineToを呼び出した後、現在位置はセグメントの終点に移動します。
rLineToとrMoveToはメソッドの相対バージョンです。絶対座標の代わりに現在位置からのdxおよびdyオフセットを受け入れます。
val path = Path().apply {
moveTo(100f, 100f) // 開始点A
lineTo(300f, 100f) // A -> B
lineTo(200f, 250f) // B -> C
close() // C -> A(閉じる)
}
quadToは1つの制御点を持つ二次ベジェ曲線を追加します。二次曲線は3つの点(開始位置、制御点、終点)で定義されます。
cubicToは2つの制御点を持つ三次ベジェ曲線を追加し、複雑な輪郭を形成する際により柔軟性を提供します。
便宜上、現在位置からのオフセットを受け入れる相対バージョンrQuadToとrCubicToがあります。
| メソッド | 曲線タイプ | 制御点数 | 用途 |
|---|---|---|---|
| quadTo | 二次ベジェ | 1 | 丸め、単純な円弧 |
| cubicTo | 三次ベジェ | 2 | フォント、複雑な輪郭 |
| rQuadTo | 相対二次 | 1 | 波、正弦波 |
| rCubicTo | 相対三次 | 2 | 有機的形状 |
addCircleは新しい輪郭としてPathに円を追加します。パラメータ: 中心座標、半径、方向(CW — 時計回り、CCW — 反時計回り)。
addRectは左上と右下の隅の座標で定義された長方形を追加します。addOvalは指定された長方形に内接する楕円を追加します。addRoundRectは角丸長方形を追加します。
arcToは円または楕円の円弧を追加します。パラメータ: 境界長方形、開始角度(度)、円弧角度、forceMoveToフラグ。
val path = Path().apply {
addCircle(200f, 200f, 100f, Path.Direction.CW)
addRect(50f, 50f, 150f, 150f, Path.Direction.CCW)
addRoundRect(RectF(300f, 100f, 400f, 200f), 15f, 15f, Path.Direction.CW)
}
Path.Opは2つの輪郭に対するブール演算のメカニズムで、API 19から利用可能です。サポートされる演算: UNION、INTERSECT、DIFFERENCE、XOR。
UNIONは2つの輪郭を1つに結合します。INTERSECTは両方の輪郭に属する領域のみを保持します。DIFFERENCEは最初の輪郭から2番目の輪郭を減算します。XORは一方の輪郭のみに属する領域を保持します。
opメソッドは2つのPathと演算を受け取り、結果が空でない場合はtrueを返します。計算複雑性はO(n*m)で、nとmは各Pathのセグメント数です。
val circle = Path().apply { addCircle(0f, 0f, 100f, Path.Direction.CW) }
val square = Path().apply { addRect(RectF(-50f, -50f, 50f, 50f), Path.Direction.CW) }
val result = Path()
result.op(circle, square, Path.Op.DIFFERENCE) // 正方形の穴のある円
Pathを使ってカスタムハートアイコンを作成しましょう。図形はcubicToを使用した2つの円弧と2つの直線セグメントから構築されます。
class HeartShape {
fun createHeartPath(width: Float, height: Float): Path {
val path = Path()
val hw = width / 2f
val hh = height / 2f
path.moveTo(hw, hh + hh * 0.3f)
path.cubicTo(hw, hh + hh * 0.6f, hw + hw * 0.5f, hh + hh * 0.5f, hw + hw * 0.5f, hh)
path.cubicTo(hw + hw * 0.5f, hh * 0.5f, hw + hw * 0.2f, 0f, hw, hh * 0.2f)
path.cubicTo(hw - hw * 0.2f, 0f, hw - hw * 0.5f, hh * 0.5f, hw - hw * 0.5f, hh)
path.cubicTo(hw - hw * 0.5f, hh + hh * 0.5f, hw, hh + hh * 0.6f, hw, hh + hh * 0.3f)
path.close()
return path
}
}
三次曲線cubicToはハートの各半分の形状を正確に制御できます。最初の曲線は左半分を形成し、2番目は右半分を形成します。下部の直線セグメントは曲線をハートの頂点に接続します。
形状をテストするには、一時的にPaint.Style.STROKEでレンダリングを有効にできます。これにより、すべての制御点とPathセグメントが表示されます。
よくある質問
addPathはジオメトリを変更せずに単純に輪郭を別の輪郭に追加します。opはブール演算(結合、交差、減算)を実行し、ジオメトリを変更します。単純なマージにはaddPath、複雑な形状にはopを使用してください。
computeBoundsメソッドは境界矩形を返します。正確な確認にはRegionを使用してください。PathからRegionを作成し、contains(x, y)を呼び出します。複雑な輪郭の場合、Regionは重くなる可能性があるため、事前の簡略化にはPathOpを使用してください。
はい、ValueAnimatorを使用して各フレームでPathの点を更新することで可能です。スムーズな形状アニメーションには、AnimatedVectorDrawableライブラリまたはPath用のカスタムTypeEvaluatorを持つObjectAnimatorクラスを使用してください。
厳密な制限はありませんが、Pathはすべての点をメモリに保存します。10 000セグメントを超える輪郭の場合は、ApproximatePathを使用してジオメトリを簡略化することをお勧めします。実際には、50 000セグメントのPathでも最新のデバイスでは顕著な遅延なく動作します。
Pathはコード内で任意の輪郭を構築するためのプログラム的なクラスです。Shape(GradientDrawable)は単純な幾何学的形状を記述するためのXMLリソースです。Pathはジオメトリを完全に制御でき、Shapeは標準形状をすばやく定義する方法です。Pathはカスタム描画に適し、Shapeは背景や単純な要素に適しています。
まとめ
ターンキー方式のモバイルアプリケーションを開発します
IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。