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 优化。
相关推荐
澈20741 分钟前
C++并查集:高效解决连通性问题
java·c++·算法
旖-旎2 小时前
深搜练习(单词搜索)(12)
c++·算法·深度优先·力扣
企客宝CRM3 小时前
2026年中小企业CRM选型指南:企客宝CRM处于什么位置?
android·算法·企业微信·rxjava·crm
橙淮3 小时前
二叉树核心概念与Java实现详解
数据结构·算法
米罗篮4 小时前
DSU并查集 & 拓展欧几里得-逆元
c++·经验分享·笔记·算法·青少年编程
橙淮4 小时前
双指针法:高效算法解题的利器
算法
初心未改HD4 小时前
深度学习之MLP与反向传播算法详解
人工智能·深度学习·算法
刀法如飞4 小时前
【Go 字符串查找的 20 种实现方式,用不同思路解决问题】
人工智能·算法·go
技术小黑6 小时前
CNN算法实战系列03 | DenseNet121算法实战与解析
pytorch·深度学习·算法·cnn