当前位置: 首页 > news >正文

制作物理知识动画 光的折射控制器

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>光的折射控制器</title>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<style>
body {
display: flex;
flex-direction: column;
align-items: center;
background: #f0f0f0;
font-family: Arial, sans-serif;
}
#container {
position: relative;
width: 600px;
height: 400px;
border: 2px solid #333;
margin: 20px 0;
overflow: hidden;
}
#medium1 {
position: absolute;
top: 0;
width: 100%;
height: 50%;
background: #e0f7fa;
}
#medium2 {
position: absolute;
bottom: 0;
width: 100%;
height: 50%;
background: #bbdefb;
}
#normal {
position: absolute;
left: 300px;
top: 0;
width: 1px;
height: 400px;
background: #f00;
}
#ray {
position: absolute;
left: 300px;
top: 0;
width: 200px;
height: 2px;
background: #000;
transform-origin: left center;
}
#ray::after {
content: '';
position: absolute;
right: 0;
top: -5px;
border: 6px solid transparent;
border-left-color: inherit;
}
.control {
margin: 10px 0;
}
</style>
</head>
<body>
<h1>光的折射控制器</h1>
<div id="container">
<div id="medium1" title="介质1"></div>
<div id="medium2" title="介质2"></div>
<div id="normal" title="法线"></div>
<div id="ray" title="光线"></div>
</div>

<div class="control">
<label>入射角:<span id="iAngle">45</span>°</label>
<input type="range" id="iSlider" min="0" max="89" value="45">
</div>
<div class="control">
<label>介质1折射率:<span id="n1Val">1.0</span></label>
<input type="range" id="n1Slider" min="1.0" max="2.0" step="0.1" value="1.0">
</div>
<div class="control">
<label>介质2折射率:<span id="n2Val">1.5</span></label>
<input type="range" id="n2Slider" min="1.0" max="2.0" step="0.1" value="1.5">
</div>
<div class="control">
<label>光线颜色:</label>
<input type="color" id="colorPicker" value="#000000">
</div>
<div class="control">
<label>折射角:<span id="rAngle">28</span>°</label>
</div>
<div class="control">
<label>斯涅尔定律:n₁sinθ₁ = n₂sinθ₂</label>
</div>

<script>
const ray = document.getElementById('ray');
const iAngleSpan = document.getElementById('iAngle');
const rAngleSpan = document.getElementById('rAngle');
const n1ValSpan = document.getElementById('n1Val');
const n2ValSpan = document.getElementById('n2Val');
const iSlider = document.getElementById('iSlider');
const n1Slider = document.getElementById('n1Slider');
const n2Slider = document.getElementById('n2Slider');
const colorPicker = document.getElementById('colorPicker');

function updateRay() {
const iAngle = parseFloat(iSlider.value);
const n1 = parseFloat(n1Slider.value);
const n2 = parseFloat(n2Slider.value);

// 计算折射角(斯涅尔定律)
const sinI = Math.sin(iAngle * Math.PI / 180);
const sinR = (n1 * sinI) / n2;
const rAngle = sinR > 1 ? 90 : Math.asin(sinR) * 180 / Math.PI;

// 更新显示
iAngleSpan.textContent = iAngle;
rAngleSpan.textContent = rAngle.toFixed(0);
n1ValSpan.textContent = n1;
n2ValSpan.textContent = n2;

// 绘制入射光线
ray.style.transform = `rotate(${iAngle}deg)`;
ray.style.width = '200px';
ray.style.top = '0';
ray.style.backgroundColor = colorPicker.value;
ray.style.borderLeftColor = colorPicker.value;

// 绘制折射光线
if (sinR <= 1) {
const refractedRay = document.getElementById('refractedRay') || document.createElement('div');
refractedRay.id = 'refractedRay';
refractedRay.style.position = 'absolute';
refractedRay.style.left = '300px';
refractedRay.style.top = '200px';
refractedRay.style.width = '200px';
refractedRay.style.height = '2px';
refractedRay.style.backgroundColor = colorPicker.value;
refractedRay.style.transformOrigin = 'left center';
refractedRay.style.transform = `rotate(${-rAngle}deg)`;
refractedRay.style.borderLeftColor = colorPicker.value;
refractedRay.innerHTML = '<div style="position:absolute;right:0;top:-5px;border:6px solid transparent;border-left-color:inherit;"></div>';
document.getElementById('container').appendChild(refractedRay);
} else {
document.getElementById('refractedRay')?.remove();
}
}

// 绑定事件
iSlider.addEventListener('input', updateRay);
n1Slider.addEventListener('input', updateRay);
n2Slider.addEventListener('input', updateRay);
colorPicker.addEventListener('input', updateRay);

// 初始化
updateRay();
</script>
</body>
</html>

http://www.cnnetsun.cn/news/163254.html

相关文章:

  • 9大高级RAG技术详解:提升大模型检索效果的实战指南
  • Langchain-Chatchat移动设备安全管理知识库
  • Langchain-Chatchat JWT令牌机制知识库构建
  • Langchain-Chatchat文件共享权限管理问答系统
  • Langchain-Chatchat IOC指标查询问答工具
  • Langchain-Chatchat渗透测试报告生成辅助工具
  • 50、多线程编程:任务控制与并行迭代
  • 51、多线程编程全解析
  • ML Workspace终极指南:5分钟搭建专业级机器学习环境
  • Langchain-Chatchat DevOps运维知识整合实践
  • Jetpack Compose响应式布局实战:构建自适应多屏Android应用
  • 端侧AI部署技术深度解析:从架构原理到行业实战
  • 30、构建安全、高效的企业级Web农场与数据仓库
  • Langchain-Chatchat数据安全法解读知识检索工具
  • React-Move 动画库终极指南:从入门到精通的完整实践手册
  • xPack OpenOCD 安装配置完全指南:快速搭建嵌入式调试环境
  • Langchain-Chatchat嵌入模型本地化部署要点
  • Proton-GE Wayland完全指南:解锁原生Linux游戏体验
  • Zed编辑器插件生态:完整指南与开发实战
  • CppMicroServices 终极指南:5步掌握C++模块化开发
  • SVG转Canvas渲染引擎终极指南:从零到精通的完整教程
  • Browser-Use Web-UI完全指南:让AI智能体在浏览器中自主工作的终极方案
  • Langchain-Chatchat科研辅助系统构建:论文资料智能问答平台
  • FastAPI蓝绿部署实战指南:实现零停机更新
  • Langchain-Chatchat能否支持视频文档解析?多媒体处理展望
  • 如何在3天内用TFLearn构建医疗AI预测模型:完整指南
  • 【第1章·第8节】自适应MPC控制器的simulink建模与仿真
  • C# 简介
  • S3Proxy加密机制深度解析:透明安全的云端数据保护方案
  • 如何用NixOS和Hyprland构建终极Linux桌面:完整配置指南