正弦与余弦函数教学演示-探索函数正余弦函数的参数影响

06 11月
作者:cinjep|分类:辅助教学

交互式的正弦与余弦函数教学演示,帮助学生理解函数参数A、ω、φ对函数图像的影响。

因生成图像需使用“chart.js”在线加载较慢,已和html文件打包压缩,文末有下载链接,解压后不能删除该文件。

正弦与余弦函数教学演示.PNG

以下是实现代码( 由 deepseek 依据人工指令生成):

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>正弦与余弦函数教学演示</title>
    <script src="chart.js"></script>
    <style>
        * {
            box-sizing: border-box;
            margin: 0;
            padding: 0;
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
        }
        
        body {
            background: linear-gradient(135deg, #0a1a3a, #1a3a6a, #2a5a9a);
            color: white;
            min-height: 100vh;
            padding: 15px;
            overflow: hidden;
        }
        
        .container {
            max-width: 1400px;
            margin: 0 auto;
            background-color: rgba(10, 25, 50, 0.85);
            border-radius: 15px;
            padding: 20px;
            box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5);
            height: calc(100vh - 30px);
            display: flex;
            flex-direction: column;
        }
        
        header {
            text-align: center;
            margin-bottom: 20px;
            padding-bottom: 10px;
            border-bottom: 2px solid rgba(100, 150, 255, 0.3);
            flex-shrink: 0;
        }
        
        h1 {
            font-size: 2rem;
            margin-bottom: 8px;
            text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.5);
            color: #a8d1ff;
        }
        
        .subtitle {
            font-size: 1rem;
            opacity: 0.9;
            color: #c8e1ff;
        }
        
        .main-content {
            display: flex;
            flex: 1;
            overflow: hidden;
            gap: 20px;
        }
        
        .left-panel {
            flex: 3;
            display: flex;
            flex-direction: column;
            gap: 15px;
        }
        
        .right-panel {
            flex: 2;
            display: flex;
            flex-direction: column;
            gap: 15px;
            max-width: 400px;
        }
        
        .controls-container {
            background: rgba(20, 40, 80, 0.8);
            border-radius: 10px;
            padding: 15px;
            border: 1px solid rgba(100, 150, 255, 0.2);
        }
        
        .function-selector {
            display: flex;
            gap: 10px;
            margin-bottom: 15px;
        }
        
        .function-option {
            flex: 1;
            text-align: center;
            padding: 10px;
            background: rgba(40, 70, 120, 0.8);
            border-radius: 8px;
            cursor: pointer;
            transition: all 0.3s ease;
            border: 1px solid rgba(100, 150, 255, 0.3);
        }
        
        .function-option:hover {
            background: rgba(60, 100, 160, 0.8);
            transform: translateY(-2px);
        }
        
        .function-option.active {
            background: #2a5a9a;
            box-shadow: 0 0 15px rgba(80, 140, 255, 0.5);
            border: 1px solid rgba(120, 180, 255, 0.5);
        }
        
        .function-option input {
            display: none;
        }
        
        .function-option label {
            cursor: pointer;
            display: block;
            margin: 0;
            font-weight: 500;
            font-size: 0.9rem;
        }
        
        .parameters-container {
            display: flex;
            flex-direction: column;
            gap: 15px;
        }
        
        .control-group {
            background: rgba(30, 60, 100, 0.6);
            border-radius: 8px;
            padding: 12px;
            border: 1px solid rgba(100, 150, 255, 0.2);
        }
        
        h2 {
            font-size: 1.2rem;
            margin-bottom: 12px;
            color: #8cc2ff;
            text-align: center;
        }
        
        .parameter {
            margin-bottom: 12px;
        }
        
        label {
            display: block;
            margin-bottom: 6px;
            font-weight: 500;
            color: #c8e1ff;
            font-size: 0.9rem;
        }
        
        input[type="range"] {
            width: 100%;
            height: 8px;
            border-radius: 5px;
            background: #1a3a6a;
            outline: none;
            margin-bottom: 5px;
        }
        
        input[type="range"]::-webkit-slider-thumb {
            appearance: none;
            width: 16px;
            height: 16px;
            border-radius: 50%;
            background: #4a9cff;
            cursor: pointer;
            box-shadow: 0 0 5px rgba(0, 0, 0, 0.5);
        }
        
        .value-display {
            display: flex;
            justify-content: space-between;
            font-size: 0.85rem;
            color: #a8d1ff;
        }
        
        .function-display {
            background: rgba(30, 60, 100, 0.6);
            border-radius: 10px;
            padding: 15px;
            display: flex;
            justify-content: space-around;
            align-items: center;
            gap: 15px;
            border: 1px solid rgba(100, 150, 255, 0.2);
        }
        
        .function-equation {
            font-size: 1.1rem;
            text-align: center;
            font-family: 'Cambria Math', serif;
            padding: 12px;
            background: rgba(40, 80, 140, 0.5);
            border-radius: 8px;
            flex: 1;
            border: 1px solid rgba(100, 150, 255, 0.3);
        }
        
        .sin-equation {
            color: #64b4ff;
        }
        
        .cos-equation {
            color: #ffd166;
        }
        
        .chart-container {
            background: rgba(20, 40, 80, 0.8);
            border-radius: 10px;
            padding: 15px;
            flex: 1;
            overflow: hidden;
            border: 1px solid rgba(100, 150, 255, 0.2);
            position: relative;
        }
        
        canvas {
            width: 100% !important;
            height: 100% !important;
        }
        
        .crosshair {
            position: absolute;
            pointer-events: none;
            z-index: 10;
            display: none;
        }
        
        .crosshair-line {
            position: absolute;
            background-color: rgba(255, 255, 255, 0.7);
        }
        
        .crosshair-x {
            width: 100%;
            height: 1px;
            top: 0;
            left: 0;
        }
        
        .crosshair-y {
            width: 1px;
            height: 100%;
            top: 0;
            left: 0;
        }
        
        .crosshair-label {
            position: absolute;
            background: rgba(0, 0, 0, 0.7);
            color: white;
            padding: 4px 8px;
            border-radius: 4px;
            font-size: 0.8rem;
            white-space: nowrap;
        }
        
        .explanation {
            background: rgba(20, 40, 80, 0.8);
            border-radius: 10px;
            padding: 15px;
            border: 1px solid rgba(100, 150, 255, 0.2);
            flex-shrink: 0;
            max-height: 200px;
            overflow-y: auto;
        }
        
        .explanation h2 {
            color: #8cc2ff;
            text-align: left;
            font-size: 1.2rem;
            margin-bottom: 10px;
        }
        
        .explanation p {
            line-height: 1.5;
            margin-bottom: 10px;
            color: #c8e1ff;
            font-size: 0.9rem;
        }
        
        .parameter-explanation {
            display: flex;
            flex-wrap: wrap;
            gap: 10px;
            margin-top: 10px;
        }
        
        .param-card {
            flex: 1;
            min-width: 120px;
            background: rgba(40, 80, 140, 0.5);
            border-radius: 8px;
            padding: 10px;
            border: 1px solid rgba(100, 150, 255, 0.3);
        }
        
        .param-card h3 {
            color: #8cc2ff;
            margin-bottom: 8px;
            font-size: 0.95rem;
        }
        
        .param-card p {
            color: #c8e1ff;
            font-size: 0.85rem;
        }
        
        @media (max-width: 1024px) {
            .main-content {
                flex-direction: column;
            }
            
            .right-panel {
                max-width: none;
            }
            
            .parameters-container {
                flex-direction: row;
            }
        }
        
        @media (max-width: 768px) {
            .parameters-container {
                flex-direction: column;
            }
            
            .function-selector {
                flex-direction: column;
            }
            
            .function-display {
                flex-direction: column;
            }
            
            .parameter-explanation {
                flex-direction: column;
            }
        }
    </style>
</head>
<body>
    <div>
        <header>
            <h1>正弦与余弦函数教学演示</h1>
            <p>探索函数 y = A·sin(ωx+φ) 和 y = A·cos(ωx+φ) 的参数影响</p>
        </header>
        
        <div>
            <div>
                <div>
                    <div>
                        <div class="function-option active" id="sinOption">
                            <input type="radio" id="showSin" name="functionDisplay" value="sin" checked>
                            <label for="showSin">正弦函数</label>
                        </div>
                        <div id="cosOption">
                            <input type="radio" id="showCos" name="functionDisplay" value="cos">
                            <label for="showCos">余弦函数</label>
                        </div>
                        <div id="bothOption">
                            <input type="radio" id="showBoth" name="functionDisplay" value="both">
                            <label for="showBoth">两者叠加</label>
                        </div>
                    </div>
                    
                    <div>
                        <div class="function-equation sin-equation" id="sinEquation">y = 1·sin(1x + 0)</div>
                        <div class="function-equation cos-equation" id="cosEquation">y = 1·cos(1x + 0)</div>
                    </div>
                </div>
                
                <div id="chartContainer">
                    <canvas id="waveChart"></canvas>
                    <div id="crosshair">
                        <div class="crosshair-line crosshair-x" id="crosshairX"></div>
                        <div class="crosshair-line crosshair-y" id="crosshairY"></div>
                        <div id="crosshairLabel"></div>
                    </div>
                </div>
                
                <div>
                    <h2>参数说明</h2>
                    <p>正弦函数和余弦函数是周期函数的基本形式,广泛应用于物理学、工程学和信号处理等领域。</p>
                    
                    <div>
                        <div>
                            <h3>振幅 (A)</h3>
                            <p>控制函数图像的垂直伸缩。A值越大,波峰和波谷之间的距离越大。</p>
                        </div>
                        
                        <div>
                            <h3>角频率 (ω)</h3>
                            <p>控制函数图像的周期。ω值越大,函数周期越短,波形越密集。</p>
                        </div>
                        
                        <div>
                            <h3>初相位 (φ)</h3>
                            <p>控制函数图像的水平位移。正值向左移动,负值向右移动。</p>
                        </div>
                    </div>
                </div>
            </div>
            
            <div>
                <div>
                    <div>
                        <div>
                            <h2>正弦函数参数</h2>
                            
                            <div>
                                <label for="sinA">振幅 (A):</label>
                                <input type="range" id="sinA" min="0.1" max="3" step="0.1" value="1">
                                <div>
                                    <span>0.1</span>
                                    <span id="sinAValue">1</span>
                                    <span>3</span>
                                </div>
                            </div>
                            
                            <div>
                                <label for="sinOmega">角频率 (ω):</label>
                                <input type="range" id="sinOmega" min="0.5" max="4" step="0.1" value="1">
                                <div>
                                    <span>0.5</span>
                                    <span id="sinOmegaValue">1</span>
                                    <span>4</span>
                                </div>
                            </div>
                            
                            <div>
                                <label for="sinPhi">初相位 (φ):</label>
                                <input type="range" id="sinPhi" min="-3.14" max="3.14" step="0.1" value="0">
                                <div>
                                    <span>-π</span>
                                    <span id="sinPhiValue">0</span>
                                    <span>π</span>
                                </div>
                            </div>
                        </div>
                        
                        <div>
                            <h2>余弦函数参数</h2>
                            
                            <div>
                                <label for="cosA">振幅 (A):</label>
                                <input type="range" id="cosA" min="0.1" max="3" step="0.1" value="1">
                                <div>
                                    <span>0.1</span>
                                    <span id="cosAValue">1</span>
                                    <span>3</span>
                                </div>
                            </div>
                            
                            <div>
                                <label for="cosOmega">角频率 (ω):</label>
                                <input type="range" id="cosOmega" min="0.5" max="4" step="0.1" value="1">
                                <div>
                                    <span>0.5</span>
                                    <span id="cosOmegaValue">1</span>
                                    <span>4</span>
                                </div>
                            </div>
                            
                            <div>
                                <label for="cosPhi">初相位 (φ):</label>
                                <input type="range" id="cosPhi" min="-3.14" max="3.14" step="0.1" value="0">
                                <div>
                                    <span>-π</span>
                                    <span id="cosPhiValue">0</span>
                                    <span>π</span>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>

    <script>
        // 获取DOM元素
        const sinA = document.getElementById('sinA');
        const sinOmega = document.getElementById('sinOmega');
        const sinPhi = document.getElementById('sinPhi');
        const cosA = document.getElementById('cosA');
        const cosOmega = document.getElementById('cosOmega');
        const cosPhi = document.getElementById('cosPhi');
        
        const sinAValue = document.getElementById('sinAValue');
        const sinOmegaValue = document.getElementById('sinOmegaValue');
        const sinPhiValue = document.getElementById('sinPhiValue');
        const cosAValue = document.getElementById('cosAValue');
        const cosOmegaValue = document.getElementById('cosOmegaValue');
        const cosPhiValue = document.getElementById('cosPhiValue');
        
        const sinEquation = document.getElementById('sinEquation');
        const cosEquation = document.getElementById('cosEquation');
        
        // 函数选择器
        const sinOption = document.getElementById('sinOption');
        const cosOption = document.getElementById('cosOption');
        const bothOption = document.getElementById('bothOption');
        const functionDisplayRadios = document.getElementsByName('functionDisplay');
        
        // 十字线元素
        const crosshair = document.getElementById('crosshair');
        const crosshairX = document.getElementById('crosshairX');
        const crosshairY = document.getElementById('crosshairY');
        const crosshairLabel = document.getElementById('crosshairLabel');
        const chartContainer = document.getElementById('chartContainer');
        
        // 初始化图表
        const ctx = document.getElementById('waveChart').getContext('2d');
        const waveChart = new Chart(ctx, {
            type: 'line',
            data: {
                labels: [],
                datasets: [
                    {
                        label: '正弦函数 y = A·sin(ωx+φ)',
                        data: [],
                        borderColor: 'rgb(100, 180, 255)', // 蓝色正弦曲线
                        backgroundColor: 'rgba(100, 180, 255, 0.1)',
                        borderWidth: 1.5,
                        tension: 0.4,
                        fill: false,
                        hidden: false,
                        pointRadius: 0,
                        pointHoverRadius: 3
                    },
                    {
                        label: '余弦函数 y = A·cos(ωx+φ)',
                        data: [],
                        borderColor: 'rgb(255, 209, 102)', // 黄色余弦曲线
                        backgroundColor: 'rgba(255, 209, 102, 0.1)',
                        borderWidth: 1.5,
                        tension: 0.4,
                        fill: false,
                        hidden: false,
                        pointRadius: 0,
                        pointHoverRadius: 3
                    }
                ]
            },
            options: {
                responsive: true,
                maintainAspectRatio: false,
                scales: {
                    x: {
                        type: 'linear',
                        position: 'bottom',
                        title: {
                            display: true,
                            text: 'x',
                            color: '#a8d1ff'
                        },
                        grid: {
                            color: 'rgba(100, 150, 255, 0.1)'
                        },
                        ticks: {
                            color: '#a8d1ff'
                        },
                        min: -Math.PI * 2,
                        max: Math.PI * 2
                    },
                    y: {
                        title: {
                            display: true,
                            text: 'y',
                            color: '#a8d1ff'
                        },
                        min: -3.5,
                        max: 3.5,
                        grid: {
                            color: 'rgba(100, 150, 255, 0.1)'
                        },
                        ticks: {
                            color: '#a8d1ff'
                        }
                    }
                },
                plugins: {
                    legend: {
                        labels: {
                            color: '#a8d1ff',
                            font: {
                                size: 12
                            },
                            // 自定义图例颜色
                            generateLabels: function(chart) {
                                const original = Chart.defaults.plugins.legend.labels.generateLabels;
                                const labelsOriginal = original.call(this, chart);
                                
                                // 设置正弦函数图例颜色
                                labelsOriginal[0].fillStyle = 'rgb(100, 180, 255)';
                                // 设置余弦函数图例颜色
                                labelsOriginal[1].fillStyle = 'rgb(255, 209, 102)';
                                
                                return labelsOriginal;
                            }
                        }
                    },
                    tooltip: {
                        mode: 'index',
                        intersect: false,
                        backgroundColor: 'rgba(10, 30, 60, 0.9)',
                        titleColor: '#a8d1ff',
                        bodyColor: '#c8e1ff',
                        borderColor: 'rgba(100, 150, 255, 0.5)',
                        callbacks: {
                            label: function(context) {
                                // 获取当前x值
                                const x = context.parsed.x;
                                
                                // 获取当前参数值
                                const sA = parseFloat(sinA.value);
                                const sOmega = parseFloat(sinOmega.value);
                                const sPhi = parseFloat(sinPhi.value);
                                const cA = parseFloat(cosA.value);
                                const cOmega = parseFloat(cosOmega.value);
                                const cPhi = parseFloat(cosPhi.value);
                                
                                // 计算函数值
                                const sinY = sA * Math.sin(sOmega * x + sPhi);
                                const cosY = cA * Math.cos(cOmega * x + cPhi);
                                
                                // 根据数据集返回相应信息
                                if (context.datasetIndex === 0) {
                                    return [
                                        `正弦函数: y = ${sA}·sin(${sOmega}·${x.toFixed(2)} + ${sPhi.toFixed(2)})`,
                                        `y = ${sinY.toFixed(4)}`,
                                        `A = ${sA}, ω = ${sOmega}, φ = ${sPhi.toFixed(2)}`
                                    ];
                                } else {
                                    return [
                                        `余弦函数: y = ${cA}·cos(${cOmega}·${x.toFixed(2)} + ${cPhi.toFixed(2)})`,
                                        `y = ${cosY.toFixed(4)}`,
                                        `A = ${cA}, ω = ${cOmega}, φ = ${cPhi.toFixed(2)}`
                                    ];
                                }
                            }
                        }
                    }
                },
                interaction: {
                    mode: 'nearest',
                    axis: 'xy',
                    intersect: false
                }
            }
        });
        
        // 生成数据点
        function generateData() {
            const dataPoints = 200;
            const xValues = [];
            const sinYValues = [];
            const cosYValues = [];
            
            // 获取当前参数值
            const sA = parseFloat(sinA.value);
            const sOmega = parseFloat(sinOmega.value);
            const sPhi = parseFloat(sinPhi.value);
            const cA = parseFloat(cosA.value);
            const cOmega = parseFloat(cosOmega.value);
            const cPhi = parseFloat(cosPhi.value);
            
            // 生成x值
            for (let i = 0; i < dataPoints; i++) {
                const x = -Math.PI * 2 + (i / dataPoints) * Math.PI * 4;
                xValues.push(x);
                
                // 计算正弦函数值
                sinYValues.push(sA * Math.sin(sOmega * x + sPhi));
                
                // 计算余弦函数值
                cosYValues.push(cA * Math.cos(cOmega * x + cPhi));
            }
            
            return { xValues, sinYValues, cosYValues };
        }
        
        // 更新图表
        function updateChart() {
            const { xValues, sinYValues, cosYValues } = generateData();
            
            waveChart.data.labels = xValues;
            waveChart.data.datasets[0].data = sinYValues;
            waveChart.data.datasets[1].data = cosYValues;
            
            // 根据选择显示/隐藏函数
            const selectedFunction = document.querySelector('input[name="functionDisplay"]:checked').value;
            
            if (selectedFunction === 'sin') {
                waveChart.data.datasets[0].hidden = false;
                waveChart.data.datasets[1].hidden = true;
            } else if (selectedFunction === 'cos') {
                waveChart.data.datasets[0].hidden = true;
                waveChart.data.datasets[1].hidden = false;
            } else { // both
                waveChart.data.datasets[0].hidden = false;
                waveChart.data.datasets[1].hidden = false;
            }
            
            waveChart.update();
        }
        
        // 更新参数显示
        function updateParameterDisplay() {
            sinAValue.textContent = sinA.value;
            sinOmegaValue.textContent = sinOmega.value;
            sinPhiValue.textContent = parseFloat(sinPhi.value).toFixed(2);
            cosAValue.textContent = cosA.value;
            cosOmegaValue.textContent = cosOmega.value;
            cosPhiValue.textContent = parseFloat(cosPhi.value).toFixed(2);
            
            // 更新函数表达式
            sinEquation.textContent = `y = ${sinA.value}·sin(${sinOmega.value}x + ${parseFloat(sinPhi.value).toFixed(2)})`;
            cosEquation.textContent = `y = ${cosA.value}·cos(${cosOmega.value}x + ${parseFloat(cosPhi.value).toFixed(2)})`;
        }
        
        // 函数选择器事件处理
        function handleFunctionSelection() {
            // 更新选项样式
            sinOption.classList.toggle('active', functionDisplayRadios[0].checked);
            cosOption.classList.toggle('active', functionDisplayRadios[1].checked);
            bothOption.classList.toggle('active', functionDisplayRadios[2].checked);
            
            updateChart();
        }
        
        // 十字线功能
        function initCrosshair() {
            chartContainer.addEventListener('mousemove', function(e) {
                const rect = chartContainer.getBoundingClientRect();
                const x = e.clientX - rect.left;
                const y = e.clientY - rect.top;
                
                // 更新十字线位置
                crosshairX.style.top = y + 'px';
                crosshairY.style.left = x + 'px';
                
                // 计算对应的坐标值
                const xScale = waveChart.scales.x;
                const yScale = waveChart.scales.y;
                
                if (xScale && yScale) {
                    const xValue = xScale.getValueForPixel(x);
                    const yValue = yScale.getValueForPixel(y);
                    
                    // 更新坐标标签
                    crosshairLabel.textContent = `x: ${xValue.toFixed(2)}, y: ${yValue.toFixed(2)}`;
                    crosshairLabel.style.left = (x + 10) + 'px';
                    crosshairLabel.style.top = (y - 25) + 'px';
                }
            });
            
            chartContainer.addEventListener('mouseenter', function() {
                crosshair.style.display = 'block';
            });
            
            chartContainer.addEventListener('mouseleave', function() {
                crosshair.style.display = 'none';
            });
        }
        
        // 添加事件监听器
        [sinA, sinOmega, sinPhi, cosA, cosOmega, cosPhi].forEach(slider => {
            slider.addEventListener('input', () => {
                updateParameterDisplay();
                updateChart();
            });
        });
        
        // 为函数选择器添加事件监听
        functionDisplayRadios.forEach(radio => {
            radio.addEventListener('change', handleFunctionSelection);
        });
        
        // 初始化
        updateParameterDisplay();
        updateChart();
        handleFunctionSelection();
        
        // 初始化十字线
        setTimeout(initCrosshair, 500); // 延迟初始化确保图表已渲染
    </script>
</body>
</html>

下载  正弦与余弦函数教学演示.zip

打开  正弦与余弦函数教学演示_deepseek.html (因需要chart.js插件,可能加载较慢)

浏览188
返回
目录
返回
首页
课堂随机点名应用 QListWidget 应用笔记