チュートリアル - ビットマップ ペイント ツールの開発 - ストロークの強化

このビットマップ ペイント ツール開発の手順では、よりよいストローク描画のコードを追加し、ストロークが点線状にならないようにします。

全体の流れ:

新しい関数を追加することによって既存の MacroScript を拡張します。

新しい関数にはマウスの元の位置と新しい位置を渡します。 2 つの地点の間に線が引かれ、それが連続したストロークになります。

スクリプト:

    macroScript MicroPaint category: "HowTo"
    (
    global MicroPaint_CanvasRollout
    try (destroyDialog MicroPaint_CanvasRollout) catch()
    local isDrawing = false
    local bitmapX = bitmapY = 512
    local theCanvasBitmap = bitmap bitmapX bitmapY color:white
    local currentPos = lastPos = [0,0]

    rollout MicroPaint_CanvasRollout "MicroPaint"
    (
      bitmap theCanvas pos:[0,0] width:bitmapX height:bitmapY bitmap:theCanvasBitmap
      fn paintBrush pos = ( setPixels theCanvasBitmap pos #(color 0 0 0) )
      fn drawStroke lastPos pos =
      (
        currentPos = lastPos
        deltaX = pos.x - lastPos.x
        deltaY = pos.y - lastPos.y
        maxSteps = amax #(abs(deltaX),abs(deltaY))
        deltaStepX = deltaX / maxSteps
        deltaStepY = deltaY / maxSteps
        for i = 0 to maxSteps do
        (
          paintBrush currentPos
          currentPos += [deltaStepX, deltaStepY]
        )
        theCanvas.bitmap = theCanvasBitmap
      )
      on MicroPaint_CanvasRollout lbuttondown pos do
      (
        lastPos = pos
        isDrawing = true
        drawStroke lastPos pos
      )
      on MicroPaint_CanvasRollout lbuttonup pos do isDrawing = false
      on MicroPaint_CanvasRollout mousemove pos do
      (
        if isDrawing do drawStroke lastPos pos
        lastPos = pos
      )
    )
    createDialog MicroPaint_CanvasRollout bitmapX bitmapY
    )

ステップごとの解説

--Code in italic has no changes since the previous version. macroScript MicroPaint category:"HowTo"
(
global MicroPaint_CanvasRollout
try(destroyDialog CanvasRollout)catch()
local isDrawing = false
local bitmapX = bitmapY = 512
local theCanvasBitmap = bitmap bitmapX bitmapY color:white local currentPos = lastPos = [0,0]

最初に行うべき変更は、現在の位置と直前の既知の位置の変数を定義することです。これらの変数は、現在のストロークを追跡するために使用されます。どちらも[0,0]に初期化します。

rolloutMicroPaint_CanvasRollout "MicroPaint" ( bitmap theCanvas pos:[0,0] width:400 height:400 bitmap:theCanvasBitmap fn paintBrush pos = ( setPixels theCanvasBitmap pos #(black) )

paintBrush 関数を簡素化します。点を描画するだけで、キャンバスの更新は行いません。ストローク内には大量のブラシの点が含まれますが、更新はストロークの後 1 回だけにして、インタラクティブ性を保ちます。

fn drawStroke lastPos pos =
(

マウス関連のハンドラに呼び出されるストローク描画の関数です。この関数には 2 つの引数が渡されます。1 つは直前のマウス位置(ストロークの開始地点)で、もう 1 つは現在のマウス位置(ストロークの終了地点)です。

currentPos = lastPos

現在位置の変数がストローク開始地点に初期化されます。これは、ストロークの開始地点から終了地点に向かって線を描画するために使用されます。

deltaX = pos.x - lastPos.x
deltaY = pos.y - lastPos.y

直前の位置から新しい位置に線をまっすぐに描画するには、2 つの点が X 軸と Y 軸についてそれぞれどれくらい離れているのかを知る必要があります。

maxSteps = amax #(abs(deltaX),abs(deltaY))

次に、X 軸と Y 軸について 2 つの点の絶対値を比較し、どちらの値が大きいかを調べます。maxSteps は、X 軸または Y 軸のどちらかでの 2 点間のピクセル数になります。

deltaStepX = deltaX / maxSteps
deltaStepY = deltaY / maxSteps

ここで、ステップごとの増分を X 軸と Y 軸について計算します。maxSteps が X 軸での 2 点間の距離に等しい場合、deltaStepX は +1 または -1 になり、deltaStepY は 1.0 未満の数値になります。maxSteps が Y 軸での 2 点間の距離に等しい場合、deltaStepY は +1 または -1 になり、deltaStepX は 1.0 未満の数値になります。

for i = 0 to maxSteps do
(

0 からステップの数だけループします。

paintBrush currentPos

カスタム関数の paintBrush を呼び出し、現在位置に黒のドットをペイントします。

currentPos += [deltaStepX, deltaStepY]

現在のマウス位置になるまで、現在位置を deltaStep の値で増分します。

)
theCanvas.bitmap = theCanvasBitmap

最後に、ストロークが終了したら、ロールアウトのビットマップを更新します。

) on MicroPaint_CanvasRollout lbuttondown pos do
(  
lastPos = pos

ユーザがマウス ボタンを押したら、そのクリックした地点にストロークをリセットします。

isDrawing = true drawStroke lastPos pos

paintBrush 関数を呼び出す代わりに drawStroke 関数を呼び出し、直前および現在の位置(この時点では同じです)を渡します。これにより、クリック地点で 1 つのドットが描画されます(ストロークの長さは 0 で、deltaX と deltaY も両方 0 であり、したがって maxSteps も 0 になりますが、for i ループのカウントが 0 から開始されるため 1 回だけループが実行され、点が描画されます)。

) on MicroPaint_CanvasRollout mousemove pos do ( if isDrawing do drawStroke lastPos pos on MicroPaint_CanvasRollout lbuttonup pos do isDrawing = false

paintBrush 関数を呼び出す代わりにもう一度 drawStroke 関数を呼び出します。このときには lastPos と pos の値が異なるので、長いストロークが描画されます。

lastPos = pos

ストロークの描画後、現在のマウス位置を lastPos 変数に記録します。 これは次のストロークの開始地点として使用されます。

)
)
createDialog MicroPaint_CanvasRollout bitmapX bitmapY
)

結果

前のチュートリアル:

チュートリアル - ビットマップ ペイント ツールの開発 - 基本ユーティリティ

次のチュートリアル:

チュートリアル - ビットマップ ペイント ツールの開発 - ブラシのサイズとカラー