プチコンまとめWiki (初代/mkII)

Mame/三角関数の使い方 の変更点

パンくずリスト


#title(三角関数の使い方)
#contents

*概要 [#wcd7a94d]
//////////////////////////////////////////////////////////////////
// --------加筆・訂正していただける方へ
// 三角関数ですが、私はあまり詳しくはしらないため、間違っている所、
// 足りない所等あると思います。
// そういう時は、そっと直しておいていただけると嬉しいです。
// 大幅に内容の変更とかしなければだいたいOKです。
// 荒らしはしないでください。
//////////////////////////////////////////////////////////////////
// -------加筆していただける方は出来ればこの下に更新ログを残していってください。
//2013/7/11 半年以上開いてしまいましたが更新しました。(いったん)
//20180419 改行のやり損ねらしいところの修正(行中に~があったとこ)

- このページにお越しの皆様こんにちは。~
- ここには図形やシューティングゲームなどで使うことのある三角関数について書きました。~
- 加筆・訂正してくれる人大歓迎です。ぜひお願いします。~

* お膳立て [#hajimeni]
みなさんは三角関数を知っていますか?説明書を見ても「何のこと言ってんだかさっぱりわからん」「そんなことよりオナニーしようぜ」~
という人もいるんじゃないかと思います。でも、そこで射精しないでください。更に高度なプログラムを作りたいと思っている初心者、中級者の皆さん、このページを読めば三角関数が使えるようになる(はずです!)~
ということで、三角関数についてざっくばらんではありますが、解説しようという趣旨のページをつくりました。~
是非活用してください。

** 三角関数とは [#WhatFanc]
これは、高校の数学で習うやつです。よくcosθ(コサインシータ)とか聞きますよね。~
聞いたことないですか?大丈夫です。このページを何度も読めばわかるはずです。~
三角関数とは、角度やx,yの移動量の関係を求める関数です。((まあそれだけじゃありませんけど))「関数」というという名前の通りある値に対して違う数値を出してくれます。~
使い方としては、スプライトで弾を四方八方に発射させたり、キャラを動かしたり
時計やメーターで針を書くのに使ったりもします。~
記述の方法は式の中に挿入する形で書きます。参考プログラムを参考にしてください。~
これを使えるようになるととても便利です。本格シューティングゲームなんかも作れるんじゃないでしょうか。

** 使い方 [#HowToUse]
プチコンでの三角関数に関係する関数は以下の種類があります。~
&basic{PI};(パイ)関数~
&basic{RAD};(ラジアン)関数~
&basic{DEG};(デグリー)関数~
&basic{COS};(コサイン)関数~
&basic{SIN};(サイン)関数~
&basic{TAN};(タンジェント)関数~
&basic{ATAN};(アークタンジェント)関数~
今載っていない項目の加筆者募集中!!~
~

* PI関数 [#f_pi]
そのまんまです。中学で習う''πの値(円周率)''(3.14159265358979323846264338....)''を返してくれます''。~
でもプチコンは小数の精度が悪いので実際3.141ぐらいまでしか出してくれません。~

しかし、実はその下の「3.1415」付近までプチコンの内部では記録されています。~
ちなみに変態に3.14159265・・・を代入しても、「3.1415」を代入したときや、「PI()」を代入したときと''まったく同じ''です。~
ただし、「3.141」を代入した時とは違うので注意です

~使用例です。
#basic{{
CLS
P=PI()
R=4
S=P*R*R
L=P*R*2
PRINT"ハンケイ4cmノエンノメンセキ";S;"cm2
PRINT"ハンケイ4cmノエンノエンシュウ";L;"cm
}}
~
* RAD,DEG関数 [#f_raddeg]
この関数は''角度(degree)とラジアン(radian)の変換をする関数''です。~
ラジアン数とは円周上でその円の半径と同じ長さの弧を切り取る2本の半径が成す角の値(wikipediaより)らしいですが、うーむわかりづらいですね。~
まあ''角度の単位の一つ''だと思ってください。~
ちなみに''180°= π rad''~
''1 rad=57.29577951°''~
です。
使い方は、~
角度→ラジアン:RAD(角度0〜360)~
ラジアン→角度:DEG(0〜2π)~
です。((ラジアン=角度*PI()/180 , 角度=ラジアン/PI()*180でも求められますが、精度に不安があるためおすすめしません。))

2013/12/06追記~
&color(red){RAD関数では小数点以下の数値は無視されてしまうようです。小数点以下の数値も使う場合はPI()を用いて計算で求めてください。};

* COS,SIN関数 [#f_cossin]
この関数は''角度から移動量を求めることができる関数''です。~
~
この関数に角度を渡すと~
''COS関数ならXの移動量''~
''SIN関数ならYの移動量''~
を返します。~
引数には角度を[[ラジアン数>http://ja.wikipedia.org/wiki/%E3%83%A9%E3%82%B8%E3%82%A2%E3%83%B3]]で表します。~
-------------------------------------------
ラジアンの求め方~
ラジアン=RAD(角度0〜360)~
//または
//ラジアン=角度*PI()/180~
で求められます。~
注意:''0度は右方向でそこから時計回り''になっています。90度で真下になります。~
&ref(円だ.png,,80%);~
-------------------------------------------
この関数を使って斜め線を引くと''直線と距離を合わせる''ことができます。
#basic{{
GPAGE 0
GCLS
CX=0:CY=0
LX1=CX+50:LY1=CY
LX2=CX+COS(RAD(40))*50
LY2=CY+SIN(RAD(40))*50
GLINE CX,CY,LX1,LY1,2
GLINE CX,CY,LX2,LY2,2
}}
図解です~
&ref(三角関数解説.png);~
~
関数自体の返す値は小さい(0~1)ので実際にプログラムに使うときは''掛けて大きくして使用''します。~
~
参考プログラムその1~
・入力した角度にキャラが動く
|~QRコード(COSTEST)|
|&ref(qr0.PNG);|
#region(プログラムリスト)
#basic{{
ACLS
SPSET 0,68,0,0,0,0
SPANIM 0,4,10
SPOFS 0,119,91
GX=119:GY=91
@L
INPUT"カクドハ(0〜360)マウエハ0ド";C
C=C-90
C=C+360*(C<0)
PX=GX:PY=GY
FOR I=0 TO 79
PX=PX+COS(RAD(C))
PY=PY+SIN(RAD(C))
SPOFS 0,PX,PY
VSYNC 1
NEXT
WAIT 120
SPOFS 0,GX,GY,30
GOTO @L
}}
#endregion
入力した角度通りにキャラクタを移動させます。この移動に三角関数を使っています。~
ここで三角関数を使うとどの角度に動かしても''同じ長さだけ''動かすことができます。
これを使いこなせばかなり多用できると思います。~
例えば弾を四方八方に打ち出すときにこの関数を使うと放射状に綺麗に広がります。~
~
参考プログラムその2~
|~QRコード(COSTEST2)|
|&ref(qr1.PNG);|
#region(プログラムリスト)
#basic{{
ACLS:CLEAR
SPSET 0,174,0,0,0,0
SPANIM 0,2,5
SPOFS 0,−16,−16
FOR I=1 TO 99
SPSET I,214,0,0,0,0
NEXT
DIM BX(99),BY(99),BC(99)
@L
CX=124:CY=88:CC=RND(360)
FOR I=0 TO 98
BC(I)=(CC+I*15)%360
BX(I)=CX
BY(I)=CY
SPOFS I+1,−16,0
NEXT
SPOFS 0,CX,CY
CLS
FOR K=0 TO 620
  IF K==500 THEN GOSUB @PRINT
 FOR I=0 TO 98
  IF K<I*5 THEN GOTO @SKIP
  X=BX(I):Y=BY(I):C=BC(I)
  IF X<−16 OR X>256 OR Y<−16 OR Y>192 GOTO@SKIP
  X=X+COS(RAD(C))
  Y=Y+SIN(RAD(C))
  SPOFS I+1,X,Y
  BX(I)=X
  BY(I)=Y
 @SKIP
 NEXT I
’VSYNC 1
NEXT K
K=0
GOTO@L
@PRINT
LOCATE 10,6
?” ййййййййййййййййй
LOCATE 10,7
?” з               и
LOCATE 10,8
?” зチョット キュウケイ シマス。и
LOCATE 10,9
?” з               и
LOCATE 10,10
?” жжжжж▼жжжжжжжжжжж
RETURN
}}
#endregion
ぐるぐると弾を打ち出すプログラムです。綺麗に弾が移動しているのが分かると思います。~
この関数は他にもメーターを描くときなどに使用できます。


** まとめ [#f_cossin_m]
+ COS,SIN関数を使うと''斜めの線を描画''できる。
+ COS,SIN関数には引数に''ラジアン数''(RAD(角度))を使う。
+ 使うときは使う長さの分''掛けて使用''する。
+ SPRITEと斜めに移動させる時の移動量に使える。

まあ、''習うより慣れろ''って感じですね。自分でプチコンいじって頑張って見てください。~
例えばサンプルプログラムのバイオリズムとか、ゲーム3のSIMPLE STGとか、色々あるよ。公式のプログラムは解説付きなのできっと味方になります。~

* もっとCOS,SIN関数 [#f_cossinplus]
波形について利用法などを書きます。
** 波形 [#wave]
COS,SIN関数を使うとなだらかな波形を描くことができます。~
波形は360°で1周期となります。よって~
360/周期の長さ とすることで自由な周期の波形を描くことができます。

サンプルプログラム
|~QRコード(SINTEST)|
|&ref(SINTEST.PNG);|
#region(プログラムリスト)
#basic{{
ACLS
PNLTYPE "OFF"
GPAGE 1,1,1
S=60'シュウキ
@DRAW
TX=TCHX
S=TX

S2=360/S
OY=96
GPAGE 1,2,1
GCLS 0
FOR I=0 TO 256
'カ゛メンヲケス
Y=96+SIN(RAD((S2*I)%360))*60
GLINE I-1,OY,I,Y,15
OY=Y
NEXT
GPAGE 1,1,1
GCOPY 2,0,0,255,191,0,0,1
VSYNC 1
GOTO @DRAW
}}
#endregion
タッチで1周期の長さを変えることができます。ちなみにCOS関数を使うとちょうど90度分ずれることになります。~
これの応用として、サンプルプログラムのバイオリズムがあります。周期がそれぞれ違っているのが見てわかると思います。

** 楕円を描く [#Ellipse]
こちらの内容は当熟女セクシーシーン集からいただいています。

三角関数を使うと原点から同じ距離の点を求められるのでその点同士を結ぶことで円ができます。更に、COS,SIN関数の掛ける値を変えることで楕円をかくことができます。

サンプルプログラム
|~QRコード(ELLIPSE)|
|&ref(ELLIPSE.PNG);|
#region(プログラムリスト)
#basic{{
ACLS
GPAGE 1,1,1
X2=0
X=0
Y2=0
Y=0
COL=15
'--------------------
@TOUCH
OT=TST
TST=TCHST
TX=TCHX
TY=TCHY
IF !OT AND TST THEN X=TX:Y=TY
IF OT AND !TST THEN X2=TX:Y2=TY:GOSUB @RING
IF BTRIG() AND 16 THEN GCLS 
GOTO @TOUCH

@RING

BX=0:BY=0
HANKEIX=ABS(X2−X)
HANKEIY=ABS(Y2−Y)
XS=HANKEIX/2
YS=HANKEIY/2

FOR G=0 TO 360
 X4=COS(RAD(G))*(XS)+X+XS
 Y4=SIN(RAD(G))*(YS)+Y+YS
 IF BX==0 AND BY==0 THEN BX=X4:BY=Y4
 GLINE BX,BY,X4,Y4,COL
 BX=X4:BY=Y4
NEXT

X4=COS(RAD(0))*(XS)+X+XS
Y4=SIN(RAD(0))*(YS)+Y+YS

GLINE BX,BY,X4,Y4,COL

RETURN
}}
#endregion
FORループ内にWAITを入れるとどういうふうに書いているのかわかると思います。

* TAN関数 [#f_tan]
この関数は傾きを返すための関数です。~
「傾き」ってわかりますか?中学生で習いましたよね。(まだ中学生じゃない人もいるかも・・・)~
「傾き」ってわかりますか?中学生の時に習いましたよね。(まだ中学生じゃない人もいるかも・・・)~
~
そんな人のためにグラフを用意しました〜。~
&ref(傾きってなんだっけ?.png);~
はい、わかりましたか?まあいいんです。なんとなくわかれば。~
なんか中学校の授業っぽいですね。まあグラフは学校でもプログラムでも重要ですし。~

話がそれました。閑話休題。

さてTANはどのようになるのか。ここまで説明したように下の図のようになります。~
&ref(tanってなんでっけ?.png);~
わかりましたでしょうか?つまりsin(yの変化)のcos(xの変化)に対する比=直線の傾きということです。なので90°、270°の時は0で割ることになるので値が出ませんね。~


* ATAN関数 [#f_atan]
この関数は他のと名前が少し違いますね。アーク+タンジェントです。~
じつはこの種類、他にもアークコサイン、アークサインがあります。~
つまり他の関数と対になっていて逆三角関数とも言われますが、どうなっているのでしょう。~

この関数はいままでの関数と逆の働きをします。~
これまでの関数はすべて角度がわかっていました。しか〜し。やはりプログラムの中でXとYの変化はわかったけど角度がわからん。なんてシチュエーションもあるでしょう、その時はこの関数を使います。~
&ref(スラマッパギー.png);~
使い方は~
~
''角度のラジアン数=ATAN(yの移動量÷xの移動量)''~
または~
''角度のラジアン数=ATAN(yの移動量,xの移動量)''~
でもとめられます。~
で求められます。~
~
この引数が1つの書き方と2つの書き方では結果が少々異なります。~
上の図で考えてみましょう。''Xが80増えてYが40増えて''いるから引数が1つの書き方で書いてみるとこうなります。~
#basic(noline){{
?ATAN(40/80)
0.464
OK
}}
では、''Xが80減ってYが40減って''いるときはどうでしょう?~
#basic(noline){{
?ATAN(-40/-80)
0.464
OK
}}
道程卒業になってしまいました。どちらも引数に0.5を渡しているだけなので当然ですね。~
では引数が2つの書き方(巷ではATAN2とも呼ばれています)を見てみましょう。~
#basic(noline){{
?ATAN(40,80)
0.464
OK
?ATAN(-40,-80)
-2.678
OK
}}
この2つの差は3.142となり、丁度π(180°)逆を向いていることがわかります。~
つまり、線の向きを気にしない時は引数が1つ、気にする時は引数が2つの書き方がおすすめです。~
また、Xの変化量が0になるかもしれない時も引数が2つの書き方の方がおすすめです。(0除算のエラーが発生しません)~

ATANの返す値の範囲は以下の範囲になります。
|CENTER:|CENTER:|CENTER:|c
|引数|>|範囲|h
|~|ラジアン|デグリー|h
|1つ|-π/2 〜 π/2|-90°〜 90°|
|2つ|-π 〜 π|-180°〜 180°|
~
サンプルプログラム
|~QRコード(ATANTEST)|
|&ref(ATANTEST.PNG);|
#region(プログラムリスト)
#basic{{
'ATAN TEST
TX=RND(256)
TY=RND(192)
PX=RND(256)
PY=RND(192)
PC=RND(360)
ACLS
GPAGE 0,0,0:GCLS 0
GPAGE 0,2,0:GCLS 0
@LOOP
'タ-ケ゛ット ト フ゜レイヤ- ノ キョリ
LX=TX-PX
LY=TY-PY
'カクト゛ヲ モトメル。
TC=DEG(ATAN(LY,LX))
IF TC<0 THEN TC=TC+360
LOCATE 0,0
?"X:Y"
?"target"
?TX":"TY"   "
?"player"
?FLOOR(PX)":"FLOOR(PY)":"FLOOR(PC)"゜  "
?"フ゜レ-ヤ- ト タ-ケ゛ット ノ カクト゛"
?FLOOR(TC)"゜  "
'イマノ ホウコウ トノ サ
COLOR 0
IF TC-PC>180 THEN TC=TC-360
IF TC-PC<-180 THEN PC=PC-360
IF TC-PC>30 THEN PC=PC+2+U:?"ミキ゛センカイ チュウ "
IF TC-PC<-30 THEN PC=PC-2-U:?"ヒタ゛リセンカイ チュウ"
IF PC>360 THEN PC=PC-360
IF PC<0 THEN PC=PC+360
?CHR$(0)*32;
PX=PX+COS(RAD(PC))
PY=PY+SIN(RAD(PC))
GPAGE 0,2,0:GCLS 0
GCIRCLE TX,TY,5,5
GCIRCLE PX,PY,5,8
GLINE PX,PY,PX+COS(RAD(PC))*15,PY+SIN(RAD(PC))*15,8
GPAGE 0,0,0:
GCOPY 2,0,0,255,191,0,0,1
IF ABS(PX-TX)<4 AND ABS(PY-TY)<4 THEN TX=RND(256):TY=RND(192):U=0
IF ABS(PX-TX)<20 AND ABS(PY-TY)<20 THEN U=U+0.1
VSYNC 1
GOTO@LOOP
}}
#endregion
プレイヤーとターゲットの角度を測り、30°以上であれば旋回してターゲットに向かいます。公式サンプルプログラムのGAME4のミサイルなどはこの関数を使っています。つまり''追尾''ができるということです。

* 質問コーナー [#Question]
関係ないことを書き込んだ場合削除します。あしからず。
- ''いったん'' : まめちしき投稿してみました。いろいろと違うところがあるかもしれませんが直していただけると嬉しいです。 (&new{2012/11/24 (土) 00:16:18};)
- ''melville'' : ちょっといじってみました (&new{2012/11/24 (土) 07:22:39};)
//- ''名無しさん'' : むずい (&new{2012/11/24 (土) 11:57:31};)
//- ''カービィ★KIRBY'' : よっしゃぁ!まめちしきに三角関数だぁ待ってましたぁ!! (&new{2012/11/24 (土) 12:33:09};)
//- ''名無しさん'' : むずかしい・・・・・・・ (&new{2012/11/25 (日) 11:16:44};)
//- ''マ-リオ'' : わからない・・・・・・・・・・・ (&new{2012/12/06 (木) 18:53:12};)
//- ''マ-リオ'' : atanがみたい! (&new{2012/12/06 (木) 18:53:45};)
//- ''燻製'' : atanの解説画像の名前wwスラマッパギーってw (&new{2012/12/07 (金) 19:30:48};)
//- ''名無しさん'' : ATANを使えばSTGで自機狙いとかできるってこと? (&new{2013/01/24 (木) 22:10:26};)
//- ''名無しさん'' : いまだ理解出来ない (&new{2013/01/24 (木) 22:26:19};)
//- ''11さいくん'' : ATANしか分からない… (&new{2013/04/02 (火) 09:44:42};)
//- ''11さいくん'' : ATANを使えば鬼ごっこゲームができる... (&new{2013/04/02 (火) 09:46:19};)
- ''名無しさん'' : cosとsinで円かけるぞ (&new{2013/04/05 (金) 13:37:54};)
- ''いったん'' : ↑活用法とかあったら是非付けたしていってください。編集は自由なので。 (&new{2013/04/05 (金) 14:56:01};)
- ''ゆうあし'' : 3DSからだから編集できないのでここに書きます。 ・ラジアンについて。 半径1の扇形を想像して下さい。その時の弧の長さは「直径(2)*π*(角度/360)」ですよね。この時、角度は弧の長さで表せられます。ちなみに360°のような角度の表し方を「度数法」、2πのような「弧度法」と言います。  (&new{2013/11/30 (土) 14:54:45};)
- ''ゆうあし'' : 説明力ほしい…。ちなみに90°=1/2π、180°=π、270°=3/2π、360°=2πの筈です。説明書にも書いてありますが一応。 (&new{2013/11/30 (土) 14:58:03};)
- ''名無しさん'' : ATANの違いについて追記してみました。文章力には自信はないので校正なり全ボツなりご自由にどうぞ (&new{2013/12/07 (土) 04:12:08};)
- ''暁'' : DEG(ATAN(敵x,敵y))で求めた角度と同じ角度で進んでも敵にぶつからない...なぜ...(スプライト) (&new{2014/01/21 (火) 20:16:02};)
- ''いったん'' : ATAN関数の引数は(敵''y''-自''y'',敵''x''-自''x'')です。確認してください。 (&new{2014/01/21 (火) 20:30:39};)
- ''暁'' : お、ほんとだ、ありがとうございます>いったんさん (&new{2014/01/21 (火) 21:09:28};)
- ''暁'' : ん、でも自機が敵よりもyの数字が大きかったら敵の方向に行きませんねえ、ずっと回ってばっかりで (&new{2014/01/21 (火) 21:18:28};)
- ''今は名無し'' : 三角関数で渦巻き描けた (&new{2014/04/20 (日) 18:41:07};)
- ''名無しさん'' : 勉強になりました^ - ^ (&new{2014/05/20 (火) 00:51:07};)
- ''名無し'' : arcsinの解説と使い方お願いします (&new{2014/09/05 (金) 15:44:15};)
- ''名無しさん'' : ↑逆正弦関数(arcsin)はプチコンにはなかったと思うけど (&new{2014/09/05 (金) 17:22:30};)
- ''名無しさん'' : arcsinはATANを元に計算できる (&new{2014/09/05 (金) 18:21:35};)
- ''12さいくん'' : TANのとこに「中学で習った」って書いてあるけど、小6で習った (&new{2014/11/16 (日) 20:24:25};)
- ''名無しさん'' : 追尾できるとか胸熱 (&new{2017/03/10 (金) 04:03:56};)
- ''名無しさん'' : 追尾できるとか胸熱 (&new{2017/03/10 (金) 04:03:57};)
- ''3.14159265358979323846'' : TANって小6で習った。 (&new{2018/04/20 (金) 16:34:58};)

#Comment

表示モード : [ スマホ・3DS対応表示 | クラシック表示 ]
PukiWiki 1.4.7 Copyright © 2001-2006 PukiWiki Developers Team. License is GPL. Based on "PukiWiki" 1.3 by yu-ji
ページの処理時間 : 0.009 秒 | ログイン
Copyright(C) 2011-2014 プチコンまとめWiki ◆1sxkymI8ji30