news 2026/5/26 1:30:20

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

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
制作物理知识动画 光的折射控制器

<!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>

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/25 0:29:29

让大模型记住你:必学的持久化记忆+动态画像+多智能体框架实现指南

本文提出一种个性化大模型框架&#xff0c;通过持久化记忆(STM/LTM/摘要/用户画像)和多智能体协作(协调/检索/验证/生成)实现自适应、连续性、定制化对话。系统将当前任务、历史交互与用户偏好融入决策上下文&#xff0c;通过反思校验提升回答质量&#xff0c;在长对话场景表现…

作者头像 李华
网站建设 2026/5/26 4:26:36

Langchain-Chatchat网络安全法条文解析工具

Langchain-Chatchat网络安全法条文解析工具 在数字化转型加速推进的今天&#xff0c;企业合规压力与日俱增。尤其是面对《网络安全法》《数据安全法》和《个人信息保护法》等法规日益严格的监管要求&#xff0c;如何快速、准确地响应法律咨询、完成合规审查&#xff0c;成为许多…

作者头像 李华
网站建设 2026/5/25 8:09:14

Langchain-Chatchat攻防演练FAQ智能应答系统

Langchain-Chatchat攻防演练FAQ智能应答系统 在网络安全攻防演练中&#xff0c;一线人员常常面临这样的窘境&#xff1a;面对突发问题&#xff0c;明明知道公司内部有详细的操作手册和应急预案&#xff0c;却要在几十份PDF、Wiki页面和邮件记录中反复翻找&#xff0c;耗时动辄半…

作者头像 李华
网站建设 2026/5/25 14:36:06

Langchain-Chatchat企业微信安全使用知识查询平台

Langchain-Chatchat企业微信安全使用知识查询平台 在企业数字化转型不断加速的今天&#xff0c;员工对内部制度、流程规范和合规要求的信息获取需求日益增长。然而&#xff0c;许多企业的知识仍散落在PDF、Word文档甚至纸质文件中&#xff0c;查找困难、响应滞后&#xff0c;新…

作者头像 李华
网站建设 2026/5/25 18:28:02

Langchain-Chatchat Teams协作工具安全知识平台

Langchain-Chatchat&#xff1a;构建企业级安全知识协作平台 在数字化转型浪潮中&#xff0c;企业积累的文档资产日益庞大——从员工手册、财务制度到技术规范&#xff0c;这些“沉默的知识”往往散落在各个共享盘和邮箱附件里。当一名新员工询问“年假如何申请”时&#xff0c…

作者头像 李华