Canvas 图形开发高频算法面试题

文章目录

一、判断点是否在闭合路径内(射线法 / 奇偶规则)

这是 Canvas 面试100% 会考的题,用于判断鼠标点击是否在多边形、不规则图形内。

1. 算法原理(射线法)

  • 从目标点向右发射一条水平无限长射线
  • 统计射线与闭合路径边的相交次数
  • 奇数次 = 在图形内,偶数次 = 在图形外

2. 通用代码(支持任意多边形 / 闭合路径)

javascript 复制代码
/**
 * 判断点是否在多边形内部 (射线法)
 * @param {Object} point - 目标点 {x, y}
 * @param {Array} polygon - 多边形顶点数组 [{x,y}, {x,y}, ...]
 * @returns {Boolean} 在内返回 true,在外 false
 */
function isPointInPolygon(point, polygon) {
  let inside = false;
  const px = point.x;
  const py = point.y;

  // 遍历多边形所有边(首尾相连)
  for (let i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {
    const xi = polygon[i].x, yi = polygon[i].y;
    const xj = polygon[j].x, yj = polygon[j].y;

    // 核心判断:点的y坐标在边的y区间内 + 射线与边相交
    const intersect = 
      ((yi > py) !== (yj > py)) 
      && 
      (px < (xj - xi) * (py - yi) / (yj - yi) + xi);

    if (intersect) inside = !inside;
  }
  return inside;
}

3. Canvas 原生简化方案

Canvas 自带 isPointInPath() API,性能更高、支持圆弧 / 贝塞尔曲线:

javascript 复制代码
// 绘制闭合路径
ctx.beginPath();
ctx.moveTo(100, 100);
ctx.lineTo(200, 100);
ctx.lineTo(150, 200);
ctx.closePath();

// 判断点 (150,150) 是否在路径内
const isInPath = ctx.isPointInPath(150, 150); 

二、判断点是否在圆形内

超简单,勾股定理计算距离即可。

javascript 复制代码
/**
 * 判断点是否在圆内
 * @param {Object} point - 点 {x,y}
 * @param {Object} circle - 圆 {x,y,r}
 * @returns {Boolean}
 */
function isPointInCircle(point, circle) {
  const dx = point.x - circle.x;
  const dy = point.y - circle.y;
  // 距离平方 < 半径平方(避免开方,提升性能)
  return dx * dx + dy * dy <= circle.r * circle.r;
}

三、线段相交判断

用于碰撞检测、路径裁剪。

javascript 复制代码
/**
 * 判断两条线段是否相交
 */
function isSegmentsIntersect(a1, a2, b1, b2) {
  // 向量叉乘计算
  function cross(p1, p2, p0) {
    return (p1.x - p0.x) * (p2.y - p0.y) - (p2.x - p0.x) * (p1.y - p0.y);
  }

  const d1 = cross(b1, b2, a1);
  const d2 = cross(b1, b2, a2);
  const d3 = cross(a1, a2, b1);
  const d4 = cross(a1, a2, b2);

  // 跨立实验(快速判断)
  if (d1 * d2 < 0 && d3 * d4 < 0) return true;
  
  return false;
}

四、贝塞尔曲线点判断

直接用 Canvas 原生 API,手写算法复杂且没必要:

javascript 复制代码
// 绘制二次贝塞尔曲线
ctx.beginPath();
ctx.moveTo(50,50);
ctx.quadraticCurveTo(100,100, 150,50);
ctx.lineTo(150,100);
ctx.lineTo(50,100);
ctx.closePath();

// 判断点是否在曲线围成的区域内
ctx.isPointInPath(x, y);

面试回答万能模板(背这个)

面试官问:如何判断点在 Canvas 闭合图形内?

标准回答:

  1. 对于多边形,我使用射线法:从点向右发射水平射线,统计与边的相交次数,奇数在内、偶数在外;
  2. 对于圆形,用距离公式判断点到圆心距离是否小于半径;
  3. 实际开发中,我优先使用 Canvas 原生 isPointInPath(),支持所有路径(多边形、圆弧、贝塞尔曲线),性能最优、代码简洁。

总结

  1. 核心必考:射线法判断点在多边形内 + isPointInPath 原生 API;
  2. 基础算法:点圆、点矩形、矩形碰撞、线段相交;
  3. 面试技巧:先讲原理,再写代码,最后提原生 API 优化。
相关推荐
手写码匠10 小时前
DeepSeek 函数调用实战:从零搭建一个会“动手“的 AI 助手
人工智能·深度学习·算法·aigc
果壳science11 小时前
《自然本源》如何实现狭义相对论的代数化
笔记·算法·几何学
302wanger11 小时前
分享一个工作习惯:整点看即时消息
算法
洋不写bug13 小时前
排序(一)基础排序,插入|希尔|冒泡|直接选择排序详解
java·算法·排序算法·插入排序·冒泡排序·希尔排序·直接选择排序
牧羊人.33313 小时前
动手学深度学习 03 | 卷积神经网络实现手写数字识别
人工智能·深度学习·神经网络·算法·cnn
AgentMaster13 小时前
数据治理工具选型指南:一套可复用的四阶段决策框架
大数据·数据结构·人工智能·算法
liliangcsdn14 小时前
最终留出样本/样本外测试集-holdout解读
算法
爱敲代码的小黄14 小时前
机器学习入门:从数据、训练到业务决策
算法
数据知道14 小时前
哈希与密码存储——bcrypt、Argon2、盐值与彩虹表
网络·算法·安全·网络安全·密码学·哈希算法
haon112214 小时前
树模型在信贷风控怎么用——从决策树到 XGBoost
大数据·人工智能·算法·决策树·机器学习·数据挖掘