-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathLens-sheet.html
More file actions
242 lines (206 loc) · 11.3 KB
/
Lens-sheet.html
File metadata and controls
242 lines (206 loc) · 11.3 KB
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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>レンズのはたらき</title>
<link rel="stylesheet" href="common.css">
<script src="common.js"></script>
</head>
<body onLoad="loopd()">
<h2>レンズのはたらき(作図練習用)</h2>
Chromeの場合は、[Ctrl + P]で、ページ印刷ができます。簡単に、練習プリントが作成できる!<br>
光線の本数
<input type="range" value="20" min="10" max="300" step="1"
oninput="document.getElementById('output1').value=this.value * 2">
<output id="output1">40</output>
<input type="checkbox" name="sakuzu" id="sakuzu" value="sakuzu">作図用の線を描画する
<br><input type="checkbox" name="kekka" id="kekka" value="kekka">作図結果の表示
<br>下の図形上でクリックすると全光線を描画します<br>
<canvas id="cv" style="background-color:#FFFFFF;">
図形を表示するには、canvasタグをサポートしたブラウザが必要です。
</canvas>
<br>2020.3.19 phys-ken作成
<script>
//領域
var cvs = document.getElementById("cv");
var ctx = cvs.getContext("2d");
cvs.width = document.documentElement.clientWidth - 10;
cvs.height = cvs.width * 8 / 16;
w = cvs.width;
h = cvs.height
//光源
var X = (1 / 6) * w; //初期座標 X
var Y = (1 / 2) * h; //初期座標y
var L = Math.sqrt(h * h + w * w); //対角線の長さ
//var honsu = 70; //光線の本数
var r = h / 20; //光源の半径
//スリット
slithole = h / 3; //スリットの穴の高さdef120
slitw = w / 50; //幅
slitx = w * 1 / 2; //スリットの位置
//レンズ
var f = w / 8; //焦点距離
var state; //全光線のstate
function loopd() {
cvs.addEventListener('click', function(e) {
if (state == 0) { state = 1; } else { state = 0; }
});
cvs.addEventListener("mousemove", function(e) {
var rect = e.target.getBoundingClientRect();
if (e.clientX - rect.left <= slitx) {
if (e.clientX - rect.left != slitx - f) {
X = e.clientX - rect.left;
Y = e.clientY - rect.top;
}
}
});
function loop() { draw(); requestAnimationFrame(loop); }
requestAnimationFrame(loop);
}
function draw() {
var flag1 = document.getElementById("sakuzu").checked;
if (flag1 == true) {
sakuzustate = 1;
} else {
sakuzustate = 0;
}
var flag3 = document.getElementById("kekka").checked;
if (flag3 == true) {
var kekkastate = 1;
} else {
kekkastate = 0;
}
var ho = document.getElementById('output1');
var honsu = ho.value;
ctx.clearRect(0, 0, w, h); //canvasの初期化
drawGridDotted(16, 8); // グリッドを最初に描画(背景として)
/////////////////////////////////////////////結像公式から、像の位置を求める////////////////////////////////////
var zouX;
var zouY;
var distXslit = slitx - X; //結像公式のa
var distzouX; //結像公式のb
var kh = Y - (h / 2);//光源の光軸からの高さh
var zouH;//像の光軸からの高さH
distzouX = (f * distXslit) / (distXslit - f);
zouX = slitx + distzouX;
zouH = f * kh / (distXslit - f);
zouY = -1 * zouH + (h / 2);
/////////////////////////////////////////////結像公式から、像の位置を求める////////////////////////////////////
///////////////////////////////////////////////////////////////////////放射状に線を引く/////////////////////////////////////////////////////////////////
//まずは、縦線だけ引く
if (state == 0) {//stateが0だったら全体の光線、そうじゃなかったら代表線のみ
var L = Math.sqrt(h * h + w * w); //全体の光線を表示する場合
} else {
var L = 0; //代表線のみを表示する場合
}
X2 = X + L * Math.sin(Math.PI * 0);
Y2 = Y - L * Math.cos(Math.PI * 0);
ctx.beginPath(); // 1.Pathで描画を開始する
ctx.moveTo(X, Y); // 2.描画する位置を指定する
ctx.lineTo(X2, Y2);
ctx.strokeStyle = "black";
ctx.lineWidth = 1.5;
ctx.stroke();
//放射状に引く
for (var i = 1; i < 2 * (honsu); i++) {
if (state == 0) {
var L = Math.sqrt(h * h + w * w); //全体の光線を表示する場合
} else {
var L = 0; //代表線のみを表示する場合
}
if (i < (honsu)) {
takasa = (slitx - X) * Math.tan((Math.PI * i / honsu) + Math.PI / 2); //光面と光線の交点の高さ
yoko = slitx - X;//光面と光源の距離
if (Y + takasa < h / 2 + slithole / 2 && Y + takasa > h / 2 - slithole / 2) {
L = Math.sqrt(takasa * takasa + yoko * yoko);
}
}
X2 = X + L * Math.sin(Math.PI * i / honsu);//レンズとの交点のX座標
Y2 = Y - L * Math.cos(Math.PI * i / honsu);//レンズとの交点のy座標
ctx.beginPath(); // 1.Pathで描画を開始する
ctx.moveTo(X, Y); // 2.描画する位置を指定する
ctx.lineTo(X2, Y2);
ctx.strokeStyle = "black";
ctx.lineWidth = 1.5;
ctx.stroke(); // 4.Canvas上に描画する
var L = Math.sqrt(h * h + w * w);
//レンズより奥
if (kekkastate === 1) {
if (X == slitx - f) {//光源が焦点にあるとき
if (Y + takasa < h / 2 + slithole / 2 && Y + takasa > h / 2 - slithole / 2) {//レンズより内側なら屈折
var L = Math.sqrt(h * h + w * w);
}
} else if (X >= slitx - f) {//光源が焦点とレンズの間にあるとき
if (Y + takasa < h / 2 + slithole / 2 && Y + takasa > h / 2 - slithole / 2) {//レンズより内側なら屈折
linemaker(X2, Y2, zouX, zouY, w, "black");
}
} else {//光源が焦点より左にあるとき
if (Y + takasa < h / 2 + slithole / 2 && Y + takasa > h / 2 - slithole / 2) {//光線のうち、レンズの内側にある光線については、屈折させる。
linemaker(X2, Y2, zouX, zouY, w, "black");
var L = Math.sqrt(h * h + w * w);
}
}
}
}
///////////////////////////////////////////////////////////////////////放射状に線を引いた/////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////光源/////////////////////////////////////////////////////////////////
drawSource(X, Y, r, 'red');
///////////////////////////////////////////////////////////////////////光源/////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////スクリーン/////////////////////////////////////////////////////////////
// パスをリセット
ctx.beginPath();
//色を指定する
ctx.fillStyle = "black"; //塗りつぶしの色は黒
//左から,上から,の位置に、幅,高さ,の四角形を描く
ctx.fillRect(w - (w / 80), 0, w / 80, h);
// 線を描画を実行
ctx.stroke();
//////////////////////////////////////////////////////////////スクリーン/////////////////////////////////////////////////////////////
/* /////////////////////////////////////////////////////////////スリット/////////////////////////////////////////////////////////////
// パスをリセット
ctx.beginPath();
//色を指定する
ctx.fillStyle = "black"; //塗りつぶしの色は黒
//左から,上から,の位置に、幅,高さ,の四角形を描く
ctx.fillRect(slitx, 0, slitw, h / 2 - slithole / 2); //スリット上部
ctx.fillRect(slitx, h / 2 + slithole / 2, slitw, h / 2 - slithole / 2); //スリット下部
// 線を描画を実行
ctx.stroke();
/////////////////////////////////////////////////////////////スリット///////////////////////////////////////////////////////////// */
/////////////////////////////////////////////////////////////焦点(教科書スタイル:十字マーカー)/////////////////////////////////////////////////////////////
var fmSz = Math.max(6, h / 50);
drawFocusMarker(slitx + f, h / 2, fmSz); //f(右)
drawFocusMarker(slitx - f, h / 2, fmSz); //f(左)
drawFocusMarker(slitx + 2 * f, h / 2, fmSz); //2f(右)
drawFocusMarker(slitx - 2 * f, h / 2, fmSz); //2f(左)
/////////////////////////////////////////////////////////////焦点終わり/////////////////////////////////////////////////////////////
////////////////////////////////////////////光軸(両端矢印付き)
drawAxisWithArrows(2);
////////////光軸終わり
/////////////レンズをかく////////////////////////////////
lensw = w / 40;
ctx.strokeStyle = "black";
ctx.lineWidth = 3;
ctx.beginPath();
ctx.moveTo(slitx, (h / 2) - (slithole / 2));
ctx.quadraticCurveTo(slitx - lensw, h / 2, slitx, (h / 2) + (slithole / 2));
ctx.stroke();
ctx.beginPath();
ctx.moveTo(slitx, (h / 2) - (slithole / 2));
ctx.quadraticCurveTo(slitx + lensw, h / 2, slitx, (h / 2) + (slithole / 2));
ctx.stroke();
drawLensEndArrows(slitx, (h / 2) - (slithole / 2), (h / 2) + (slithole / 2));
/////////////レンズをかく////////////////////////////////
///////////////////////////////////sakuzustate==1のとき作図用の光線を引く///////////////////////////////////
if (sakuzustate == 1) {
linemaker(X, Y, slitx, h / 2, w, "blue");
linemaker(slitx, Y, slitx + f, h / 2, w, "blue");
linemaker(X, Y, slitx, Y, slitx, "blue");
}
///////////////////////////////////////////////////////////////////////////////////
// グリッドは draw() 冒頭で描画済み
}
</script>
</body>
</html>