シェイプを重ねて描く シェイプを重ねて描く

シェイプの重ね順を見てみましょう。

startshape overlaptest 

rule overlaptest {
  overlap1 {}
  overlap2 { x 1.5 }
  overlap3 { x 3 }
  overlap4 { x 4.5 }
}

rule overlap1 {
    SQUARE {}
    CIRCLE { b 1 } 
}

rule overlap2 {
    CIRCLE { b 1 } 
    SQUARE {}
}

rule overlap3 {
    CIRCLE { b 1 z 1 } 
    SQUARE {}
}

rule overlap4 {
    CIRCLE { b 1 } 
    SQUARE { z -1 }
}
overlap 1

startshapeが呼び出したoverlaptestから、さらに4つのルールが呼び出されています。

overlap1は、正方形を描いた後で円を描いています。 正方形の後で円を描くルールですので、円が上面に描画されます。 CIRCLEの中カッコ内の“b 1”は、シェイプの明るさを最大にする命令です(この例の場合は白になります)。 シェイプの色が黒ばかりでは重なりがわからないので、円はすべて白で描画するようにしています。

overlap2は、円を描いた後で正方形を描いています。 円の後で正方形を描くルールですので、正方形が上面に描画され、円が見えなくなってしまいました。

overlap3も、円を描いた後で正方形を描いています。 円の後で正方形を描くルールですが、CIRCLEの中カッコ内の“z 1”で円のz軸(奥行き)が1に設定されているため、後から描画される正方形よりも円の方が前面にあると判断され、白い円が表示されます。 Context Freeでは、z軸のデフォルト値を0としているので、なにも指定していないSQUAREのz軸値は0、CIRCLEのz軸値が1となり、描画の順番に関わりなく前後関係が設定されました。

overlap4も、円を描いた後で正方形を描いています。 overlap4はoverlap3の逆で、SQUAREのz軸値を-1とすることで、デフォルト値の0がz軸値となるCIRCLEよりも後ろに正方形を描画します。

これをふまえて、花を描いてみましょう。 まずは花びら。

startshape petal

rule petal {
    12*{ r 30 } CIRCLE [ r 15 x 0.8 s 2 0.35 ]
    CIRCLE { b 1 }
}
petal

スケールを2:0.35に変形した円をx軸方向に0.8個分移動して15度回転させたものを、30度ずつ回転させながら12個描きます。 これが花びらになります。 次に、花芯として中央部に白い円を描きます。 描く順番の通りに重なればいいので、z軸値は変更しません。

startshape stem

rule stem{
    SQUARE { s 0.5 1 }
    SQUARE { s 0.3 1 b 1 }
}
stem

これは茎です。 花芯よりも細い方がバランスがいいので、x軸方向のスケールを0.5にしています。 真っ黒な茎でもいいのですが、このページの説明の都合上白抜きにする必要があるので、x軸方向のスケールを0.3にした白い四角形を描きました。 描く順番の通りに重なればいいので、z軸値は変更しません。

startshape leaves

rule leaves{
    leaf { x 0.4 r -45 }
    leaf { x -0.4 r 45 }
}

rule leaf {
    CIRCLE { s 0.4 1 }
    CIRCLE { s 0.3 0.9 b 1 }
}
leaves

白抜きした楕円を逆ハの字に配置し、葉とします。

パーツができたので、これを組み合わせて花を作りましょう。 描画順は、まず葉の部分を描き、適当な長さになるまで茎を伸ばし、最後に花びら部分を描いて終了となります。

startshape flower

rule flower {
    leaves { s 2.5 }
    Stems {}
}

rule Stems {
    stem {}
    Stems { y 1 }
}

rule Stems 0.2 {
    stem {}
    petal { y 1 }
}

rule leaves {
    leaf { x 0.4 r -45 }
    leaf { x -0.4 r 45 }
}

rule leaf {
    CIRCLE { s 0.4 1 }
    CIRCLE { s 0.3 0.9 b 1 }
}

rule stem {
    SQUARE { s 0.5 1 }
    SQUARE { s 0.3 1 b 1 }
}

rule petal {
    12*{ r 30 } CIRCLE [ r 15 x 0.8 s 2 0.35 ]
    CIRCLE { b 1 }
}
leaves

コードを見ていきましょう。 まず、startshapeがルールのflowerを呼び出します。flowerでは、葉であるleavesのスケールを2.5倍にして描画し、茎を描くためStermsを呼び出します。 Stermsは2種類あります。 最初のStermsは茎を描いて、Stermsをy軸方向に1個分移動して再帰呼び出しします。 これによって茎が伸びていくわけです。 次のStermsは、茎を描いてからy軸方向に1個分移動してpetalを呼び出します。 再帰呼び出しはしていませんから、最後の茎と花びらを描いて処理は終了となります。 Stermsのウエイトは、茎を伸ばすStermsがデフォルトの1、花びらを描いて処理を終了するStermsが0.2となっていますから、適度に茎が伸びて、先端に花が開いたイメージができあがります。

できあがったはいいのですが、それぞれのパーツの重ね順がおかしいので、不自然な花になっていますね。 z軸方向の情報を追加して、正しく描画するように修正しましょう。

startshape flower

rule flower {
    leaves { s 2.5 z 1 }
    Stems {}
}

rule Stems {
    stem {}
    Stems { y 1 }
}

rule Stems 0.2 {
    stem {}
    petal { y 1 z 1 }
}

rule leaves {
    leaf { x 0.4 r -45 }
    leaf { x -0.4 r 45 }
}

rule leaf {
    CIRCLE { s 0.4 1 }
    CIRCLE { s 0.3 0.9 b 1 }
}

rule stem {
    SQUARE { s 0.5 1 }
    SQUARE { s 0.3 1 b 1 }
}

rule petal {
    12*{ r 30 } CIRCLE [ r 15 x 0.8 s 2 0.35 ]
    CIRCLE { b 1 }
}
leaves

flowerルールのleavesと、Stemsルールのpetalに“z 1”を追加し、正しい重なりで花を描画することができました。

まとめて10本咲かせてみましょう。

startshape flowers 

rule flowers {
    10 * { x 3 y 0.5 z -1 } flower {}
}

rule flower {
    leaves { s 2.5 z 1 }
    Stems {}
}

rule Stems {
    stem {}
    Stems { y 1 }
}

rule Stems 0.2 {
    stem {}
    petal { y 1 z 1 }
}

rule leaves {
    leaf { x 0.4 r -45 }
    leaf { x -0.4 r 45 }
}

rule leaf {
    CIRCLE { s 0.4 1 }
    CIRCLE { s 0.3 0.9 b 1 }
}

rule stem {
    SQUARE { s 0.5 1 }
    SQUARE { s 0.3 1 b 1 }
}

rule petal {
    12*{ r 30 } CIRCLE [ r 15 x 0.8 s 2 0.35 ]
    CIRCLE { b 1 }
}
leaves できるようになった(はずの)こと
  1. シェイプの明るさを変えて、白い色で描画できる
  2. シェイプの重ね順を変えて描画できる