javascript中的 三角函数
-
<template> <div> <header>正切函数 循环 定义域[-Math.PI/2, Math.PI/2] 值域(-无穷, +无穷)</header> <canvas id="canvas"></canvas> <header>双曲线正弦函数 (-无穷, +无穷) 值域(-无穷, +无穷)</header> <canvas id="canvas2"></canvas> <header>双曲线余弦函数 (-无穷, +无穷) 值域(1, +无穷)</header> <canvas id="canvas3"></canvas> <header>双曲线正切函数 (-无穷, +无穷) 值域(-1, 1)</header> <canvas id="canvas4"></canvas> </div> </template> <script> import { defineComponent, onMounted } from 'vue' export default defineComponent({ name: 'math', setup() { // 绝对值 console.log(Math.abs(-1.3)); // 1.3 // 上舍入 console.log(Math.ceil(1.67)); // 2 // 下舍入 console.log(Math.floor(1.46)); // 1 // 四舍五入 console.log(Math.round(1.45)); // 1 console.log(Math.round(1.56)); // 2 // exp(x) 自然对数的x次幂 console.log(Math.exp(1)); // 2.718281828459045 e是自然对数的底数 // log(x) 返回x的自然对数 console.log(Math.log(Math.E)); // 1 // max 求数中的最大值 console.log(Math.max(5,6,7,9)); // 9 // min 求数中的最小值 console.log(Math.min(5,6,7,9)); // 5 // pow(x,y); 返回x的y次幂 console.log(Math.pow(3,2)); // 9 console.log(3**2); // 9 // sqrt(x) 返回x的平方根 console.log(Math.sqrt(100)); // 10 // trunc(x) 将x的小数部分去掉 console.log(Math.trunc(1.2345)); // 1 console.log(Math.trunc(-1.2345)); // -1 // 正切函数 console.log(Math.tan(45 / 180 * Math.PI)); // 0.99999... ~= 1 console.log(Math.tan(-45 / 180 * Math.PI)); // -0.99999... ~= -1 // 反正切换函数 console.log(Math.atan(1) * 180 / Math.PI); // 45度 console.log(Math.atan(-1) * 180 / Math.PI); // -45 // 返回从 x 轴到点 (x,y) 之间的角度。Math.atan2(y, x) console.log(Math.atan2(1, 1) * 180 / Math.PI); // 45度 console.log(Math.atan2(-1, 1) * 180 / Math.PI); // -45 // 正弦 console.log(Math.sin(30 / 180 * Math.PI)); // 0.5 console.log(Math.sin(90 / 180 * Math.PI)); // 1 // 反正弦 console.log(Math.asin(1) * 180 / Math.PI); // 90度 console.log(Math.asin(0) * 180 / Math.PI); // 0度 // 余弦 console.log(Math.cos(0 / 180 * Math.PI)); // 1 console.log(Math.cos(60 / 180 * Math.PI)); // 0.5 // 反余弦 console.log(Math.acos(1) * 180 / Math.PI); // 0度 console.log(Math.acos(0) * 180 / Math.PI); // 90度 // 双曲线正切函数 tanh(x) 值(-1,1) // 双曲线正切函数=双曲线正弦函数/双曲线余弦函数 console.log(Math.tanh(0)); // 0 // 绘制正切函数 function drawTan(canvasDom, size=400){ const ctx = canvasDom.getContext('2d'); const radius = size/2; canvasDom.width = size; canvasDom.height = size; ctx.lineWidth = 1; ctx.strokeStyle = '#ff0000'; ctx.translate(radius, radius); // 原点移动到画布中心 ctx.save(); for(let x = -radius; x < radius; x++){ const xtan = Math.tan((x / radius * (Math.PI / 2))) / 4; // 归一化 [-1, 1] * (Math.pI / 2) 除以4是加了个系数 const y = -xtan * radius; if(x === -radius){ ctx.moveTo(x, y); } else { ctx.lineTo(x, y); } } ctx.stroke(); // 画x轴 const fontSize = 18; drawText({ ctx, text: 'x', x: radius - fontSize, y: fontSize, fontSize: 18, fontColor: 'blue', }) drawLine({ ctx, startX: -radius, startY: 0, endX: radius, endY: 0, strokeColor: 'blue', lineWidth: 1, }); // 画箭头 drawArrow({ ctx, x: radius, y: 0, direction: 'left', size: 10, strokeColor: 'blue', lineWidth: 1, angle: 60, }); // 画y轴 drawText({ ctx, text: 'y', x: 10, y: -radius + fontSize, fontSize, fontColor: 'blue', }) drawLine({ ctx, startX: 0, startY: radius, endX: 0, endY: -radius, strokeColor: 'blue', lineWidth: 1, }); // 画箭头 drawArrow({ ctx, x: 0, y: -radius, direction: 'top', size: 10, strokeColor: 'blue', lineWidth: 1, angle: 60, }); } // 绘制双曲线正弦函数 function drawSinh(canvasDom, size=400){ const ctx = canvasDom.getContext('2d'); const radius = size/2; canvasDom.width = size; canvasDom.height = size; ctx.lineWidth = 1; ctx.strokeStyle = '#ff0000'; ctx.translate(radius, radius); // 原点移动到画布中心 ctx.save(); for(let x = -radius; x < radius; x++){ const xtan = Math.sinh((x / radius * (Math.PI / 2))) /4; // 归一化 [-1, 1] * (Math.pI / 2) 除以4是加了个系数让曲线好看,否则太陡峭 const y = -xtan * radius; if(x === -radius){ ctx.moveTo(x, y); } else { ctx.lineTo(x, y); } } ctx.stroke(); // 画x轴 const fontSize = 18; drawText({ ctx, text: 'x', x: radius - fontSize, y: fontSize, fontSize: 18, fontColor: 'blue', }) drawLine({ ctx, startX: -radius, startY: 0, endX: radius, endY: 0, strokeColor: 'blue', lineWidth: 1, }); // 画箭头 drawArrow({ ctx, x: radius, y: 0, direction: 'left', size: 10, strokeColor: 'blue', lineWidth: 1, angle: 60, }); // 画y轴 drawText({ ctx, text: 'y', x: 10, y: -radius + fontSize, fontSize, fontColor: 'blue', }) drawLine({ ctx, startX: 0, startY: radius, endX: 0, endY: -radius, strokeColor: 'blue', lineWidth: 1, }); // 画箭头 drawArrow({ ctx, x: 0, y: -radius, direction: 'top', size: 10, strokeColor: 'blue', lineWidth: 1, angle: 60, }); } // 绘制双曲线余弦函数 function drawCosh(canvasDom, size=400){ const ctx = canvasDom.getContext('2d'); const radius = size/2; canvasDom.width = size; canvasDom.height = size; ctx.lineWidth = 1; ctx.strokeStyle = '#ff0000'; ctx.translate(radius, radius); // 原点移动到画布中心 ctx.save(); for(let x = -radius; x < radius; x++){ const xtan = Math.cosh((x / radius * (Math.PI / 2))) / 2; // 归一化 [-1, 1] * (Math.pI / 2) 除以4是加了个系数让曲线好看,否则太陡峭 const y = -xtan * radius; if(x === -radius){ ctx.moveTo(x, y); } else { ctx.lineTo(x, y); } } ctx.stroke(); // 画x轴 const fontSize = 18; drawText({ ctx, text: 'x', x: radius - fontSize, y: fontSize, fontSize: 18, fontColor: 'blue', }) drawLine({ ctx, startX: -radius, startY: 0, endX: radius, endY: 0, strokeColor: 'blue', lineWidth: 1, }); // 画箭头 drawArrow({ ctx, x: radius, y: 0, direction: 'left', size: 10, strokeColor: 'blue', lineWidth: 1, angle: 60, }); // 画y轴 drawText({ ctx, text: 'y', x: 10, y: -radius + fontSize, fontSize, fontColor: 'blue', }) drawLine({ ctx, startX: 0, startY: radius, endX: 0, endY: -radius, strokeColor: 'blue', lineWidth: 1, }); // 画箭头 drawArrow({ ctx, x: 0, y: -radius, direction: 'top', size: 10, strokeColor: 'blue', lineWidth: 1, angle: 60, }); } // 绘制双曲线正切函数 function drawTanh(canvasDom, size=400){ const ctx = canvasDom.getContext('2d'); const radius = size/2; canvasDom.width = size; canvasDom.height = size; ctx.lineWidth = 1; ctx.strokeStyle = '#ff0000'; ctx.translate(radius, radius); // 原点移动到画布中心 ctx.save(); for(let x = -radius; x < radius; x++){ const xtan = Math.tanh((x / radius * (Math.PI / 2))) / 2; // 归一化 [-1, 1] * (Math.pI / 2) 除以4是加了个系数让曲线好看,否则太陡峭 const y = -xtan * radius; if(x === -radius){ ctx.moveTo(x, y); } else { ctx.lineTo(x, y); } } ctx.stroke(); // 画x轴 const fontSize = 18; drawText({ ctx, text: 'x', x: radius - fontSize, y: fontSize, fontSize: 18, fontColor: 'blue', }) drawLine({ ctx, startX: -radius, startY: 0, endX: radius, endY: 0, strokeColor: 'blue', lineWidth: 1, }); // 画箭头 drawArrow({ ctx, x: radius, y: 0, direction: 'left', size: 10, strokeColor: 'blue', lineWidth: 1, angle: 60, }); // 画y轴 drawText({ ctx, text: 'y', x: 10, y: -radius + fontSize, fontSize, fontColor: 'blue', }) drawLine({ ctx, startX: 0, startY: radius, endX: 0, endY: -radius, strokeColor: 'blue', lineWidth: 1, }); // 画箭头 drawArrow({ ctx, x: 0, y: -radius, direction: 'top', size: 10, strokeColor: 'blue', lineWidth: 1, angle: 60, }); } /** * 画箭头 * x,y箭头顶点坐标 * direction 方向 left,right,top,bottom * size 箭头斜边边长 * color 箭头颜色 * bold 箭头粗细 * angle 箭头角度 * @param param0 */ function drawArrow({ctx,x, y, direction='left', size=28, strokeColor='red', lineWidth=1, angle=60}){ // 半角 const halfAngle = angle / 2 * Math.PI / 180; const sin = size * Math.sin(halfAngle); const cos = size * Math.cos(halfAngle); ctx.save(); ctx.beginPath(); // 确保每次绘制都是新的路径 ctx.lineWidth = lineWidth; ctx.strokeStyle = strokeColor; let startPoint, endPoint; switch(direction){ case 'left': startPoint = [x - cos, y - sin]; endPoint = [x - cos, y + sin]; break; case 'right': startPoint = [x + cos, y - sin]; endPoint = [x + cos, y + sin]; break; case 'top': startPoint = [x - sin, y + cos]; endPoint = [x + sin, y + cos]; break; case 'bottom': startPoint = [x - sin, y - cos]; endPoint = [x + sin, y - cos]; break; } const [startX, startY] = startPoint; const [endX, endY] = endPoint; console.log({startPoint, endPoint,sin, cos}) ctx.moveTo(startX,startY); ctx.lineTo(x, y); ctx.lineTo(endX, endY); ctx.stroke(); ctx.restore(); } // 画线 function drawLine({ctx, startX, startY, endX, endY, strokeColor, lineWidth=1}){ ctx.save(); ctx.beginPath(); // 确保每次绘制都是新的路径(画线时要加beginPath,否则认为和之前是一条线,颜色什么的会用之前的) ctx.strokeStyle = strokeColor; ctx.lineWidth = lineWidth; ctx.moveTo(startX, startY); ctx.lineTo(endX, endY); ctx.stroke(); ctx.restore(); } // 画文字 function drawText({ctx, text, x, y, fontSize=18, fontColor='red'}){ ctx.save(); ctx.fillStyle = fontColor; ctx.font = `${fontSize}px sans-serif`; ctx.fillText(text, x, y); ctx.restore(); } onMounted(() => { const canvas = document.querySelector('#canvas'); drawTan(canvas, 400); const canvas2 = document.querySelector('#canvas2'); drawSinh(canvas2, 400); const canvas3 = document.querySelector('#canvas3'); drawCosh(canvas3, 400); const canvas4 = document.querySelector('#canvas4'); drawTanh(canvas4, 400); }) return {} } }); </script> <style scoped lang='scss'> #canvas{ border: 1px solid red; } </style>
=
=
=
-
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通