SOURCE

console 命令行工具 X clear

                    
>
console
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>平行线判定定理证明</title>
    <style>
        body {
            font-family: 'Microsoft YaHei', sans-serif;
            max-width: 900px;
            margin: 0 auto;
            padding: 20px;
            background-color: #f5f5f5;
            color: #333;
        }
        h1 {
            color: #2c3e50;
            text-align: center;
            border-bottom: 2px solid #3498db;
            padding-bottom: 10px;
        }
        h2 {
            color: #2980b9;
            margin-top: 30px;
        }
        .theorem {
            background-color: #e8f4fc;
            padding: 15px;
            border-left: 5px solid #3498db;
            margin: 20px 0;
            border-radius: 0 5px 5px 0;
        }
        .proof {
            background-color: #f9f9f9;
            padding: 15px;
            border: 1px solid #ddd;
            border-radius: 5px;
            margin: 15px 0;
        }
        .interactive {
            background-color: #fff;
            padding: 20px;
            border-radius: 8px;
            box-shadow: 0 2px 10px rgba(0,0,0,0.1);
            margin: 25px 0;
            text-align: center;
        }
        canvas {
            background-color: #fff;
            border: 1px solid #ddd;
            margin: 10px auto;
            display: block;
        }
        .controls {
            margin: 15px 0;
        }
        button {
            background-color: #3498db;
            color: white;
            border: none;
            padding: 8px 15px;
            margin: 0 5px;
            border-radius: 4px;
            cursor: pointer;
            transition: background-color 0.3s;
        }
        button:hover {
            background-color: #2980b9;
        }
        .note {
            font-style: italic;
            color: #7f8c8d;
        }
        .conclusion {
            font-weight: bold;
            color: #27ae60;
        }
    </style>
</head>
<body>
    <h1>平行线判定定理可视化证明</h1>
    
    <div class="theorem">
        <h2>平行线的判定定理</h2>
        <p>1. <strong>同位角相等,两直线平行</strong></p>
        <p>2. <strong>内错角相等,两直线平行</strong></p>
        <p>3. <strong>同旁内角互补,两直线平行</strong></p>
    </div>

    <div class="interactive">
        <h3>交互式演示 - 拖动点改变角度</h3>
        <canvas id="parallelCanvas" width="600" height="300"></canvas>
        <div class="controls">
            <button onclick="showCorresponding()">同位角演示</button>
            <button onclick="showAlternate()">内错角演示</button>
            <button onclick="showConsecutive()">同旁内角演示</button>
            <button onclick="reset()">重置</button>
        </div>
        <p class="note">拖动红色点改变角度,观察平行线条件</p>
    </div>

    <div class="proof">
        <h2>1. 同位角相等,两直线平行</h2>
        <p><strong>已知</strong>:直线l₁和l₂被直线m所截,同位角∠1 = ∠2</p>
        <p><strong>证明</strong>:l₁ ∥ l₂</p>
        <p>假设l₁不平行于l₂,则两直线必相交于某点P,形成三角形。</p>
        <p>根据三角形外角定理,∠2 = ∠1 + ∠P(外角等于不相邻内角之和)</p>
        <p>但已知∠1 = ∠2,代入得∠1 = ∠1 + ∠P ⇒ ∠P = 0°</p>
        <p>这意味着两直线不相交,即l₁ ∥ l₂。</p>
        <p class="conclusion">∴ 同位角相等时,两直线平行。</p>
    </div>

    <div class="proof">
        <h2>2. 内错角相等,两直线平行</h2>
        <p><strong>已知</strong>:直线l₁和l₂被直线m所截,内错角∠3 = ∠4</p>
        <p><strong>证明</strong>:l₁ ∥ l₂</p>
        <p>∵ ∠1 = ∠3(对顶角相等),且∠3 = ∠4(已知)</p>
        <p>∴ ∠1 = ∠4</p>
        <p>但∠1和∠4是同位角,根据定理1:同位角相等⇒两直线平行</p>
        <p class="conclusion">∴ 内错角相等时,两直线平行。</p>
    </div>

    <div class="proof">
        <h2>3. 同旁内角互补,两直线平行</h2>
        <p><strong>已知</strong>:直线l₁和l₂被直线m所截,同旁内角∠5 + ∠6 = 180°</p>
        <p><strong>证明</strong>:l₁ ∥ l₂</p>
        <p>∵ ∠5 + ∠6 = 180°,且∠6 + ∠7 = 180°(邻补角定义)</p>
        <p>∴ ∠5 = ∠7</p>
        <p>但∠5和∠7是同位角,根据定理1:同位角相等⇒两直线平行</p>
        <p class="conclusion">∴ 同旁内角互补时,两直线平行。</p>
    </div>

    <script>
        const canvas = document.getElementById('parallelCanvas');
        const ctx = canvas.getContext('2d');
        let angle = 60;
        let mode = 'corresponding';
        let isDragging = false;
        let dragPoint = { x: 300, y: 150 };

        function draw() {
            ctx.clearRect(0, 0, canvas.width, canvas.height);
            
            // 绘制两条平行线
            ctx.beginPath();
            ctx.moveTo(100, 100);
            ctx.lineTo(500, 100);
            ctx.moveTo(100, 200);
            ctx.lineTo(500, 200);
            ctx.strokeStyle = '#3498db';
            ctx.lineWidth = 2;
            ctx.stroke();

            // 绘制截线
            ctx.beginPath();
            ctx.moveTo(150, 50);
            ctx.lineTo(450, 250);
            ctx.strokeStyle = '#e74c3c';
            ctx.lineWidth = 2;
            ctx.stroke();

            // 计算角度点
            if (mode === 'corresponding') {
                dragPoint = {
                    x: 300 + Math.cos((angle-90) * Math.PI / 180) * 50,
                    y: 150 + Math.sin((angle-90) * Math.PI / 180) * 50
                };
            } else {
                dragPoint = {
                    x: 300 + Math.cos((angle) * Math.PI / 180) * 50,
                    y: 150 + Math.sin((angle) * Math.PI / 180) * 50
                };
            }

            // 绘制角度标记
            drawAngle(300, 150, angle);
            
            // 绘制拖拽点
            ctx.beginPath();
            ctx.arc(dragPoint.x, dragPoint.y, 8, 0, Math.PI * 2);
            ctx.fillStyle = 'red';
            ctx.fill();
        }

        function drawAngle(x, y, angle) {
            const radius = 30;
            
            // 绘制角度弧线
            ctx.beginPath();
            ctx.arc(x, y, radius, 0, angle * Math.PI / 180);
            ctx.strokeStyle = '#2ecc71';
            ctx.lineWidth = 2;
            ctx.stroke();
            
            // 绘制角度文本
            ctx.font = '16px Arial';
            ctx.fillStyle = '#2ecc71';
            ctx.fillText(angle + '°', x + radius + 5, y + 5);
            
            // 根据模式绘制不同角度标记
            if (mode === 'corresponding') {
                // 同位角
                drawCorrespondingAngles(x, y, angle);
            } else if (mode === 'alternate') {
                // 内错角
                drawAlternateAngles(x, y, angle);
            } else {
                // 同旁内角
                drawConsecutiveAngles(x, y, angle);
            }
        }

        function drawCorrespondingAngles(x, y, angle) {
            ctx.strokeStyle = '#9b59b6';
            ctx.lineWidth = 1;
            
            // 第一个同位角
            ctx.beginPath();
            ctx.moveTo(x, y);
            ctx.lineTo(x + 40, y);
            ctx.lineTo(x + 40, y - 40);
            ctx.stroke();
            
            // 第二个同位角
            ctx.beginPath();
            ctx.moveTo(x, y);
            ctx.lineTo(x + 40, y + 100);
            ctx.lineTo(x + 40 + 40 * Math.cos(angle * Math.PI / 180), 
                       y + 100 + 40 * Math.sin(angle * Math.PI / 180));
            ctx.stroke();
            
            // 标记角度
            ctx.font = '14px Arial';
            ctx.fillStyle = '#9b59b6';
            ctx.fillText('∠1', x + 20, y - 10);
            ctx.fillText('∠2', x + 60, y + 80);
        }

        function drawAlternateAngles(x, y, angle) {
            ctx.strokeStyle = '#e67e22';
            ctx.lineWidth = 1;
            
            // 内错角1
            ctx.beginPath();
            ctx.moveTo(x, y);
            ctx.lineTo(x + 40, y);
            ctx.lineTo(x + 40, y - 40);
            ctx.stroke();
            
            // 内错角2
            ctx.beginPath();
            ctx.moveTo(x, y);
            ctx.lineTo(x - 40 * Math.cos(angle * Math.PI / 180), 
                       y + 100 - 40 * Math.sin(angle * Math.PI / 180));
            ctx.lineTo(x - 40 * Math.cos(angle * Math.PI / 180) - 40, 
                       y + 100 - 40 * Math.sin(angle * Math.PI / 180));
            ctx.stroke();
            
            // 标记角度
            ctx.font = '14px Arial';
            ctx.fillStyle = '#e67e22';
            ctx.fillText('∠3', x + 20, y - 10);
            ctx.fillText('∠4', x - 50, y + 80);
        }

        function drawConsecutiveAngles(x, y, angle) {
            ctx.strokeStyle = '#1abc9c';
            ctx.lineWidth = 1;
            
            // 同旁内角1
            ctx.beginPath();
            ctx.moveTo(x, y);
            ctx.lineTo(x + 40, y);
            ctx.lineTo(x + 40, y - 40);
            ctx.stroke();
            
            // 同旁内角2
            ctx.beginPath();
            ctx.moveTo(x, y);
            ctx.lineTo(x - 40 * Math.cos(angle * Math.PI / 180), 
                       y + 100 - 40 * Math.sin(angle * Math.PI / 180));
            ctx.lineTo(x - 40 * Math.cos(angle * Math.PI / 180), 
                       y + 100 - 40 * Math.sin(angle * Math.PI / 180) - 40);
            ctx.stroke();
            
            // 标记角度
            ctx.font = '14px Arial';
            ctx.fillStyle = '#1abc9c';
            ctx.fillText('∠5', x + 20, y - 10);
            ctx.fillText('∠6', x - 30, y + 60);
            ctx.fillText('∠5 + ∠6 = ' + angle + '°', x + 100, y + 120);
        }

        function showCorresponding() {
            mode = 'corresponding';
            angle = 60;
            draw();
        }

        function showAlternate() {
            mode = 'alternate';
            angle = 60;
            draw();
        }

        function showConsecutive() {
            mode = 'consecutive';
            angle = 120;
            draw();
        }

        function reset() {
            angle = 60;
            draw();
        }

        // 鼠标交互
        canvas.addEventListener('mousedown', (e) => {
            const rect = canvas.getBoundingClientRect();
            const mouseX = e.clientX - rect.left;
            const mouseY = e.clientY - rect.top;
            
            if (Math.sqrt((mouseX - dragPoint.x) ** 2 + (mouseY - dragPoint.y) ** 2) < 15) {
                isDragging = true;
            }
        });

        canvas.addEventListener('mousemove', (e) => {
            if (isDragging) {
                const rect = canvas.getBoundingClientRect();
                const mouseX = e.clientX - rect.left;
                const mouseY = e.clientY - rect.top;
                
                const dx = mouseX - 300;
                const dy = mouseY - 150;
                angle = Math.atan2(dy, dx) * 180 / Math.PI;
                
                if (mode === 'corresponding') {
                    angle += 90;
                }
                
                angle = Math.max(10, Math.min(170, angle));
                draw();
            }
        });

        canvas.addEventListener('mouseup', () => {
            isDragging = false;
        });

        canvas.addEventListener('mouseleave', () => {
            isDragging = false;
        });

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