講義プリント

CG プログラミング論 平成 26 年 5 月 26 日
第6章.図形の移動
【学習のねらい】
① 今週は、図形を移動する方法を学習します。具体的には、「x 軸(水平軸)に対する対
称移動」、「y軸に対する対称移動」、「原点に対する対称移動」そして「原点の回りの
回転移動」の 4 種類の移動方法です。これらを用いれば様々な(対称性を持った)図
形を容易に描くことができる事が分かるはずです。そうすれば CG への興味が益々湧
いてくることと思います。いずれもプリントをよく読めば確実に理解できる内容なの
で、
「対称移動」等の言葉に惑わされずに落ち着いて学習して下さい。
6-1
多角形の描画
まず、移動する基となる図形として次の様な多角形を描きましょう。
(-30,90)
y軸
(30,90)
(0,60)
(-30,30)
(30,30)
x軸
(0,0)
これまでの学習でもう慣れていることと思いますが、これをコンピュータ画面上に描く場
合には、次のように左上隅が原点である事を考慮しなければなりません。グラフの原点を
(X0,Y0)とすると、各点のコンピュータ上の座標は下の点線枠内の様になります。
(0,0)
(X0-30,Y0-90)
(-30,90)
X軸
<コンピュータ上の座標>
y軸
(30,90)
(X0+30,Y0-90)
(0,60) (X0,Y0-60)
(-30,30)
(30,30)
(X0+30,Y0-30)
(X0-30,Y0-30)
Y軸
(0,0)
53
x軸
(X0,Y0)
CG プログラミング論 平成 26 年 5 月 26 日
各点の座標が分かれば図形を描くことは容易です。以下では上のような多角形の描画に、
drawPolygon(x,y,N)、
x,y:各点の x,y 座標を格納した配列、 N:点の数
というメソッドを用います。
※ このメソッドが呼び出されると、点(x[0],y[0])
、点(x[1],x[1])、・・・、点(x[N-1],y[N-1])
と順に直線で結んで行き、最後に再び点(x[0],y[0])に戻ってきます。これにより、N 点
を結ぶ多角形が描かれます(
「プログラミング」テキスト pp.209~210 参照)
。
【基礎課題 6-1】
上で説明した多角形を描くプログラムを作成しましょう。
このプログラムを次のように記述しました。空欄を埋めてプログラムを完成させて下さい。
配列の宣言については、「プログラミング」テキスト
pp.95~97 参照。
void DrawGraphics(Graphics g) {
int[] x={0,30,30,0,-30,-30}; //多角形のx座標の定義
int[] y={0,30,90,60,90,30}; //多角形のy座標の定義
int N=6; //データ数(多角形の頂点の数)
int x0=100; //原点のx座標(コンピュータ上)
int y0=100; //原点のy座標(コンピュータ上)
int[] xp=new int[N]; //コンピュータ上のx座標を格納する配列
int[] yp=new int[N]; //コンピュータ上のy座標を格納する配列
g.setColor(Color.BLUE); //描画色を青に設定
for(int i=0; i<N; i++) {
頂点の座標をコンピュータ上の座
xp[i]= x0+x[i] ;
yp[i]=
①
;
標(xp[i],yp[i])(i=0~N-1)に変換
}
g.drawPolygon(xp,yp,N); //多角形を描画
}
54
CG プログラミング論 平成 26 年 5 月 26 日
6-2
対称移動①
-
x軸(水平軸)に対する対称移動
ある図形を、x軸に関して折り返した図形(下の点線で描かれた図形)をx軸に関して
対称な図形、あるいはx軸に対して対称移動した図形と言います。
(-30,90)
y軸
(30,90)
(0,60)
(-30,30)
(30,30)
(0,0)
(-30,-30)
x軸
y座標が逆符号
(30,-30)
(0,-60)
(-30,-90)
(30,-90)
上の図を見ると、x軸対称な図形と元の図形を比べると、対応する頂点のy座標が逆符
号になっている事が分かります。したがって、x軸対称な図形は元となる図形の各点のy
座標を逆符号にするだけで描ける事が分かります。
【基礎課題 6-2】
【基礎課題 6-1】のプログラムを修正して、次ページのようにx軸(水平軸)に対して対
称移動した図形も(併せて)描くようにしましょう。
このプログラムは次ページの様になります。プログラムを見ると分かるとおり、これは
【基礎課題 6-1】のプログラムに、x軸対称な図形を描く部分(点線枠内)を追加しただけ
です。空欄①を埋めてプログラムを完成させて下さい。
55
CG プログラミング論 平成 26 年 5 月 26 日
void DrawGraphics(Graphics g) {
int[] x={0,30,30,0,-30,-30}; //多角形のx座標の定義
int[] y={0,30,90,60,90,30};
//多角形のy座標の定義
int N=6; //データ数(多角形の頂点の数)
int x0=100; //原点のx座標(コンピュータ上)
int y0=100; //原点のy座標(コンピュータ上)
int[] xp=new int[N]; //コンピュータ上のx座標を格納する配列
int[] yp=new int[N]; //コンピュータ上のy座標を格納する配列
g.setColor(Color.BLUE); //描画色を青に設定
//図形(多角形)の描画
for(int i=0; i<N; i++) {
xp[i]= x0+x[i] ;
yp[i]=
;
}
g.drawPolygon(xp,yp,N); //多角形を描画
//x軸対称な図形の描画
for(int i=0; i<N; i++) {
xp[i]= x0+x[i] ;
yp[i]=
①
;
}
g.drawPolygon(xp,yp,N); //多角形を描画
}
56
新たに追加した部分
CG プログラミング論 平成 26 年 5 月 26 日
6-3
対称移動②
-
y軸(垂直軸)に対する対称移動
前節に続いて今度はy軸(垂直軸)に対する対称移動を考えましょう。下の左半分の点
線図形が、
(右半分の)図形をy軸に対して対称移動したものです。
y軸
(-90,30)
(-30,30)
(30,30)
(-60,0)
(-90,-30)
(90,30)
(60,0)
(-30,-30)
(30,-30)
x軸
(90,-30)
図より、y軸対称な図形と元の図形を比べると、対応する頂点のx座標が逆符号になって
いる事が分かります。したがって、y軸対称な図形は元となる図形の各点のx座標を逆符
号にするだけで描ける事が分かります。
【基礎課題 6-3】
【基礎課題 6-1】のプログラムを修正して、上図で与えられた図形のy軸対称な図形を(元
の図形と共に)描くプログラムを作成しましょう。下がその実行結果です。
57
CG プログラミング論 平成 26 年 5 月 26 日
このプログラムは次のようになります。図形が変わったことに応じてその座標が下線部
の様に(
【基礎課題 6-1】から)変わりますが、あとは、点線枠部分を追加しただけです。
空欄①、②を埋めてプログラムを完成させて下さい。
void DrawGraphics(Graphics g) {
int[] x={0,30,90,60,90,30};
//多角形のx座標の定義
int[] y={0,-30,-30,0,30,30}; //多角形のy座標の定義
int N=6; //データ数(多角形の頂点の数)
int x0=100; //原点のx座標(コンピュータ上)
int y0=100; //原点のy座標(コンピュータ上)
int[] xp=new int[N]; //コンピュータ上のx座標を格納する配列
int[] yp=new int[N]; //コンピュータ上のy座標を格納する配列
g.setColor(Color.BLUE); //描画色を青に設定
//図形(多角形)の描画
for(int i=0; i<N; i++) {
xp[i]= x0+x[i] ;
yp[i]= y0-y[i] ;
}
g.drawPolygon(xp,yp,N); //多角形を描画
//y軸対称な図形の描画
for(int i=0; i<N; i++) {
xp[i]=
①
;
yp[i]=
;
②
}
g.drawPolygon(xp,yp,N); //多角形を描画
}
58
CG プログラミング論 平成 26 年 5 月 26 日
6-4
対称移動③
-
原点に対する対称移動
対称移動の最後の例として、原点に対する対称移動を採り上げましょう。左下の点線図
形が、
(右上の)図形を原点に対して対称移動したものです。
y軸
(30,90)
(0,60)
(30,30)
x軸
(-30,-30)
(0,-60)
(-30,-90)
図より、原点対称な図形と元の図形を比べると、対応する頂点の(x,y)座標が共に逆符
号になっている事が分かります。したがって、原点対称な図形は元となる図形の各点の(x,
y)座標を共に逆符号にすることで描ける事が分かります。
【基礎課題 6-4】
【基礎課題 6-1】のプログラムを
修正して、上図で与えられた図
形の原点対称な図形を(元の図
形と共に)描くプログラムを作
成しましょう。左がその実行結
果です。
59
CG プログラミング論 平成 26 年 5 月 26 日
このプログラムは次のようになります。図形が変わったことに応じてその座標および多
角形の頂点数 N が下線部の様に(
【基礎課題 6-1】から)変わりますが、あとは、点線枠部
分を追加しただけです。空欄①、②を埋めてプログラムを完成させて下さい。
void DrawGraphics(Graphics g) {
int[] x={0,30,30,0};
//多角形のx座標の定義
int[] y={0,30,90,60}; //多角形のy座標の定義
int N=4; //データ数(多角形の頂点の数)
int x0=100; //原点のx座標(コンピュータ上)
int y0=100; //原点のy座標(コンピュータ上)
int[] xp=new int[N]; //コンピュータ上のx座標を格納する配列
int[] yp=new int[N]; //コンピュータ上のy座標を格納する配列
g.setColor(Color.BLUE); //描画色を青に設定
//図形(多角形)の描画
for(int i=0; i<N; i++) {
xp[i]=x0+x[i];
yp[i]=y0-y[i];
}
g.drawPolygon(xp,yp,N); //多角形を描画
//原点対称な図形の描画
for(int i=0; i<N; i++) {
xp[i]=
①
;
yp[i]=
;
②
}
g.drawPolygon(xp,yp,N); //多角形を描画
}
60
CG プログラミング論 平成 26 年 5 月 26 日
6-5
対称移動の組み合わせ
何らかの対称性を持つ図形は、対称移動を組み合わせる事で(少ない労力で)描くことが
できます。下は、右上の図形(斜線領域)の図形から、これまで学習したx軸対称、y軸
対称そして原点対称な図形を作成し、合成したものです。
(-30,90)
y軸
(30,90)
y軸対称
(0,60)
(-30,30)
(30,30)
x軸
(-30,-30)
原点対称
(30,-30)
(0,-60)
(-30,-90)
x軸対称
(30,-90)
【基礎課題 6-5】
上図の図形を(対称移動を組み合わせることで)描画するプログラムを作成しましょう。
61
CG プログラミング論 平成 26 年 5 月 26 日
このプログラムは次のように記述できます。図から分かるとおり、基本的には【基礎課題
6-4】のプログラムに、x軸対称な図形およびy軸対称な図形を描く部分を追加したものに
なります。これまでの総復習として、下の空欄①~⑥を埋めてプログラムを完成させて下
さい。
void DrawGraphics(Graphics g) {
int[] x={0,30,30,0};
//多角形のx座標の定義
int[] y={0,30,90,60}; //多角形のy座標の定義
int N=4; //データ数(多角形の頂点の数)
int x0=100; //原点のx座標(コンピュータ上)
int y0=100; //原点のy座標(コンピュータ上)
int[] xp=new int[N]; //コンピュータ上のx座標を格納する配列
int[] yp=new int[N]; //コンピュータ上のy座標を格納する配列
g.setColor(Color.BLUE); //描画色を青に設定
//図形(多角形)の描画
for(int i=0; i<N; i++) {
【基礎課題 6-4】に追加し
xp[i]=x0+x[i];
yp[i]=y0-y[i];
た部分
}
g.drawPolygon(xp,yp,N); //多角形を描画
//x軸対称な図形の描画
for(int i=0; i<N; i++) {
①
xp[i]=
;
yp[i]=
②
;
xp[i]=
③
;
yp[i]=
④
;
}
g.drawPolygon(xp,yp,N); //多角形を描画
//y軸対称な図形の描画
for(int i=0; i<N; i++) {
}
g.drawPolygon(xp,yp,N); //多角形を描画
//原点対称な図形の描画
for(int i=0; i<N; i++) {
xp[i]=
yp[i]=
⑤
⑥
;
;
}
g.drawPolygon(xp,yp,N); //多角形を描画
}
62
CG プログラミング論 平成 26 年 5 月 26 日
6-6
原点回りの回転移動
本章の最後に、原点回りの回転移動を考えましょう。
左のように、点 A(x,y)を角度θだけ回転させ
y軸
た時の点を B とすると、その座標(x',y')は次の
B(x',y')
ように求められます。
x'  x cos  y sin 
θ
y '  x sin   y cos
A(x,y)
x軸
回転移動を記述するのに必要な式はこれだけ
です。
【基礎課題 6-6】
上の回転移動の式を利用して、次のように三角形を 90°だけ回転させて表示させるプロ
グラムを作成しましょう。
(x1',y1')
対応する頂点の座標は例えば次のように
y軸
なっています。
(x1,y1)
x1'  x1 cos  y1sin 
90°
y1'  x1sin   y1 cos
x軸
  90   / 2
作成するプログラムの実行
結果は左の通りです。
63
CG プログラミング論 平成 26 年 5 月 26 日
このプログラムを次のように記述しました。プログラムの意味はコメントから理解でき
るでしょう。下の点線枠部分がθ=90°(π/2)だけ回転させた図形を描く部分です。
void DrawGraphics(Graphics g) {
int[] x={0,50,50}; //多角形(今の場合三角形)のx座標の定義
int[] y={0,0,50};
//多角形(今の場合三角形)のy座標の定義
int N=3; //データ数(多角形の頂点の数)
int x0=100; //原点のx座標(コンピュータ上)
int y0=100; //原点のy座標(コンピュータ上)
int[] xp=new int[N]; //コンピュータ上のx座標を格納する配列
int[] yp=new int[N]; //コンピュータ上のy座標を格納する配列
g.setColor(Color.BLUE); //描画色を青に設定
//図形(多角形)の描画
double x_rot,y_rot,theta;
theta=0; //角度θ=0
for(int i=0; i<N; i++) {
x_rot=x[i]*Math.cos(theta)-y[i]*Math.sin(theta);//回転後のx座標
y_rot=x[i]*Math.sin(theta)+y[i]*Math.cos(theta);//回転後のy座標
xp[i]=x0+(int) x_rot;
コンピュータ上の座標(xp,yp)へ変換
yp[i]=y0-(int) y_rot;
}
g.drawPolygon(xp,yp,N); //多角形を描画
theta=Math.PI/2; //角度θ=π/2(90°)
for(int i=0; i<N; i++) {
x_rot=x[i]*Math.cos(theta)-y[i]*Math.sin(theta);//回転後のx座標
y_rot=x[i]*Math.sin(theta)+y[i]*Math.cos(theta);//回転後のy座標
xp[i]=x0+(int) x_rot;
yp[i]=y0-(int) y_rot;
}
g.drawPolygon(xp,yp,N); //多角形を描画
}
回転図形を描く部分
まず、このプログラムの動作結果を確認して下さい。
次に、このプログラムを利用(改良)して、次ページのような結果を与えるプログラムを作
成しました。図から分かるとおり、これは、90°(π/2)ずつ回転させた三角形を4つ表示さ
せたものです。
64
CG プログラミング論 平成 26 年 5 月 26 日
このプログラムを次のように作成しました。空欄①を埋めてプログラムを完成させて下
さい。
void DrawGraphics(Graphics g) {
int[] x={0,50,50}; //多角形のx座標の定義
int[] y={0,0,50};
//多角形のy座標の定義
int N=3; //データ数(多角形の頂点の数)
int x0=100; //原点のx座標(コンピュータ上)
int y0=100; //原点のy座標(コンピュータ上)
int[] xp=new int[N]; //コンピュータ上のx座標を格納する配列
int[] yp=new int[N]; //コンピュータ上のy座標を格納する配列
g.setColor(Color.BLUE); //描画色を青に設定
//図形(多角形)の描画
double x_rot,y_rot,theta,d_theta;
d_theta=
; //角度θの刻み幅
①
for(int j=0;j<4;j++) { //4つの三角形を繰り返し処理で描画
theta=d_theta*j; //角度θ
for(int i=0; i<N; i++) {
x_rot=x[i]*Math.cos(theta)-y[i]*Math.sin(theta);
y_rot=x[i]*Math.sin(theta)+y[i]*Math.cos(theta);
xp[i]=x0+(int) (x_rot);
yp[i]=y0-(int) (y_rot);
}
g.drawPolygon(xp,yp,N); //多角形を描画
}
}
65
CG プログラミング論 平成 26 年 5 月 26 日
【応用課題 6-A】
【基礎課題 6-6】のプログラムを
改良して右のような(風車のよう
な)図形を描きましょう。今度は
三角形を 12 個描き、三角形内を塗
りつぶしています。
このプログラムは【基礎課題
6-6】から下のように空欄①と下線
部を修正し、点線枠②を(三角形
を色塗りする様に)修正する事で
実現できます。空欄①を埋め、修
正後の点線枠②を記述して下さい。
void DrawGraphics(Graphics g) {
int[] x={0,50,50}; //多角形のx座標の定義
int[] y={0,0,50};
//多角形のy座標の定義
int N=3; //データ数(多角形の頂点の数)
int x0=100; //原点のx座標(コンピュータ上)
int y0=100; //原点のy座標(コンピュータ上)
int[] xp=new int[N]; //コンピュータ上のx座標を格納する配列
int[] yp=new int[N]; //コンピュータ上のy座標を格納する配列
g.setColor(Color.BLUE); //描画色を青に設定
//図形(多角形)の描画
double x_rot,y_rot,theta,d_theta;
d_theta=
; //角度θの刻み幅
①
for(int j=0;j<12;j++) {
theta=d_theta*j; //角度θ
for(int i=0; i<N; i++) {
x_rot=x[i]*Math.cos(theta)-y[i]*Math.sin(theta);
y_rot=x[i]*Math.sin(theta)+y[i]*Math.cos(theta);
xp[i]=x0+(int) (x_rot);
yp[i]=y0-(int) (y_rot);
}
g.drawPolygon(xp,yp,N); //多角形を描画
②
}
}
ヒント
点線枠②では、
「青色で三角形を塗りつぶし、その後に黒線で三角形(の輪郭)を
描く」という処理を行えば良いのです。多角形の塗りつぶしは「プログラミング」テキ
スト p.209 の fillPolygon(x,y,N)メソッドを用います。
66