Определение ближайших координатных точек

Как определить ближайшие координатные точки при вводе курсора мышки в области (зеленую или желтую), для того что бы отрисовать второй контур и залить его другим цветом. Координаты лежат в массиве. Points = [{x:0,y:0},....]; example


Ответы (1 шт):

Автор решения: EzioMercer

Если рисуете в canvas-е, то могу предложить такой алгоритм, очень важно чтобы изначально заданных точек было как минимум 2:

//DEFINE INPUT, OBJECTS AND SECONDARY FUNCTIONS
const dots = [{x: 100, y: 50}, {x: 250, y: 50}, {x: 250, y: 150}, {x: 100, y: 100}];
const staticObjects = [];
const dynamicObjects = [];

const canvas = document.querySelector('#canvas');
const context = canvas.getContext('2d');

canvas.width = window.innerWidth;
canvas.height = window.innerHeight;

class FilledPolygon {  
  constructor(dots, fillColor) {
    this.dots = dots;
    this.fillColor = fillColor;
  }
  
  draw() {
    const path = new Path2D();
    const firstDot = this.dots[0];
  
    this.dots.forEach(dot => path.lineTo(dot.x, dot.y));

    path.lineTo(firstDot.x, firstDot.y);

    context.fillStyle = this.fillColor;
    context.strokeStyle = 'black';
    context.fill(path);
    context.stroke(path);
  }
}

class CornerCircle {
  constructor(center) {
    this.center = center;
  }
  
  draw() {
    const path = new Path2D();
    path.arc(this.center.x, this.center.y, 8, 0, 2 * Math.PI);
    context.stroke(path);
  }
}

const dist = (dot1, dot2) => Math.sqrt((dot2.x - dot1.x)**2 + (dot2.y - dot1.y)**2);

const findNearestDots = (dots, needDot) => {
  const nearestDots = [
    {
      distanceToNeedDot: Infinity,
      self: null
    },
    {
      distanceToNeedDot: Infinity,
      self: null
    },
  ];
  
  dots.forEach(dot => {
    const distanceToNeedDot = dist(dot, needDot);
    
    if (distanceToNeedDot < nearestDots[0].distanceToNeedDot) {
      
      [nearestDots[0], nearestDots[1]] = [nearestDots[1], nearestDots[0]];
      
      nearestDots[0].distanceToNeedDot = distanceToNeedDot;
      nearestDots[0].self = dot;
      return;
    }
    
    if (distanceToNeedDot < nearestDots[1].distanceToNeedDot) {
      nearestDots[1].distanceToNeedDot = distanceToNeedDot;
      nearestDots[1].self = dot;
      return;
    }
  });
  
  return nearestDots.map(dot => dot.self);
}

//STATIC OBJECTS
staticObjects.push(new FilledPolygon(dots, 'lightgreen'));
dots.forEach((dot, i) => staticObjects.push(new CornerCircle(dot)));

//UPDATE STATE LOGIC
canvas.addEventListener('mousemove', (e) => {
  const mouseDot = {x: e.clientX, y: e.clientY};
  
  const [nearestDot1, nearestDot2] = findNearestDots(dots, mouseDot);
  
  dynamicObjects[0] = new FilledPolygon([nearestDot1, nearestDot2, mouseDot], 'yellow');
  dynamicObjects[1] = new CornerCircle(mouseDot);
});


//DRAW LOGIC
const draw = () => {
  requestAnimationFrame(draw);

  context.clearRect(0, 0, canvas.width, canvas.height);
  
  staticObjects.forEach(staticObject => staticObject.draw());
  dynamicObjects.forEach(dynamicObject => dynamicObject.draw());
}

draw();
* {
  padding: 0;
  margin: 0;
}

canvas {
  background-color: lightgray;
}
<canvas id='canvas'></canvas>

→ Ссылка