◆PROCESSING 逆引きリファレンス
カテゴリー:図形描画
点線を描画するには
【解説】
PROCESSINGで普通に線(連続線)を引くには、「直線を描画するには」記事で紹介したように line() 命令を利用します。
その一方で、点線(や破線)を簡単に描画する命令は用意されていません。
PROCESSINGで点線(や破線)を描画するには
- OpenGLの機能を用いて描く
- 2つの座標を結ぶ直線上にある点の座標を計算して、自分で描く
の、どちらかの処理を行う事になります。この記事では、自分で座標を計算しながら線を引く方法を紹介します。
2つの座標間にある直線上の点は、lerp()命令で計算可能です。
【構文】
float f = lerp( int x, int y, float amt );
float f = lerp( float x, float y, float amt );
【パラメータ】
x :1つ目の点。float または int 値。
y :2つ目の点。float または int 値。
amt :xとyの間にある点を求める間隔。
amtが 0.5 なら、xとyの中間点を求めます。0.25なら x と y の距離を4等分して、xに近い方から1/4進んだ位置にある点を求めます。
【戻り値】
f :計算結果
【注意】
amtが 0.0 の場合、戻り値( f )は最初の点 x と同じになります。amt が 1.0 の場合、戻り値( f )は2番目の点 y と同じになります。
amtが 1.0 より大きい場合は、x と y の距離を amt 倍した直線上の位置が戻されます。例えば amt が 2.0 の場合は、x と y の長さと同一距離をx->y方向に進めた点 z が戻されます。
【関連記事】
サンプルプログラム
点線を描画する例1:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
void setup(){ size(300,300); } void draw(){ int x1 = 100; //始点X座標 int y1 = 100; //始点Y座標 int x2 = 200; //終点X座標 int y2 = 200; //終点Y座標 //始点と終点を目立つように描画する strokeWeight(24); //大きさは24ピクセル //始点は赤 stroke( 255,50,50); point( x1, y1 ); //終点は青 stroke( 50,50,255); point( x2, y2 ); //点線は4ピクセルとし、黒で描画する strokeWeight(4); stroke( 0,0,0); //点を始点・終点を含めて11個打つ for( int i = 0; i <= 10; i++ ){ float px = lerp( x1, x2, i/10.0 ); float py = lerp( y1, y2, i/10.0 ); point( px, py ); } noLoop(); } |
座標 x1 , y1 から x2, y2 に掛けて、点を打つ事で点線に見せかけています。
ぞれぞれの座標を結ぶ中間点は、lerp() 命令で計算しています。
点線を描画する例2:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
void setup(){ size(300,300); } void draw(){ int x1 = 50; //始点X座標 int y1 = 50; //始点Y座標 int x2 = 250; //終点X座標 int y2 = 250; //終点Y座標 float bx, by; //直前座標記録用 int j = 0; //破線制御用 String hasen = "0101"; //破線パターン //始点と終点を目立つように描画する strokeWeight(24); //大きさは24ピクセル //始点は赤 stroke( 255,50,50); point( x1, y1 ); //終点は青 stroke( 50,50,255); point( x2, y2 ); //点線は4ピクセルとし、黒で描画する strokeWeight(4); stroke( 0,0,0); //直前の座標を「始点」に初期化する bx = x1; by = y1; //点を始点・終点を含めて31個打つ for( int i = 0; i <= 30; i++ ){ float px = lerp( x1, x2, i/30.0 ); float py = lerp( y1, y2, i/30.0 ); //破線パターンが1の場合は線で結ぶ String ptn = hasen.substring(j,j+1); j++; //パターンの終端まで来たら、最初に戻る if( j >= hasen.length() ){ j = 0; } if( ptn.equals("1") == true ){ //線で結ぶ line( bx, by, px, py ); } else { //点を打つ point( px, py ); } //直前の座標を更新 bx = px; by = py; } noLoop(); } |
ポイントは hasen で定義している破線パターン文字列です。この文字列を先頭から1文字づつ取り出し、1 の場合は直前の座標と線で結び、0 の場合は結ばない処理を行っています。
本例ではパターンが “0101” なので、1つおきに線を引いたり空けたりして、出力サンプル1にあるような点線を描画しています。
パターンを “0110” にすると、出力サンプル2のような破線が描画されます。
本ページで利用しているアイコン画像は、下記サイト様より拝借しております。各画像の著作権は、それぞれのサイト様および作者にあります。