光の屈折 optical refraction
かなり荒削りだけど屈折の原理とはどんなもんなのか考えてみた。
屈折率の高い媒質に移ると波長も短くなるのが分からなくもない
丸っこいのが光子で、赤いのが波のつもり。
2013.12.13 左上のテキストをクリックで屈折率変化
/**
* Copyright KBM ( http://wonderfl.net/user/KBM )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/vbl9
*/
package {
import flash.events.MouseEvent;
import flash.text.TextFieldAutoSize;
import flash.text.TextFormat;
import flash.text.TextField;
import flash.display.Stage;
import flash.display.Shape;
import flash.events.Event;
import flash.display.Sprite;
public class FlashTest extends Sprite {
public function FlashTest() {
// write as3 code here..
var frame:int = 0;
var particles:Array = [];
var fre_ap:int = 2; /*パーティクル出現頻度 1 ~ 60 推奨1 ~ 5*/
var n:Number = 1.6; /*屈折率*/
var waves:Array = [];
var ptcl_quantity:int = 20; /*パーティクル出現量*/
var medium1:Shape = new Shape(); /*媒質1*/
var medium2:Shape = new Shape(); /*媒質2*/
const SW:int = stage.stageWidth;
const SH:int = stage.stageHeight;
addChild(medium1);
with(medium1.graphics){
beginFill(0xDDDDFF);
drawRect(0,0,SW,SH / 3 * 2)
}
addChild(medium2)
with(medium2.graphics){
beginFill(0x444444);
drawRect(0,SH / 3 * 2, SW, SH / 3);
}
var n_changer:Sprite = new Sprite();
addChild(n_changer);
var n_change_text:TextField = new TextField();
with(n_change_text){
mouseEnabled = false;
autoSize = TextFieldAutoSize.CENTER;
defaultTextFormat = new TextFormat(null,20,0x0);
text = "n = 0.8\nn = 1.4\nn = 3\nn = 5";
}
n_changer.addChild(n_change_text);
n_changer.buttonMode = true;
n_changer.addEventListener(MouseEvent.CLICK,function ():void{
if(n_changer.mouseY < n_changer.height / 4) n = 0.8;
else if(n_changer.mouseY < n_changer.height / 4 * 2) n = 1.4;
else if(n_changer.mouseY < n_changer.height / 4 * 3) n = 3;
else if(n_changer.mouseY < n_changer.height) n = 5;
})
function enterFrame():void{
if(frame % (60 / fre_ap) == 0){
var w_particle:Array = [];
for(var i:int = 0; i < ptcl_quantity;i++){
var particle:Particle = new Particle();
particle.x = i * 10; particle.y = 10 * ptcl_quantity - i * 10;
w_particle.push(particle);
particles.push(particle);
addChild(particle);
}
var wave:Wave = new Wave(w_particle);
waves.push(wave);
addChild(wave);
}
if(frame % 1 == 0){
for(i = 0; i < particles.length; i ++){
with(particles[i]){
if(y > SH / 3 * 2){speed = 4 / n;}
}
with(particles[i]){
x += speed * Math.cos(argument * 3.1 / 180);
y += speed * Math.sin(argument * 3.1 / 180);
}
if(particles[i].y > SH && particles[i].x > SW ){
removeChild(particles[i])
particles.splice(i,1);
}
}
for(i = 0; i < waves.length ; i++){
with(waves[i]){
x = ctrlPoints[0].x;
y = ctrlPoints[ctrlPoints.length - 1].y - 10;
width = ctrlPoints[ctrlPoints.length - 1].x - ctrlPoints[0].x;
height = ctrlPoints[0].y - ctrlPoints[ctrlPoints.length - 1].y;
}
for(var j:int = 0; j < waves[i].ctrlPoints.length ; j++){
waves[i].ctrlPoints[j].argument = Math.atan2(waves[i].width,waves[i].height) * 180 / 3.1;
}
}
}
frame ++;
}
addEventListener(Event.ENTER_FRAME,enterFrame)
}
}
}
import flash.display.Shape;
import flash.display.Graphics;
import flash.display.Sprite;
import flash.geom.Point;
class Particle extends Sprite {
public var point:Point;
public var speed:Number;
public var argument:int;
private var g:Graphics;
private var r:int;
public function Particle(){
r = 2;
g = this.graphics;
g.beginFill(0xFFD700);
g.lineStyle(0,0x333333);
g.drawCircle(-r,-r,r);
speed = 4;
argument = 20; /*進行方向の偏角 1 ~ 360推奨*/
}
public function setPoints():void{
if(this.parent != null){
point = new Point(this.x,this.y);
}
}
}
class Wave extends Shape{
public var ctrlPoints:Vector.<Particle>;
private var g:Graphics;
public function Wave(particles:Array){
g = this.graphics
ctrlPoints = new Vector.<Particle>();
for(var i:int = 0; i < particles.length; i ++){
ctrlPoints.push(particles[i])
}
ctrlPoints.fixed = true;
g.lineStyle(3,0xDD0000);
g.moveTo(ctrlPoints[0].x,ctrlPoints[0].y);
g.lineTo(ctrlPoints[ctrlPoints.length - 1].x,ctrlPoints[ctrlPoints.length - 1].y);
}
}