船锚安装位置技术原理图解
船首锚张力(平稳)
船尾锚张力(偏荡)
锚爪极限抓力线
走锚风险区
<script1>
(function() {
// ============ 工具函数 ============
function drawArrow(ctx, fromX, fromY, toX, toY, color, lineWidth = 2.2, headSize = 8) {
const angle = Math.atan2(toY - fromY, toX - fromX);
ctx.save();
ctx.strokeStyle = color;
ctx.fillStyle = color;
ctx.lineWidth = lineWidth;
ctx.lineCap = 'round';
ctx.lineJoin = 'round';
ctx.beginPath();
ctx.moveTo(fromX, fromY);
ctx.lineTo(toX, toY);
ctx.stroke();
// 箭头
ctx.beginPath();
ctx.moveTo(toX, toY);
ctx.lineTo(
toX - headSize * Math.cos(angle - Math.PI / 6),
toY - headSize * Math.sin(angle - Math.PI / 6)
);
ctx.lineTo(
toX - headSize * Math.cos(angle + Math.PI / 6),
toY - headSize * Math.sin(angle + Math.PI / 6)
);
ctx.closePath();
ctx.fill();
ctx.restore();
}
function drawDashedLine(ctx, x1, y1, x2, y2, color, dash = [6, 4], width = 1.5) {
ctx.save();
ctx.strokeStyle = color;
ctx.lineWidth = width;
ctx.setLineDash(dash);
ctx.beginPath();
ctx.moveTo(x1, y1);
ctx.lineTo(x2, y2);
ctx.stroke();
ctx.setLineDash([]);
ctx.restore();
}
// ============ 图1:最小阻力方向与偏荡机制 ============
function drawCanvas1() {
const canvas = document.getElementById('canvas1');
if (!canvas) return;
const ctx = canvas.getContext('2d');
const W = canvas.width;
const H = canvas.height;
ctx.clearRect(0, 0, W, H);
// 背景水线
ctx.fillStyle = '#e8f0fe';
ctx.fillRect(0, H * 0.72, W, H * 0.28);
ctx.fillStyle = '#dbeafe';
ctx.fillRect(0, H * 0.72, W, 2);
// --- 左侧:船首锚(正确)---
const cxL = 190;
const cyL = 180;
// 船体
ctx.save();
ctx.fillStyle = '#374151';
ctx.beginPath();
ctx.moveTo(cxL - 100, cyL);
ctx.quadraticCurveTo(cxL - 40, cyL - 28, cxL + 30, cyL - 18);
ctx.quadraticCurveTo(cxL + 80, cyL - 6, cxL + 110, cyL + 8);
ctx.quadraticCurveTo(cxL + 80, cyL + 18, cxL + 30, cyL + 14);
ctx.quadraticCurveTo(cxL - 40, cyL + 22, cxL - 100, cyL);
ctx.fill();
ctx.strokeStyle = '#1f2937';
ctx.lineWidth = 2;
ctx.stroke();
ctx.restore();
// 上层建筑
ctx.fillStyle = '#6b7280';
ctx.fillRect(cxL + 20, cyL - 40, 50, 28);
// 锚链及锚
ctx.strokeStyle = '#10b981';
ctx.lineWidth = 3;
ctx.setLineDash([5, 3]);
ctx.beginPath();
ctx.moveTo(cxL - 90, cyL - 6);
ctx.lineTo(cxL - 130, cyL + 20);
ctx.stroke();
ctx.setLineDash([]);
// 锚
ctx.fillStyle = '#10b981';
ctx.beginPath();
ctx.arc(cxL - 132, cyL + 26, 7, 0, Math.PI * 2);
ctx.fill();
ctx.fillStyle = '#047857';
ctx.beginPath();
ctx.arc(cxL - 132, cyL + 26, 3, 0, Math.PI * 2);
ctx.fill();
// 风向箭头
drawArrow(ctx, cxL - 180, cyL - 10, cxL - 120, cyL - 10, '#2563eb', 2.5, 10);
ctx.fillStyle = '#2563eb';
ctx.font = 'bold 13px "PingFang SC","Microsoft YaHei",sans-serif';
ctx.fillText('风流方向', cxL - 178, cyL - 22);
// 标签
ctx.fillStyle = '#10b981';
ctx.font = 'bold 13px "PingFang SC","Microsoft YaHei",sans-serif';
ctx.fillText('锚链拉力与风向共线', cxL - 70, cyL - 58);
ctx.fillStyle = '#1a3c5e';
ctx.font = 'bold 15px "PingFang SC","Microsoft YaHei",sans-serif';
ctx.fillText('船首锚 · 稳定平衡', cxL - 60, H - 20);
// --- 右侧:船尾锚(错误)---
const cxR = 560;
const cyR = 180;
// 船体(带偏转角)
ctx.save();
ctx.translate(cxR, cyR);
ctx.rotate(0.22); // 偏转
ctx.fillStyle = '#991b1b';
ctx.beginPath();
ctx.moveTo(-100, 0);
ctx.quadraticCurveTo(-40, -28, 30, -18);
ctx.quadraticCurveTo(80, -6, 110, 8);
ctx.quadraticCurveTo(80, 18, 30, 14);
ctx.quadraticCurveTo(-40, 22, -100, 0);
ctx.fill();
ctx.strokeStyle = '#7f1d1d';
ctx.lineWidth = 2;
ctx.stroke();
// 上层建筑
ctx.fillStyle = '#b91c1c';
ctx.fillRect(20, -40, 50, 28);
ctx.restore();
// 锚在船尾
const anchorX = cxR + 105;
const anchorY = cyR + 30;
ctx.strokeStyle = '#ef4444';
ctx.lineWidth = 3;
ctx.setLineDash([5, 3]);
ctx.beginPath();
ctx.moveTo(cxR + 95, cyR + 10);
ctx.lineTo(anchorX, anchorY);
ctx.stroke();
ctx.setLineDash([]);
ctx.fillStyle = '#ef4444';
ctx.beginPath();
ctx.arc(anchorX, anchorY, 7, 0, Math.PI * 2);
ctx.fill();
// 风向箭头(从后方来)
drawArrow(ctx, cxR + 150, cyR - 20, cxR + 105, cyR - 8, '#2563eb', 2.5, 10);
ctx.fillStyle = '#2563eb';
ctx.fillText('风流方向', cxR + 108, cyR - 42);
// 偏荡弧线
ctx.strokeStyle = '#f59e0b';
ctx.lineWidth = 2;
ctx.setLineDash([4, 5]);
ctx.beginPath();
ctx.arc(cxR + 60, cyR - 40, 150, -0.6, 0.9);
ctx.stroke();
ctx.setLineDash([]);
drawArrow(ctx, cxR + 90, cyR - 110, cxR + 60, cyR - 90, '#ef4444', 2, 7);
ctx.fillStyle = '#ef4444';
ctx.fillText('偏荡方向', cxR + 60, cyR - 120);
ctx.fillStyle = '#ef4444';
ctx.font = 'bold 13px "PingFang SC","Microsoft YaHei",sans-serif';
ctx.fillText('偏荡导致锚链横向冲击', cxR + 10, cyR - 80);
ctx.fillStyle = '#1a3c5e';
ctx.font = 'bold 15px "PingFang SC","Microsoft YaHei",sans-serif';
ctx.fillText('船尾锚 · 偏荡失稳 → 走锚', cxR - 50, H - 20);
// 分隔线
ctx.strokeStyle = '#cbd5e1';
ctx.lineWidth = 1;
ctx.setLineDash([8, 6]);
ctx.beginPath();
ctx.moveTo(W / 2, 30);
ctx.lineTo(W / 2, H - 35);
ctx.stroke();
ctx.setLineDash([]);
}
// ============ 图2:紧急制动动力学 ============
function drawCanvas2() {
const canvas = document.getElementById('canvas2');
if (!canvas) return;
const ctx = canvas.getContext('2d');
const W = canvas.width;
const H = canvas.height;
ctx.clearRect(0, 0, W, H);
ctx.fillStyle = '#e8f0fe';
ctx.fillRect(0, H * 0.7, W, H * 0.3);
ctx.fillStyle = '#dbeafe';
ctx.fillRect(0, H * 0.7, W, 2);
// --- 左侧:船首抛锚制动 ---
const cxL = 180;
const cyL = 170;
// 船体
ctx.fillStyle = '#374151';
ctx.beginPath();
ctx.moveTo(cxL - 100, cyL);
ctx.quadraticCurveTo(cxL - 40, cyL - 26, cxL + 30, cyL - 16);
ctx.quadraticCurveTo(cxL + 80, cyL - 4, cxL + 110, cyL + 10);
ctx.quadraticCurveTo(cxL + 80, cyL + 20, cxL + 30, cyL + 16);
ctx.quadraticCurveTo(cxL - 40, cyL + 24, cxL - 100, cyL);
ctx.fill();
ctx.strokeStyle = '#1f2937';
ctx.lineWidth = 2;
ctx.stroke();
// 前进箭头
drawArrow(ctx, cxL + 60, cyL - 55, cxL + 130, cyL - 55, '#2563eb', 2.5, 10);
ctx.fillStyle = '#2563eb';
ctx.font = 'bold 13px "PingFang SC","Microsoft YaHei",sans-serif';
ctx.fillText('前进惯性', cxL + 52, cyL - 70);
// 锚链
ctx.strokeStyle = '#8b5cf6';
ctx.lineWidth = 3;
ctx.setLineDash([5, 3]);
ctx.beginPath();
ctx.moveTo(cxL - 90, cyL - 4);
ctx.lineTo(cxL - 135, cyL + 28);
ctx.stroke();
ctx.setLineDash([]);
ctx.fillStyle = '#8b5cf6';
ctx.beginPath();
ctx.arc(cxL - 138, cyL + 33, 8, 0, Math.PI * 2);
ctx.fill();
ctx.fillText('锚点抓力', cxL - 145, cyL + 56);
// 力矩标注
ctx.fillStyle = '#10b981';
ctx.font = 'bold 13px "PingFang SC","Microsoft YaHei",sans-serif';
ctx.fillText('力矩平衡,船体顺直减速', cxL - 70, cyL - 60);
ctx.fillStyle = '#1a3c5e';
ctx.font = 'bold 15px "PingFang SC","Microsoft YaHei",sans-serif';
ctx.fillText('船首抛锚 · 可控制动', cxL - 50, H - 18);
// --- 右侧:船尾抛锚制动 ---
const cxR = 550;
const cyR = 170;
// 船体(已甩头横转)
ctx.save();
ctx.translate(cxR, cyR);
ctx.rotate(0.65);
ctx.fillStyle = '#991b1b';
ctx.beginPath();
ctx.moveTo(-100, 0);
ctx.quadraticCurveTo(-40, -26, 30, -16);
ctx.quadraticCurveTo(80, -4, 110, 10);
ctx.quadraticCurveTo(80, 20, 30, 16);
ctx.quadraticCurveTo(-40, 24, -100, 0);
ctx.fill();
ctx.strokeStyle = '#7f1d1d';
ctx.lineWidth = 2;
ctx.stroke();
ctx.restore();
// 锚在船尾
const ax = cxR + 60;
const ay = cyR + 60;
ctx.strokeStyle = '#8b5cf6';
ctx.lineWidth = 3;
ctx.setLineDash([5, 3]);
ctx.beginPath();
ctx.moveTo(cxR + 48, cyR + 30);
ctx.lineTo(ax, ay);
ctx.stroke();
ctx.setLineDash([]);
ctx.fillStyle = '#8b5cf6';
ctx.beginPath();
ctx.arc(ax, ay, 8, 0, Math.PI * 2);
ctx.fill();
// 旋转力矩弧线
ctx.strokeStyle = '#ef4444';
ctx.lineWidth = 2.8;
ctx.setLineDash([6, 4]);
ctx.beginPath();
ctx.arc(cxR, cyR - 20, 100, -0.3, 1.1);
ctx.stroke();
ctx.setLineDash([]);
drawArrow(ctx, cxR + 75, cyR - 55, cxR + 45, cyR - 35, '#ef4444', 2.5, 8);
ctx.fillStyle = '#ef4444';
ctx.font = 'bold 13px "PingFang SC","Microsoft YaHei",sans-serif';
ctx.fillText('巨大旋转力矩', cxR + 15, cyR - 80);
// 倾覆标记
ctx.fillStyle = '#f59e0b';
ctx.font = 'bold 14px "PingFang SC","Microsoft YaHei",sans-serif';
ctx.fillText('⚠ 剧烈侧倾/倾覆风险', cxR - 50, cyR - 100);
// 前进箭头
drawArrow(ctx, cxR + 20, cyR - 90, cxR - 40, cyR - 60, '#2563eb', 2, 8);
ctx.fillText('原前进方向', cxR - 20, cyR - 110);
ctx.fillStyle = '#1a3c5e';
ctx.font = 'bold 15px "PingFang SC","Microsoft YaHei",sans-serif';
ctx.fillText('船尾抛锚 · 失控甩头', cxR - 50, H - 18);
// 分隔
ctx.strokeStyle = '#cbd5e1';
ctx.lineWidth = 1;
ctx.setLineDash([8, 6]);
ctx.beginPath();
ctx.moveTo(W / 2, 25);
ctx.lineTo(W / 2, H - 30);
ctx.stroke();
ctx.setLineDash([]);
}
// ============ 图3:结构强度与推进器安全 ============
function drawCanvas3() {
const canvas = document.getElementById('canvas3');
if (!canvas) return;
const ctx = canvas.getContext('2d');
const W = canvas.width;
const H = canvas.height;
ctx.clearRect(0, 0, W, H);
// --- 左侧:船首结构 ---
ctx.fillStyle = '#1a3c5e';
ctx.fillRect(40, 60, 320, H - 120);
ctx.fillStyle = '#e8f0fe';
ctx.fillRect(45, 65, 310, H - 130);
// 船首轮廓
ctx.fillStyle = '#374151';
ctx.beginPath();
ctx.moveTo(100, 200);
ctx.quadraticCurveTo(60, 150, 80, 90);
ctx.lineTo(180, 90);
ctx.lineTo(220, 200);
ctx.closePath();
ctx.fill();
ctx.strokeStyle = '#1f2937';
ctx.lineWidth = 2.5;
ctx.stroke();
// 首柱高亮
ctx.strokeStyle = '#f59e0b';
ctx.lineWidth = 6;
ctx.beginPath();
ctx.moveTo(100, 200);
ctx.quadraticCurveTo(60, 150, 80, 90);
ctx.stroke();
ctx.fillStyle = '#f59e0b';
ctx.font = 'bold 13px "PingFang SC","Microsoft YaHei",sans-serif';
ctx.fillText('首柱(高强度)', 28, 130);
// 锚链连接点
ctx.fillStyle = '#ef4444';
ctx.beginPath();
ctx.arc(95, 160, 7, 0, Math.PI * 2);
ctx.fill();
ctx.fillStyle = '#ef4444';
ctx.font = 'bold 12px "PingFang SC","Microsoft YaHei",sans-serif';
ctx.fillText('锚链拉力', 30, 180);
drawArrow(ctx, 30, 170, 85, 158, '#ef4444', 2, 7);
// 力分散箭头
drawArrow(ctx, 95, 150, 120, 110, '#f59e0b', 2, 6);
drawArrow(ctx, 95, 150, 80, 110, '#f59e0b', 2, 6);
drawArrow(ctx, 95, 150, 100, 190, '#f59e0b', 2, 6);
ctx.fillStyle = '#1a3c5e';
ctx.font = 'bold 14px "PingFang SC","Microsoft YaHei",sans-serif';
ctx.fillText('船首:集中载荷可安全分散至全船骨架', 50, H - 30);
// --- 右侧:船尾结构 ---
ctx.fillStyle = '#7f1d1d';
ctx.fillRect(400, 60, 320, H - 120);
ctx.fillStyle = '#fef2f2';
ctx.fillRect(405, 65, 310, H - 130);
// 船尾轮廓
ctx.fillStyle = '#991b1b';
ctx.beginPath();
ctx.moveTo(540, 200);
ctx.quadraticCurveTo(580, 150, 620, 90);
ctx.lineTo(680, 90);
ctx.quadraticCurveTo(690, 150, 700, 200);
ctx.closePath();
ctx.fill();
ctx.strokeStyle = '#7f1d1d';
ctx.lineWidth = 2.5;
ctx.stroke();
// 螺旋桨位置
ctx.fillStyle = '#b91c1c';
ctx.beginPath();
ctx.arc(640, 185, 22, 0, Math.PI * 2);
ctx.fill();
ctx.fillStyle = '#ef4444';
ctx.font = 'bold 12px "PingFang SC","Microsoft YaHei",sans-serif';
ctx.fillText('螺旋桨', 610, 220);
// 舵
ctx.fillStyle = '#7f1d1d';
ctx.fillRect(655, 160, 8, 40);
ctx.fillText('舵', 668, 185);
// 开口标记
ctx.strokeStyle = '#ef4444';
ctx.lineWidth = 2;
ctx.setLineDash([4, 4]);
ctx.beginPath();
ctx.arc(640, 185, 30, 0, Math.PI * 2);
ctx.stroke();
ctx.setLineDash([]);
ctx.fillStyle = '#ef4444';
ctx.font = 'bold 13px "PingFang SC","Microsoft YaHei",sans-serif';
ctx.fillText('结构开口多,无法承受集中拉力', 440, 120);
// 禁止锚链标记
ctx.fillStyle = '#ef4444';
ctx.font = 'bold 14px "PingFang SC","Microsoft YaHei",sans-serif';
ctx.fillText('✕ 锚链禁止靠近', 450, 150);
ctx.fillStyle = '#1a3c5e';
ctx.font = 'bold 14px "PingFang SC","Microsoft YaHei",sans-serif';
ctx.fillText('船尾:推进器与舵机区域,严禁锚链进入', 430, H - 30);
}
// ============ 图4:偏荡运动曲线与走锚临界 ============
function drawCanvas4() {
const canvas = document.getElementById('canvas4');
if (!canvas) return;
const ctx = canvas.getContext('2d');
const W = canvas.width;
const H = canvas.height;
ctx.clearRect(0, 0, W, H);
// 坐标轴
const ox = 90;
const oy = 310;
const axisW = 600;
const axisH = 240;
ctx.strokeStyle = '#334155';
ctx.lineWidth = 2;
ctx.beginPath();
ctx.moveTo(ox, oy - axisH);
ctx.lineTo(ox, oy);
ctx.lineTo(ox + axisW, oy);
ctx.stroke();
// 轴标签
ctx.fillStyle = '#334155';
ctx.font = 'bold 13px "PingFang SC","Microsoft YaHei",sans-serif';
ctx.fillText('锚链张力 (kN)', ox - 70, oy - axisH + 20);
ctx.fillText('时间 (s)', ox + axisW - 40, oy + 25);
// 极限抓力线
const limitY = oy - 165;
ctx.strokeStyle = '#333';
ctx.lineWidth = 2.5;
ctx.setLineDash([10, 5]);
ctx.beginPath();
ctx.moveTo(ox, limitY);
ctx.lineTo(ox + axisW - 20, limitY);
ctx.stroke();
ctx.setLineDash([]);
ctx.fillStyle = '#333';
ctx.font = 'bold 13px "PingFang SC","Microsoft YaHei",sans-serif';
ctx.fillText('锚爪极限抓力', ox + axisW - 180, limitY - 8);
// 走锚风险区
ctx.fillStyle = 'rgba(245,158,11,0.12)';
ctx.fillRect(ox, limitY - 40, axisW - 20, 40);
ctx.fillStyle = '#f59e0b';
ctx.font = 'bold 12px "PingFang SC","Microsoft YaHei",sans-serif';
ctx.fillText('走锚风险区', ox + 20, limitY - 48);
// 船首锚曲线(平稳)
ctx.strokeStyle = '#0891b2';
ctx.lineWidth = 3;
ctx.beginPath();
const baseY = oy - 110;
for (let x = 0; x <= axisW - 20; x += 2) {
const y = baseY + Math.sin(x * 0.015) * 6 + Math.sin(x * 0.04) * 3;
if (x === 0) ctx.moveTo(ox + x, y);
else ctx.lineTo(ox + x, y);
}
ctx.stroke();
ctx.fillStyle = '#0891b2';
ctx.font = 'bold 13px "PingFang SC","Microsoft YaHei",sans-serif';
ctx.fillText('船首锚张力(低幅平稳)', ox + 30, baseY - 18);
// 船尾锚曲线(剧烈偏荡)
ctx.strokeStyle = '#ef4444';
ctx.lineWidth = 2.8;
ctx.beginPath();
const baseY2 = oy - 130;
for (let x = 0; x <= axisW - 20; x += 2) {
const amp = 40 + Math.sin(x * 0.02) * 18;
const y = baseY2 + Math.sin(x * 0.08) * amp;
if (x === 0) ctx.moveTo(ox + x, y);
else ctx.lineTo(ox + x, y);
}
ctx.stroke();
ctx.fillStyle = '#ef4444';
ctx.font = 'bold 13px "PingFang SC","Microsoft YaHei",sans-serif';
ctx.fillText('船尾锚张力(偏荡冲击)', ox + 380, oy - 200);
// 走锚标记箭头
const peakX = ox + 340;
const peakY = oy - 195;
drawArrow(ctx, peakX, peakY, peakX, limitY - 5, '#f59e0b', 2.5, 8);
ctx.fillStyle = '#f59e0b';
ctx.font = 'bold 12px "PingFang SC","Microsoft YaHei",sans-serif';
ctx.fillText('超出极限抓力 → 走锚', peakX - 40, limitY + 20);
}
// ============ 执行所有绘图 ============
drawCanvas1();
drawCanvas2();
drawCanvas3();
drawCanvas4();
// 响应窗口大小变化(简单重绘)
window.addEventListener('resize', () => {
drawCanvas1();
drawCanvas2();
drawCanvas3();
drawCanvas4();
});
})();
</script1>