Files
autopilot/examples/page2.html

250 lines
8.7 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Интерактивная система координат с трансформацией</title>
<style>
body {
font-family: Arial, sans-serif;
max-width: 800px;
margin: 50px auto;
padding: 20px;
}
canvas {
border: 1px solid #ccc;
display: block;
margin: 20px auto;
background: #f9f9f9;
}
.controls {
display: grid;
grid-template-columns: 150px 1fr 80px;
gap: 15px;
margin-bottom: 20px;
align-items: center;
}
input[type="range"] {
width: 100%;
}
label {
font-weight: bold;
}
.value {
text-align: center;
font-family: monospace;
}
</style>
</head>
<body>
<h1>Система координат с матрицей трансформации 3×3</h1>
<div class="controls">
<label for="scale">Масштаб:</label>
<input type="range" id="scale" min="0.5" max="3" step="0.1" value="1">
<span class="value" id="scaleValue">1.0</span>
<label for="projX">Проекция X (px):</label>
<input type="range" id="projX" min="-1.0" max="1.0" step="0.01" value="0">
<span class="value" id="projXValue">0.00</span>
<label for="projY">Проекция Y (py):</label>
<input type="range" id="projY" min="-1.0" max="1.0" step="0.01" value="0">
<span class="value" id="projYValue">0.00</span>
<label for="rotation">Поворот:</label>
<input type="range" id="rotation" min="0" max="360" step="1" value="0">
<span class="value" id="rotationValue"></span>
</div>
<canvas id="canvas" width="600" height="600"></canvas>
<script>
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
// Исходные точки квадрата
const originalPoints = [
[-50, -50, 1],
[-25, -50, 1],
[0, -50, 1],
[25, -50, 1],
[50, -50, 1],
[50, 50, 1],
[-50, 50, 1]
];
// Элементы управления
const scaleInput = document.getElementById('scale');
const projXInput = document.getElementById('projX');
const projYInput = document.getElementById('projY');
const rotationInput = document.getElementById('rotation');
// Отображение значений
const scaleValue = document.getElementById('scaleValue');
const projXValue = document.getElementById('projXValue');
const projYValue = document.getElementById('projYValue');
const rotationValue = document.getElementById('rotationValue');
// Умножение матриц 3x3
function multiplyMatrices(a, b) {
const result = [
[0, 0, 0],
[0, 0, 0],
[0, 0, 0]
];
for (let i = 0; i < 3; i++) {
for (let j = 0; j < 3; j++) {
for (let k = 0; k < 3; k++) {
result[i][j] += a[i][k] * b[k][j];
}
}
}
return result;
}
// Применение матрицы к точке
function applyMatrix(matrix, point) {
const x = matrix[0][0] * point[0] + matrix[0][1] * point[1] + matrix[0][2] * point[2];
const y = matrix[1][0] * point[0] + matrix[1][1] * point[1] + matrix[1][2] * point[2];
const w = matrix[2][0] * point[0] + matrix[2][1] * point[1] + matrix[2][2] * point[2];
return [x / w, y / w, 1];
}
// Создание матрицы масштабирования
function getScaleMatrix(s) {
return [
[s, 0, 0],
[0, s, 0],
[0, 0, 1]
];
}
// Создание матрицы поворота
function getRotationMatrix(angle) {
const rad = angle * Math.PI / 180;
const cos = Math.cos(rad);
const sin = Math.sin(rad);
return [
[cos, -sin, 0],
[sin, cos, 0],
[0, 0, 1]
];
}
// Создание матрицы проекции
function getProjectionMatrix(px, py) {
return [
[1, 0, 0],
[0, 1, 0],
[px, py, 1]
];
}
// Рисование сетки координат
function drawGrid() {
ctx.strokeStyle = '#ddd';
ctx.lineWidth = 1;
// Вертикальные линии
for (let x = 0; x <= canvas.width; x += 50) {
ctx.beginPath();
ctx.moveTo(x, 0);
ctx.lineTo(x, canvas.height);
ctx.stroke();
}
// Горизонтальные линии
for (let y = 0; y <= canvas.height; y += 50) {
ctx.beginPath();
ctx.moveTo(0, y);
ctx.lineTo(canvas.width, y);
ctx.stroke();
}
// Оси координат
ctx.strokeStyle = '#999';
ctx.lineWidth = 2;
ctx.beginPath();
ctx.moveTo(canvas.width / 2, 0);
ctx.lineTo(canvas.width / 2, canvas.height);
ctx.moveTo(0, canvas.height / 2);
ctx.lineTo(canvas.width, canvas.height / 2);
ctx.stroke();
}
// Рисование четырехугольника
function drawQuadrilateral(points) {
const centerX = canvas.width / 2;
const centerY = canvas.height / 2;
// Рисуем четырехугольник
ctx.fillStyle = 'rgba(66, 153, 225, 0.3)';
ctx.strokeStyle = '#2c5aa0';
ctx.lineWidth = 2;
ctx.beginPath();
ctx.moveTo(centerX + points[0][0], centerY - points[0][1]);
for (let i = 1; i < points.length; i++) {
ctx.lineTo(centerX + points[i][0], centerY - points[i][1]);
}
ctx.closePath();
ctx.fill();
ctx.stroke();
// Рисуем точки
ctx.fillStyle = '#e53e3e';
points.forEach(point => {
ctx.beginPath();
ctx.arc(centerX + point[0], centerY - point[1], 5, 0, Math.PI * 2);
ctx.fill();
});
}
// Обновление сцены
function update() {
const scale = parseFloat(scaleInput.value);
const projX = parseFloat(projXInput.value) / 50;
const projY = parseFloat(projYInput.value) / 50;
const rotation = parseFloat(rotationInput.value);
// Обновление отображаемых значений
scaleValue.textContent = scale.toFixed(1);
projXValue.textContent = projX.toFixed(2);
projYValue.textContent = projY.toFixed(2);
rotationValue.textContent = rotation + '°';
// Создание матриц трансформации
const scaleMatrix = getScaleMatrix(scale);
const rotationMatrix = getRotationMatrix(rotation);
const projectionMatrix = getProjectionMatrix(projX, projY);
// Комбинированная матрица: проекция * поворот * масштаб
let transformMatrix = multiplyMatrices(scaleMatrix, rotationMatrix);
transformMatrix = multiplyMatrices(transformMatrix, projectionMatrix);
// Применение трансформации к точкам
const transformedPoints = originalPoints.map(point =>
applyMatrix(transformMatrix, point)
);
// Отрисовка
ctx.clearRect(0, 0, canvas.width, canvas.height);
drawGrid();
drawQuadrilateral(transformedPoints);
}
// Обработчики событий
scaleInput.addEventListener('input', update);
projXInput.addEventListener('input', update);
projYInput.addEventListener('input', update);
rotationInput.addEventListener('input', update);
// Начальная отрисовка
update();
</script>
</body>
</html>