光の反射
Re: 光の反射
「光の反射の描画」とは具体的にどういうモノなのか説明してください。
Re: 光の反射
まずはDXライブラリのことを一切考えず,数学的にどうやってやればいいかを考えるといいでしょう.
なぜかというと,DXライブラリは基本的に,指定された2つの座標に線を引くとか,指定された位置に指定された大きさの球を描くことしかしてくれないからです.自動的に入射角=反射角の式を用いて線を引いてくれる,という機能はありません.
つまり,まずは描画のことは一切考慮せず,描きたい直線の式を求めればいいということです.
描きたい直線の式が求まったらプログラムに落とし込みます.
なぜかというと,DXライブラリは基本的に,指定された2つの座標に線を引くとか,指定された位置に指定された大きさの球を描くことしかしてくれないからです.自動的に入射角=反射角の式を用いて線を引いてくれる,という機能はありません.
つまり,まずは描画のことは一切考慮せず,描きたい直線の式を求めればいいということです.
描きたい直線の式が求まったらプログラムに落とし込みます.
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 14年前
- 住所: 東海地方
- 連絡を取る:
Re: 光の反射
ところで3Dなのか2Dなのかをお聞きして良いですか?
後DrawLineとかを使ってプログラムは組めますか?
【補足】nonさんも書いていますが、telfさんがプログラムを組むのが前提で我々はそれをお手伝いするだけです。
理論を理解しないと応用できないと思いますので、分かるところだけでもプログラムを組んでもらって問題点を明確にして行きましょう。
後DrawLineとかを使ってプログラムは組めますか?
【補足】nonさんも書いていますが、telfさんがプログラムを組むのが前提で我々はそれをお手伝いするだけです。
理論を理解しないと応用できないと思いますので、分かるところだけでもプログラムを組んでもらって問題点を明確にして行きましょう。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: 光の反射
#include "DxLib.h"
int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int){
ChangeWindowMode(TRUE), DxLib_Init(), SetDrawScreen( DX_SCREEN_BACK ); //ウィンドウモード変更と初期化と裏画面設定
int Cr;
int x=200,y=200;
Cr=GetColor(255,255,255);
// while(裏画面を表画面に反映, メッセージ処理, 画面クリア)
while( ScreenFlip()==0 && ProcessMessage()==0 && ClearDrawScreen()==0 ){
DrawLine(x ,y ,300 ,300 ,Cr); //入射光
DrawLine(300 ,300 ,400 ,200 ,Cr); //反射光
DrawLine(200 ,300 ,400 ,300 ,Cr); //鏡の変わり
}
DxLib_End(); // DXライブラリ終了処理
return 0;
}
2Dです。
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 14年前
- 住所: 東海地方
- 連絡を取る:
Re: 光の反射
鏡の反射は純粋に数学的な計算になりますが、
(1)直線の方程式
(2)2直線の交点の座標
(3)2つの線分のなす角度
で求め方分からないものがありますか?
出来れば習っているか確認したいので学年とかも教えてもらってよいでしょうか?
(1)直線の方程式
(2)2直線の交点の座標
(3)2つの線分のなす角度
で求め方分からないものがありますか?
出来れば習っているか確認したいので学年とかも教えてもらってよいでしょうか?
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: 光の反射
もし入射光がベクトルで与えられていて、
鏡が画面に並行か垂直である場合は三角関数を使わなくても簡単に計算できますね。
速度が要求される場合はテーブルを作っておく場合もありますが。
鏡が画面に並行か垂直である場合は三角関数を使わなくても簡単に計算できますね。
C言語ではcos関数があるので予め定義する必要はありません。telf さんが書きました: 自分の頭のなかでは、#defineでcosθ(0~90)を定義して
斜辺や底辺を定義してcosθを求めるのかと思っていました。
速度が要求される場合はテーブルを作っておく場合もありますが。
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 14年前
- 住所: 東海地方
- 連絡を取る:
Re: 光の反射
私の方法は鏡が自由に動く前提で、高校3年なら理解できると思います。
(1)はそのとおりです。
(2)は(1)の2つの直線の方程式の交わる点を求めること。1つの直線は光線でもう一つの直線は鏡の面です。
つまり、鏡の面の何処にあたっているかを求めるのに使います。ここを基準に光は反射されるのと入ってきた光線はここまで止まります。
「2年3章7回」
http://sakura.canvas.ne.jp/spr/ynaka/2nen-3/2307.html
ただし交点が鏡の面のサイズ範囲にあることの確認は必要です。
(3)は入射角を求めるのに使います。(2)と同様に光線と鏡です。
「2直線のなす角」
http://w3e.kanazawa-it.ac.jp/math/categ ... ukaku.html
「線分の角度関係が簡単に分かる便利なテクニック」
http://www.h4.dion.ne.jp/~zero1341/t/04.htm
以上です。
交点と入射角が分かったので反射角は求まりますので入射光と反射光は、これで描画できます。
(1)はそのとおりです。
(2)は(1)の2つの直線の方程式の交わる点を求めること。1つの直線は光線でもう一つの直線は鏡の面です。
つまり、鏡の面の何処にあたっているかを求めるのに使います。ここを基準に光は反射されるのと入ってきた光線はここまで止まります。
「2年3章7回」
http://sakura.canvas.ne.jp/spr/ynaka/2nen-3/2307.html
ただし交点が鏡の面のサイズ範囲にあることの確認は必要です。
(3)は入射角を求めるのに使います。(2)と同様に光線と鏡です。
「2直線のなす角」
http://w3e.kanazawa-it.ac.jp/math/categ ... ukaku.html
「線分の角度関係が簡単に分かる便利なテクニック」
http://www.h4.dion.ne.jp/~zero1341/t/04.htm
以上です。
交点と入射角が分かったので反射角は求まりますので入射光と反射光は、これで描画できます。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: 光の反射
#include "DxLib.h"
#include <math.h>
int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int){
ChangeWindowMode(TRUE), DxLib_Init(), SetDrawScreen( DX_SCREEN_BACK ); //ウィンドウモード変更と初期化と裏画面設定
int Cr;
int a=20,x=10;
int y=a*x;
int z=-a*x;
Cr=GetColor(255,255,255);
// while(裏画面を表画面に反映, メッセージ処理, 画面クリア)
while( ScreenFlip()==0 && ProcessMessage()==0 && ClearDrawScreen()==0 ){
DrawLine(0,0,a,y,Cr);
}
DxLib_End(); // DXライブラリ終了処理
return 0;
}
上のソースは試しで打ちました。
変数yの値を変えるには変数への代入しかないでしょうか?
また、Cで連立方程式はどのようにやればよいのでしょうか?
Re: 光の反射
(1次)連立方程式の解き方はこちらを参考にどうぞ。
http://dixq.net/forum/blog.php?u=536&b=2655
http://dixq.net/forum/blog.php?u=536&b=2655
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 14年前
- 住所: 東海地方
- 連絡を取る:
Re: 光の反射
DXライブラリ以前にC言語で問題を解くことが出来ていない様ですね。
簡単なものからプログラムを書いてみましょうか。
(1)の直線の方程式をプログラムしてみましょう。
例えばx1=10,y1=50とx2=100,y2=130が与えられた時にこの2点を通る直線の方程式y=ax+bのaとbを求めるプログラムを書いてみてください。
もし余力があればDXライブラリで実際に線を引いてみましょう。ただし、y=0からy=400までの線を引きます。上で求めたaとbを使って計算して下さい。
簡単なものからプログラムを書いてみましょうか。
(1)の直線の方程式をプログラムしてみましょう。
例えばx1=10,y1=50とx2=100,y2=130が与えられた時にこの2点を通る直線の方程式y=ax+bのaとbを求めるプログラムを書いてみてください。
もし余力があればDXライブラリで実際に線を引いてみましょう。ただし、y=0からy=400までの線を引きます。上で求めたaとbを使って計算して下さい。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: 光の反射
#include <stdio.h>
#include <math.h>
int main(){
int a1,a2,b1,b2 ;
int x1=10,y1=50 ; /*一次方程式①のx座標、y座標*/
int x2=100,y2=130 ; /*一次方程式②のx座標、y座標*/
/*1次方程式①y1=a1*x1+b1*/
b1=y1/(a1*x1) ;
a1=(b1-y1)/x1 ;
printf("b1の値は%dです。a1の値は%dです。\n",b1,a1);
/*一次方程式②y2=a2*2+b2 */
b2=y2/(a2*x2) ;
a2=(b2-y2)/x2 ;
printf("b2の値は%dです。a2の値は%dです。\n",b2,a2);
return 0;
}
エラー C4700: 初期化されていないローカル変数 が使用されます
と出ました。どうすれば良いのでしょうか?
また,式としてはこれであっているでしょうか?
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 14年前
- 住所: 東海地方
- 連絡を取る:
Re: 光の反射
●数学的な問題点
数学的に考えて2点しか与えられていないので1つの直線の方程式しか求められません。
もう一度数学の教科書を読み直してみましょう。
「2点を通る直線の方程式」 ← 参考
http://www.geisya.or.jp/~mwm48961/math3 ... func1.html
●プログラミングとしての問題点。
a1,b1を求めるのにb1=y1/(a1*x1) ;としたらa1と言う不定値を使っていることになります。これがC4700エラーの原因です。
上から順番で実行されるプログラムの流れ的にNGですのでプログラミングの基礎として流れを意識することは非常に重要です。よく考えてみて下さい。
数学的に考えて2点しか与えられていないので1つの直線の方程式しか求められません。
もう一度数学の教科書を読み直してみましょう。
「2点を通る直線の方程式」 ← 参考
http://www.geisya.or.jp/~mwm48961/math3 ... func1.html
●プログラミングとしての問題点。
a1,b1を求めるのにb1=y1/(a1*x1) ;としたらa1と言う不定値を使っていることになります。これがC4700エラーの原因です。
上から順番で実行されるプログラムの流れ的にNGですのでプログラミングの基礎として流れを意識することは非常に重要です。よく考えてみて下さい。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: 光の反射
/*
***********************************************************
* 連立方程式の解法(ガウス・ジョルダン法) *
***********************************************************
*/
/*y=ax+b*/
/*x1=10,y1=50,x2=100,y2=130*/
#include <stdio.h>
#include <math.h>
#define N 2 /*元の数*/
void main(void)
{
double A[N] [N+1]={{50, 10, 1}, /*********/
{130, 100, 1}};/* 係数行列*/
double p,d;
int i,j,k;
for(k=0;k<N;k++){
p=A[k][k];
for (j=k;j<N;j++){
A[k][j]=A[k][j]/p;
for(i=0;i<N;i++){
if(i!=k){
d=A[i][k];
for(j=k;j<N;j++)
A[i][j]=A[i][j]-d*A[k][i];
}
}
}
for(k=0;k<N;k++)
printf("x%d=%f\n",k+1,A[k][N]);
}
}
22行までは、処理の内容を理解できたのですが、そのあとが、よくわからないので、どこをどう変えて、a,bを求めればわからなくて、
詰まってます。
また、前回のソフト屋さんの投稿で、連立でやるといわれたこと忘れてました。
Re: 光の反射
参考にしたサイトor本にこのままのコードが載っていたのですか?
インデントを整えた方がいいですよ。
↓C言語インデント補正マシン
http://www34.atpages.jp/mikecat/js/indent/index.html
インデントを整えた方がいいですよ。
↓C言語インデント補正マシン
http://www34.atpages.jp/mikecat/js/indent/index.html
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 14年前
- 住所: 東海地方
- 連絡を取る:
Re: 光の反射
肝心のアルゴリズムが分からないといった感じですね。
実際の所簡単な式なのでガウス・ジョルダン法を使わなくても解けます。
y1=x1*a+b
y2=x2*a+b
の連立方程式からaを求める式とbを求める式を作り出してみてください。
普通に学校で習う方法で出来ますよ。
「中二/連立方程式1」
http://www.geisya.or.jp/~mwm48961/math/qu_2_1.htm
【補足】ちなみに後々のためにプログラム化するときにx1,x2,y1,y2の変数は必ず使って下さい。
実際の所簡単な式なのでガウス・ジョルダン法を使わなくても解けます。
y1=x1*a+b
y2=x2*a+b
の連立方程式からaを求める式とbを求める式を作り出してみてください。
普通に学校で習う方法で出来ますよ。
「中二/連立方程式1」
http://www.geisya.or.jp/~mwm48961/math/qu_2_1.htm
【補足】ちなみに後々のためにプログラム化するときにx1,x2,y1,y2の変数は必ず使って下さい。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: 光の反射
#include <stdio.h>
#include <math.h>
int main(){
int a,b ;
int x1=10,y1=50 ; /*一次方程式①のx座標、y座標*/
int x2=20,y2=120 ; /*一次方程式①のx座標、y座標*/
/*連立方程式加減法*/
/*{y1=a*x1+b*/
/*{y2=a*x2+b*/
/*-10a=50-120*/
/* a=7 */
/*b=70-50 */
/*b=20 */
a=(50-120)/-10 ;
b=a*x1-y1;
printf("a=%dです。b=%dです。\n",a,b);
return 0;
}
これで、合ってるでしょうか
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 14年前
- 住所: 東海地方
- 連絡を取る:
Re: 光の反射
素直に式を代入法で変換するだけなのですが・・・。
自分で答えがあっているか検証できるので試してみてください。
a,bが求まればx1からy1、x2からy2が計算できるはずです。
あとaとbを求める式をちゃんとx1,x2,y1,y2で書いて下さい。
残念ですが違います。ごく基本的なミスをされてます。
自分で答えがあっているか検証できるので試してみてください。
a,bが求まればx1からy1、x2からy2が計算できるはずです。
あとaとbを求める式をちゃんとx1,x2,y1,y2で書いて下さい。
残念ですが違います。ごく基本的なミスをされてます。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 14年前
- 住所: 東海地方
- 連絡を取る:
Re: 光の反射
C言語の理屈で言えば違う値が入っているので変数名が違わないといけません。
手書き式だとしても値が違うものなので何らかの形で名前は変えてやらないとマズイですよね。
手書き式だとしても値が違うものなので何らかの形で名前は変えてやらないとマズイですよね。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: 光の反射
#include <stdio.h>
#include <math.h>
int main(){
int a,b ;
int x1=10,y1=50 ; /*一次方程式①のx座標、y座標*/
int x2=100,y2=130; /*一次方程式①のx座標、y座標*/
/*連立方程式加減法*/
/*{y1=a*x1+b*/
/*{y2=a*x2+b*/
/*50=10a+b*/
/*b=10a-50式①*/
/*130=100a+b*/
/*b=100a-130式②*/
/*100a-10a=130-50*/
/*90a=80*/
a=80/90;
b=10*a-50;
printf("a=%dです。b=%dです。\n",a,b);
return 0;
}
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 14年前
- 住所: 東海地方
- 連絡を取る:
Re: 光の反射
まず、筆算で合っていることを確認してみてください。y=ax+bで計算は合いますか?
あとプログラムは直接数値を書くのではなく、aの式はx1,x2,y1,y2はそのまま式に残してくださいね。
(1)y1=x1*a+b
と
(2)y2=x2*a+b
ですのでbを消してみましょう。
まず(1)をbの式に変形します。
y1=x1*a+b
↓
y1-x1*a=b
↓
b=y1-x1*a
はOKですか?
あとは、このbを(2)の式に当てはめてaを求める式に変形するだけです。
あとプログラムは直接数値を書くのではなく、aの式はx1,x2,y1,y2はそのまま式に残してくださいね。
(1)y1=x1*a+b
と
(2)y2=x2*a+b
ですのでbを消してみましょう。
まず(1)をbの式に変形します。
y1=x1*a+b
↓
y1-x1*a=b
↓
b=y1-x1*a
はOKですか?
あとは、このbを(2)の式に当てはめてaを求める式に変形するだけです。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 14年前
- 住所: 東海地方
- 連絡を取る:
Re: 光の反射
(2)に代入してどうなるか書いてみてくださいね。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 14年前
- 住所: 東海地方
- 連絡を取る:
Re: 光の反射
代入法を行うのはあくまで方程式の話でC言語の話ではありません。
(2)に対して(1)の変形式を代入してbを消去した式を作ってみてください。
(2)に対して(1)の変形式を代入してbを消去した式を作ってみてください。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: 光の反射
#include <stdio.h>
#include <math.h>
int main(){
double a,b ;
int x1=10,y1=50 ; /*一次方程式①のx座標、y座標*/
int x2=100,y2=130; /*一次方程式①のx座標、y座標*/
/*連立方程式代入法*/
/*式①
y1=a*x1+b*/
/*b=y1-a*x1;
/*式②
y2=a*x2+b
y2-b=a*x2*/
/*y2-(y1-a*x1)=a*x2
y2-y1+a*x1=a*x2
a*x1-a*x2=-(y2-y1)*/
a =-(y2-y1)/(x1-x2);
b=y1-a*x1;
printf("a=%4.2fです。b=%4.2fです。\n",a,b);
return 0;
}
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 14年前
- 住所: 東海地方
- 連絡を取る:
Re: 光の反射
今回の場合は少数以下を計算する必要があるので全ての型をdoubleにしないとマズイです。intが交じると小数点以下が計算されません。
プログラムで検証できるはずのですので検証処理も続いて書いてみてください。x1から求めたy1answerとy1が同じならOKですが違うならなにか間違っています。同様にx2もチェックしてみてください。
プログラムで検証できるはずのですので検証処理も続いて書いてみてください。x1から求めたy1answerとy1が同じならOKですが違うならなにか間違っています。同様にx2もチェックしてみてください。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 14年前
- 住所: 東海地方
- 連絡を取る:
Re: 光の反射
aとbがもとまっているので直線の方程式であるy=x*a+bの式に当てはめればx1からy1がx2からy2の値が求まります。telf さんが書きました:手書きの数学でやる確認計算みたいなかんじですよね
手書きに連立方程式に確認式もわからないんですけど・
ちゃんと求まればaとbは正しいと確認できます。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: 光の反射
#include <stdio.h>
#include <math.h>
int main(){
double a,b ;
double x1=10,y1=50 ; /*一次方程式①のx座標、y座標*/
double x2=100,y2=130; /*一次方程式①のx座標、y座標*/
/*連立方程式代入法*/
/*式①
y1=a*x1+b*/
/*式②
y2=a*x2+b*/
/*bを消す*/
/*y1-y2=(a*x1-a*x2)
y1-y2=a(x1-x2)*/
a=(y1-y2)/(x1-x2);
/*①にaを代入*/
/* y1=a*x1+b */
b=y1-a*x1;
printf("a=%4.2fです。b=%4.2fです。\n",a,b);
if(y1==a*x1+b){
printf("正解\n");
}else {
printf("不正解\n");
}
if(y2=a*x2+b){
printf("正解\n");
}else {
printf("不正解\n");
}
return 0;
}
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 14年前
- 住所: 東海地方
- 連絡を取る:
Re: 光の反射
実行してみると分かりますが一致しません。これは浮動小数点の計算誤差問題が原因です。[補足]混乱させちゃうので先の書いておくべきでした。
if(y2=a*x2+b){
は比較条件になっていませんので=と==の書き間違いには注意して下さいね。
この場合は人の目で確認したほうが早いです。
printf("y1=%4.2f (a*x1+b)=%4.2f\n",y1,(a*x1+b));
printf("y2=%4.2f (a*x2+b)=%4.2f\n",y2,(a*x2+b));
doubleは誤差を持つと覚えておいて下さい。
じゃあ、前に書いた通りこの直線方程式を使ってy1=0からy1=400まで直線をDrawLineしてみましょう。
【追記】実行しての結果と結果の自分なりの考察もお願いします。なんか実行しているのかいないのか分からないのが気になります。
if(y2=a*x2+b){
は比較条件になっていませんので=と==の書き間違いには注意して下さいね。
この場合は人の目で確認したほうが早いです。
printf("y1=%4.2f (a*x1+b)=%4.2f\n",y1,(a*x1+b));
printf("y2=%4.2f (a*x2+b)=%4.2f\n",y2,(a*x2+b));
doubleは誤差を持つと覚えておいて下さい。
じゃあ、前に書いた通りこの直線方程式を使ってy1=0からy1=400まで直線をDrawLineしてみましょう。
【追記】実行しての結果と結果の自分なりの考察もお願いします。なんか実行しているのかいないのか分からないのが気になります。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 14年前
- 住所: 東海地方
- 連絡を取る:
Re: 光の反射
名前が分かりづらかったですかね。今回のはlx,lyとしましょう。telf さんが書きました:ってことは、softya(ソフト屋) さんが書きました: じゃあ、前に書いた通りこの直線方程式を使ってy1=0からy1=400まで直線をDrawLineしてみましょう。
y1=a*xa+b;
y2=a*x2+b;
の連立ですよね?
また、y以外の変数は前回と同じ数値で連立すればよいのでしょうか?
今までので既に直線の方程式は求まっていますので、aとbの値はそのまま使います。
double x1=10,y1=50 ; /*一次方程式①のx座標、y座標*/
double x2=100,y2=130; /*一次方程式①のx座標、y座標*/
を通る直線の方程式であるy=a*x+bを使いましょう。
がly1=0とly2=400の時に、それぞれどのlx1,lx2座標を通るか求めるだけです。
後は(lx1,ly1)と(lx2,lx2)の直線を引きます。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: 光の反射
#include"DxLib.h"
int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int){
ChangeWindowMode(TRUE),DxLib_Init(),SetDrawScreen(DX_SCREEN_BACK);
int Cr=GetColor(255,255,255);
double a,b ;
double x1=10,y1=50 ; /*一次方程式①のx座標、y座標*/
double x2=100,y2=130; /*一次方程式①のx座標、y座標*/
/*連立方程式代入法*/
/*式①
y1=a*x1+b*/
/*式②
y2=a*x2+b*/
/*bを消す*/
/*y1-y2=(a*x1-a*x2)
y1-y2=a(x1-x2)*/
a=(y1-y2)/(x1-x2);
/*①にaを代入*/
/* y1=a*x1+b */
b=y1-a*x1;
double ly1=0,ly2=400,lx1,lx2;
/*y=a*x+b*/
/* y-b=a*x */
lx1=(ly1-b)/a;
lx2=(ly2-b)/a;
// while(裏画面を表画面に反映, メッセージ処理, 画面クリア)
while( ScreenFlip()==0 && ProcessMessage()==0 && ClearDrawScreen()==0 ){
DrawLine(ly1,ly1,lx2,ly2,Cr);
}
DxLib_End();
return 0;
}
warning C4244: '引数' : 'double' から 'int' への変換です。データが失われる可能性があります。
というのが出ました。
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 14年前
- 住所: 東海地方
- 連絡を取る:
Re: 光の反射
DrawLineの引数はintですからキャストして下さい。
あと引数が間違っています。よく見なおしてみてください。
基準となる座標点をプロットしてキャストしたもの。間違いはそのまま。
あと引数が間違っています。よく見なおしてみてください。
基準となる座標点をプロットしてキャストしたもの。間違いはそのまま。
#include"DxLib.h"
int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int){
ChangeWindowMode(TRUE),DxLib_Init(),SetDrawScreen(DX_SCREEN_BACK);
int Cr=GetColor(255,255,255);
double a,b ;
double x1=10,y1=50 ; /*一次方程式①のx座標、y座標*/
double x2=100,y2=130; /*一次方程式①のx座標、y座標*/
/*連立方程式代入法*/
/*式①
y1=a*x1+b*/
/*式②
y2=a*x2+b*/
/*bを消す*/
/*y1-y2=(a*x1-a*x2)
y1-y2=a(x1-x2)*/
a=(y1-y2)/(x1-x2);
/*①にaを代入*/
/* y1=a*x1+b */
b=y1-a*x1;
double ly1=0,ly2=400,lx1,lx2;
/*y=a*x+b*/
/* y-b=a*x */
lx1=(ly1-b)/a;
lx2=(ly2-b)/a;
// while(裏画面を表画面に反映, メッセージ処理, 画面クリア)
while( ScreenFlip()==0 && ProcessMessage()==0 && ClearDrawScreen()==0 ){
DrawLine((int)ly1,(int)ly1,(int)lx2,(int)ly2,Cr);
DrawCircle((int)x1,(int)y1,3,GetColor(255,0,0),TRUE);//座標点をプロット
DrawCircle((int)x2,(int)y2,3,GetColor(255,0,0),TRUE);//座標点をプロット
}
DxLib_End();
return 0;
}
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: 光の反射
座標点プロットとは、なんでしょうか?softya(ソフト屋) さんが書きました:あと引数が間違っています。よく見なおしてみてください。
基準となる座標点をプロットしてキャストしたもの。間違いはそのまま。
DrawCircle((int)x1,(int)y1,3,GetColor(255,0,0),TRUE);//座標点をプロット
DrawCircle((int)x2,(int)y2,3,GetColor(255,0,0),TRUE);//座標点をプロッ卜
また、引数は計算式が間違ってるのでしょうか?
↑自分では、どこがまちがってるのかわからないです・
Re: 光の反射
座標点をプロットするというのは,座標点を描画するという意味です.
Re: 光の反射
#include"DxLib.h"
int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int){
ChangeWindowMode(TRUE),DxLib_Init(),SetDrawScreen(DX_SCREEN_BACK);
int Cr=GetColor(255,255,255);
double a,b ;
double x1=10,y1=50 ; /*一次方程式①のx座標、y座標*/
double x2=100,y2=130; /*一次方程式①のx座標、y座標*/
/*連立方程式代入法*/
/*式①
y1=a*x1+b*/
/*式②
y2=a*x2+b*/
/*bを消す*/
/*y1-y2=(a*x1-a*x2)
y1-y2=a(x1-x2)*/
a=(y1-y2)/(x1-x2);
/*①にaを代入*/
/* y1=a*x1+b */
b=y1-a*x1;
double ly1=0,ly2=400,lx1,lx2;
/*y=a*x+b*/
/* y-b=a*x */
lx1=(ly1-b)/a;
lx2=(ly2-b)/a;
// while(裏画面を表画面に反映, メッセージ処理, 画面クリア)
while( ScreenFlip()==0 && ProcessMessage()==0 && ClearDrawScreen()==0 ){
DrawLine((int)lx1,(int)ly1,(int)lx2,(int)ly2,Cr);
DrawCircle((int)x1,(int)y1,3,GetColor(255,0,0),TRUE);//座標点をプロット
DrawCircle((int)x2,(int)y2,3,GetColor(255,0,0),TRUE);//座標点をプロット
}
DxLib_End();
return 0;
}
修正して、実行したら、点の上をしっかり通りました。
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 14年前
- 住所: 東海地方
- 連絡を取る:
Re: 光の反射
そうです。そこが問題でした。私の書いた座標プロットで行う様なセルフチェックを行う習慣はゲームを作る上でとても大事です。
自分しか仕様が分かっていないゲームのチェックが出来るのは自分だけだからですね。
さて、続いては鏡の反射ですね。2直線の交点を求めます。
その前に今後のテスト用に直線をサーチライトの様に動かすプログラムも良いかも知れませんが、どちらをやられますか?
自分しか仕様が分かっていないゲームのチェックが出来るのは自分だけだからですね。
さて、続いては鏡の反射ですね。2直線の交点を求めます。
その前に今後のテスト用に直線をサーチライトの様に動かすプログラムも良いかも知れませんが、どちらをやられますか?
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 14年前
- 住所: 東海地方
- 連絡を取る:
Re: 光の反射
次の2つを提案しますので選んでみてください。
(1)鏡の反射は、2直線の交点を求めます。
交点については説明済みですね。これを計算するプログラムと仮想の鏡との衝突点を座標プロットして表示します。
(2)ただ反射を表現しても面白みに欠けるので(1)の前に今のプログラムのx2,y2を移動するものに変えてサーチライトのように動くプログラムを作って見ませか?
よりゲームっぽくなります。
(1)鏡の反射は、2直線の交点を求めます。
交点については説明済みですね。これを計算するプログラムと仮想の鏡との衝突点を座標プロットして表示します。
(2)ただ反射を表現しても面白みに欠けるので(1)の前に今のプログラムのx2,y2を移動するものに変えてサーチライトのように動くプログラムを作って見ませか?
よりゲームっぽくなります。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: 光の反射
softyaさんが言っているのは,光の反射の交点を求めるという理論的な部分を先に実装するか,動く鏡の絵を描画する部分を先に実装するかという話だと思います.
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 14年前
- 住所: 東海地方
- 連絡を取る:
Re: 光の反射
beatleさんの言われる通りで(2)はちょっと遊び心を入れてみましょうって話です。
最終的には(1)をやりますよ、
(1)はい。何処にも動かせるのが目標です。更に両面鏡とか片面鏡とかも区別できる計算方法をお教えすることも出来ます。
(2)光の方向が移動するといったイメージです。懐中電灯で周りを探るといった感じでしょうか。
出来ればC言語の関数化したいのですが関数は学習済みですか?
最終的には(1)をやりますよ、
(1)はい。何処にも動かせるのが目標です。更に両面鏡とか片面鏡とかも区別できる計算方法をお教えすることも出来ます。
(2)光の方向が移動するといったイメージです。懐中電灯で周りを探るといった感じでしょうか。
出来ればC言語の関数化したいのですが関数は学習済みですか?
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: 光の反射
ってことは、(1)をやろうが(2)をやろうと、最終的には両方やるってことですね?softya(ソフト屋) さんが書きました:beatleさんの言われる通りで(2)はちょっと遊び心を入れてみましょうって話です。
最終的には(1)をやりますよ、
(1)はい。何処にも動かせるのが目標です。更に両面鏡とか片面鏡とかも区別できる計算方法をお教えすることも出来ます。
(2)光の方向が移動するといったイメージです。懐中電灯で周りを探るといった感じでしょうか。
出来ればC言語の関数化したいのですが関数は学習済みですか?
それなら、(1)からでもいいです。
関数は学習とは自作関数とか、そういう分野ことでしょうか?
自作関数なら、一応学習しました。
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 14年前
- 住所: 東海地方
- 連絡を取る:
Re: 光の反射
じゃあ、(1)と言うことで交点の計算をしてみてください。情報は前に出てきています。
鏡の座標はmx1,my1,mx2,my2としましょうか。
とこれも直線の方程式のa,bが欲しいですね。
そうすると・・・。
交点の前に直線の方程式のa,bを求める自作関数を作りましょう。
今のプログラムを改造して、直線の方程式のa,bを求める部分を関数化して下さい。
a,b二つの値を戻すので戻り値を構造体にするか、a,bをポインタ渡しで渡す必要があります。
出来る方でお願いします。
鏡の座標はmx1,my1,mx2,my2としましょうか。
とこれも直線の方程式のa,bが欲しいですね。
そうすると・・・。
交点の前に直線の方程式のa,bを求める自作関数を作りましょう。
今のプログラムを改造して、直線の方程式のa,bを求める部分を関数化して下さい。
a,b二つの値を戻すので戻り値を構造体にするか、a,bをポインタ渡しで渡す必要があります。
出来る方でお願いします。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 14年前
- 住所: 東海地方
- 連絡を取る:
Re: 光の反射
x1,x2,y1,y2は引数で受け取って下さい。他のa,bを求める時にも同じ関数を使います。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: 光の反射
#include"DxLib.h"
double a,b;
int renritu(double ,double , double , double );/*プロトタイプ宣言*/
int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int){
ChangeWindowMode(TRUE),DxLib_Init(),SetDrawScreen(DX_SCREEN_BACK);
double x1=10,y1=50 ; /*一次方程式①のx座標、y座標*/
double x2=100,y2=130; /*一次方程式①のx座標、y座標*/
double ly1=0,ly2=400,lx1,lx2;
int Cr=GetColor(255,255,255);
renritu(x1,y1,x2,y2);
/*y=a*x+b*/
/* y-b=a*x */
lx1=(ly1-b)/a;
lx2=(ly2-b)/a;
// while(裏画面を表画面に反映, メッセージ処理, 画面クリア)
while( ScreenFlip()==0 && ProcessMessage()==0 && ClearDrawScreen()==0 ){
DrawLine((int)lx1,(int)ly1,(int)lx2,(int)ly2,Cr);
DrawCircle((int)x1,(int)y1,3,GetColor(255,0,0),TRUE);//座標点をプロット
DrawCircle((int)x2,(int)y2,3,GetColor(255,0,0),TRUE);//座標点をプロット
}
DxLib_End();
return 0;
}
int renritu(double x1,double y1, double x2, double y2 ){ /* a,bの値を計算する関数*/
a=(y1-y2)/(x1-x2);
b=y1-a*x1;
return 0;
}
上のでは、ダメでしょうか?
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 14年前
- 住所: 東海地方
- 連絡を取る:
Re: 光の反射
なぜなら別の直線の方程式を求める時に困るからです。telf さんが書きました:必ずポインタか構造体でやらないとダメなのでしょうか?
次の交点を求めるときに、もう一つ別のa,bを求めてみようって話になりますので使いやすいように組みましょう。
それと関数名はrenritu()では無くchokusen_no_houteisiki()の方が良いと思います。より意味的に正しい名前を使いましょう。
ちなみに英語で書くとLinear_equation()です。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 14年前
- 住所: 東海地方
- 連絡を取る:
Re: 光の反射
具体的に何が分からないのでしょうか?
構造体を戻り値とする方法でしょうか?
● 構造体の引数と戻り値
「4.2.6.3 関数からの戻り値」
http://www.kiso.tsukuba.ac.jp/~makimura ... ode77.html
それとも構造体自体の宣言の方法でしょうか?
[補足] なぜ、こういう聞き方をするかというと具体的な質問には具体的な答えを返せますが、曖昧なものには曖昧な答えしか返せないからです。
なので出来るだけ具体的な質問をしてもらうと的確な答えが返せると思います。
プログラムを組むということは明確にやること意識して曖昧なことを無くすということですので、具体的な質問を考えることはプログラムを組むことのよい訓練にもなります。
構造体を戻り値とする方法でしょうか?
● 構造体の引数と戻り値
「4.2.6.3 関数からの戻り値」
http://www.kiso.tsukuba.ac.jp/~makimura ... ode77.html
それとも構造体自体の宣言の方法でしょうか?
[補足] なぜ、こういう聞き方をするかというと具体的な質問には具体的な答えを返せますが、曖昧なものには曖昧な答えしか返せないからです。
なので出来るだけ具体的な質問をしてもらうと的確な答えが返せると思います。
プログラムを組むということは明確にやること意識して曖昧なことを無くすということですので、具体的な質問を考えることはプログラムを組むことのよい訓練にもなります。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 14年前
- 住所: 東海地方
- 連絡を取る:
Re: 光の反射
そうです。そう言う風に疑問を具体的にすることが大事です。telf さんが書きました:構造体の宣言は、わかるのですが、
構造体を使って自作関数からメイン関数へ引数を返す方法がわからないのです。
私はtelfさんの理解レベルがわかりませんので具体的に聞いてもらうのがベストです。
参考サイトは見てもらえましたか?
引数と戻り値で構造体を使っていますね。
まず、戻り値はreturnに書かれた値が関数の呼びだし元の変数に代入されると覚えて下さい。
a = func();
のaの値は関数が次のような場合 でaに1が入ります。
これが構造体でも同様です。
return 構造体変数1;
とすれば
構造体変数2 = func();
で構造体変数1の内容は構造体変数2に代入されます。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: 光の反射
#include"DxLib.h"
struct chokusen {
double a;
double b;
double x1;
double y1;
double x2;
double y2;
};
int chokusen_no_housiki();
/*int chokusen_no_houteisiki(double,double,double,double );/*プロトタイプ宣言*/
int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int){
ChangeWindowMode(TRUE),DxLib_Init(),SetDrawScreen(DX_SCREEN_BACK);
double x1=10,y1=50 ; /*一次方程式①のx座標、y座標*/
double x2=100,y2=130; /*一次方程式①のx座標、y座標*/
double ly1=0,ly2=400,lx1,lx2;
int Cr=GetColor(255,255,255);
a=chokusen_no_housiki();
/*y=a*x+b*/
/* y-b=a*x */
lx1=(ly1-b)/a;
lx2=(ly2-b)/a;
// while(裏画面を表画面に反映, メッセージ処理, 画面クリア)
while( ScreenFlip()==0 && ProcessMessage()==0 && ClearDrawScreen()==0 ){
DrawLine((int)lx1,(int)ly1,(int)lx2,(int)ly2,Cr);
DrawCircle((int)x1,(int)y1,3,GetColor(255,0,0),TRUE);//座標点をプロット
DrawCircle((int)x2,(int)y2,3,GetColor(255,0,0),TRUE);//座標点をプロット
}
DxLib_End();
return 0;
}
int chokusen_no_housiki()
{
struct chokusen ret;
struct chokusen p;
ret.a=(p.y1-p.y2)/(p.x1-p.x2);
ret.b=p.y1-p.a*p.x1;
return ret;
}
↑のコードは、未完成なので、どう修正すればようでしょうか?
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 14年前
- 住所: 東海地方
- 連絡を取る:
Re: 光の反射
戻り値と引数は構造体を分けたほうが良いと思います。
などを使われてはどうでしょうか?
それと構造体変数の受け渡しや受け取りができてません。
beatleさんの書かれた事に注意して組み直してみてください。
これらは全て構造体変数になりますので値を初期化後、関数の引数として下さい。 同様にこれらのa,bは戻り値として代入された構造体変数を使わなくてはいけません。
それと構造体変数の受け渡しや受け取りができてません。
beatleさんの書かれた事に注意して組み直してみてください。
これらは全て構造体変数になりますので値を初期化後、関数の引数として下さい。 同様にこれらのa,bは戻り値として代入された構造体変数を使わなくてはいけません。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 14年前
- 住所: 東海地方
- 連絡を取る:
Re: 光の反射
プログラム全体を掲載して下さい。
定義次第ですが、
struct chokusen housiki(struct PointXY p)
ではないでしょうか?
struct chokusenとstruct PointXYが定義されているという前提となります。
あとhousikiはbeatleさんが指摘されております。
自作関数や構造体の知識がかなり曖昧なので、一度C言語の教科書を見なおされたほうが良いかと思います。
↓ こちらでもよろしいですが。
「苦しんで覚えるC言語」
http://9cguide.appspot.com/
定義次第ですが、
struct chokusen housiki(struct PointXY p)
ではないでしょうか?
struct chokusenとstruct PointXYが定義されているという前提となります。
あとhousikiはbeatleさんが指摘されております。
自作関数や構造体の知識がかなり曖昧なので、一度C言語の教科書を見なおされたほうが良いかと思います。
↓ こちらでもよろしいですが。
「苦しんで覚えるC言語」
http://9cguide.appspot.com/
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: 光の反射
C言語では構造体定義は次のようになります.
TagNameは型名ではなくて「構造体タグ名」と呼ばれるものです.型として使う場合,structを省略できないのです.「struct TagName」で一つの型になる,と考えればOKです.
ちなみに,typedefを使って以下のように定義すると,TypeNameが型名として使えるようになります. 参考までに,typedefの構文は です.
ちなみに,typedefを使って以下のように定義すると,TypeNameが型名として使えるようになります. 参考までに,typedefの構文は です.