javascript - 如何获取鼠标坐标并调用.push()?

标签 javascript jquery canvas

所以我有格雷厄姆扫描算法,它可以找到平面上有限点集的凸包。我有一些功能:

  • 从文本区域获取坐标(x,y),将其绘制在 Canvas 上,使用 格雷厄姆最后画了线;
  • 从文本文件中获取坐标 (x, y) -//-;
  • 来自 onclick 事件的坐标 (x, y) -//-;

在这里您可以查看项目:https://codepen.io/Drew_D/pen/eWeJXj

所以问题出在 .js 代码末尾的最后一个函数中。我不知道如何向现有 Canvas 添加(绘制新)点+它应该重新加载算法...... 所以我需要获取鼠标坐标,将它们推到points[]和ch[]/*points[]这是一个带有坐标的数组; ch[] 这是一个点数数组,如第一个点、第二个点等。算法需要它*/,然后用旧点 + 新点刷新 Canvas

main.js

    function create_canvas() {
        var canvas_html = document.createElement('canvas');
        canvas_html.id = "canvas";
        canvas_html.width = 600;
        canvas_html.height = 520;
        canvas_html.onclick="getCoords(event)"

        document.getElementById("canva_res").appendChild(canvas_html);

        return canvas_html.getContext('2d');
    }

    /**
     * рисует координатные оси
     */
function drawCoordLines() {
    canvas.beginPath();
    canvas.strokeStyle = '#fff';
    canvas.moveTo(300, 0);
    canvas.lineTo(300, 440);
    canvas.moveTo(0, 220);
    canvas.lineTo(600, 220);
    canvas.stroke();
    for (var x = 0.5; x < 610; x += 10) {
canvas.moveTo(x, 0);
canvas.lineTo(x, 450);
}
for (var y = 0.5; y < 450; y += 10) {
canvas.moveTo(0, y);
canvas.lineTo(600, y);
}canvas.strokeStyle = "#1abc9c";
canvas.stroke();
    canvas.closePath();
}

/**
 * рисует оболочку
 */
function drawHull() {

    canvas.beginPath();
    canvas.strokeStyle = '#fff';
    canvas.moveTo(300 + points[ h[0] ].x, 220 - points[ h[0] ].y);
    for(var i=1; i<h.length; i++){
        canvas.lineTo(300 + points[ h[i] ].x, 220 - points[ h[i] ].y);
    }

    canvas.closePath();
    canvas.stroke();
}

/**
 * рисует точки
 */
function drawPoints() {

    canvas.fillStyle = '#000';
    for(var i=0; i<points.length; i++){
        canvas.beginPath();
        canvas.arc(300 + points[i].x, 220 - points[i].y, 3, 0, Math.PI * 2); // рисует точку
        canvas.closePath();
        canvas.fill();
    }


}

/**
 * обновляет и перерисовывает канвас
 */
function update() {
    canvas.clearRect(0, 0, 1500, 800); // очищаем канвас
    drawCoordLines();
    drawHull();
    drawPoints();
}

/**
 * считывает точки из формы
 */
function getPoints() {
    // получаем строку введенную в форму, и записываем в массив, разбив ее по запятой
    var coords = pointsV.value.split(", ");
    var i = 0;
    var j = 0;
    points = [];
    ch = [];
    while (i < coords.length) {
        points[j++] = {
            'x': parseInt(coords[i++]),
            'y': parseInt(coords[i++])
        }
        ch.push(j-1);
    }
    graham();
}

/**
 * возращает векторное произведение
 */
function classify(vector, x1, y1) {
    return pr = (vector.x2 - vector.x1) * (y1 - vector.y1) - (vector.y2 - vector.y1) * (x1 - vector.x1);
}

/**
 * Выполняет поиск Грэхема и заполняет массив h, в котором будут перечислены точки, входящие в оболочку
 */
function graham() {
    var minI = 0; //номер нижней левой точки
    var min = points[0].x;
    // ищем нижнюю левую точку
    for (var i = 1; i < points.length; i++) {
        if (points[i].x < min) {
            min = points[i].x;
            minI = i;
        }
    }
    // делаем нижнюю левую точку активной
    ch[0] = minI;
    ch[minI] = 0;

    // сортируем вершины в порядке "левизны"
    for (var i = 1; i < ch.length - 1; i++) {
        for (var j = i + 1; j < ch.length; j++) {
            var cl = classify({
                'x1': points[ ch[0] ].x,
                'y1': points[ ch[0] ].y,
                'x2': points[ ch[i] ].x,
                'y2': points[ ch[i] ].y
            }, points[ ch[j] ].x, points[ ch[j] ].y) // функция classify считает векторное произведение.

            // если векторное произведение меньше 0, следовательно вершина j левее вершины i.Меняем их местами
            if (cl < 0) {
                temp = ch[i];
                ch[i] = ch[j];
                ch[j] = temp;
            }
        }
    }

    //записываем в стек вершины, которые точно входят в оболочку
    h = [];
    h[0] = ch[0];
    h[1] = ch[1];


    for (var i = 2; i < ch.length; i++) {
        while (classify({
            'x1': points[ h[h.length - 2] ].x,
            'y1': points[ h[h.length - 2] ].y,
            'x2': points[ h[h.length - 1] ].x,
            'y2': points[ h[h.length - 1] ].y
        }, points[ ch[i] ].x, points[ ch[i] ].y) < 0) {
            h.pop(); // пока встречается правый поворот, убираем точку из оболочки
        }
        h.push(ch[i]); // добавляем новую точку в оболочку
    }

    // обновляем канвас
    update();
}

/**
 * выполняется когда страница будет полностью загружена в браузер
 */
window.onload = function() {
    canvas = create_canvas();

    // массив точек, из которых строим выпуклую оболочку
    points = [{
            'x': 10,
            'y': 20
        }, {
            'x': 60,
            'y': 160
        }, {
            'x': 110,
            'y': 20
        }, {
            'x': -60,
            'y': 80
        },
        {
            'x': 70,
            'y': 140
        }];

    // массив номеров точек, потребуется для алгоритма Грэхема
    ch = [0, 1, 2, 3, 4];

    // искомая оболочка, будет заполнена функцией graham
    h = []

    // получаем форму ввода
    pointsV = document.getElementById('pointos');
    graham();

    document.getElementById('canvas').onclick = function(e) {
      var i = 1;
      var j = 1;

      points = [];
      ch = [];
      points.push({'x': e.clientX, 'y': e.clientY});
      ch.push(j);
      j++;
      graham();
    }
}

最佳答案

看起来我们需要在每次 graham 调用时重置 ch 数组:

function graham(){
     ch=ch.map((e,i)=>i);// creates [0,1,2,3,...]
    //...
}

关于javascript - 如何获取鼠标坐标并调用.push()?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43821721/

相关文章:

javascript - 向 AngularJS Accordion 添加选项卡索引?

javascript - 为什么我们不能将 jquery 选择器对象设置为另一个对象的属性并在以后使用它们?

javascript - 为什么单击关闭按钮后,可忽略的警报不再显示?

javascript - Canvas 仅获取不透明像素

javascript - Safari 扩展中带有特殊字符的 XMLHttpRequest 不起作用

javascript - 如何用javascript优化这段代码?

javascript - 如何向JS音频对象添加淡入/淡出方法

javascript - jQuery 根据输入全是数字或只是字母来触发不同表单的提交

javascript - 为什么 Canvas 上什么也没有出现?

canvas - 弯曲一个以矩形开始的图像(由用户上传),最好使用 Canvas 或 JS