【问题标题】:How to get mouse coordinates and to .push()?如何获取鼠标坐标和.push()?
【发布时间】:2017-05-06 14:38:53
【问题描述】:

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

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

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

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

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();
    }
}

【问题讨论】:

  • 简单地删除这个:points = []; ch = [];
  • @Jonasw 没有结果

标签: javascript jquery canvas


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

    我相信您不想在点击时重置客户端数组,并且您想要相对位置:

    document.getElementById('canvas').onclick = function(e) {
      var x;
      var y;
       if (e.pageX || e.pageY) { 
          x = e.pageX;
          y = e.pageY;
       }else { 
          x = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft; 
          y = e.clientY + document.body.scrollTop + document.documentElement.scrollTop; 
       } 
       x -= this.offsetLeft;
       y -= this.offsetTop;
      points.push({x:x-300,y:-y});// i think you need relative positions here...
      ch.push(ch.length);//thats all... no need for a counter...
    
      graham();
    }
    

    资源:How do I get the coordinates of a mouse click on a canvas element?

    【讨论】:

    • @charlietfl 不是 ES6 中引入的增强型对象字面量吗?
    • 但并非所有浏览器都支持
    • @charlietfl 是的,所以一个公平的评论应该是请注意这是 ES6not push a valid object 听起来像 你的代码错误! ...
    • @Jonasw 我将codepen.io/Drew_D/pen/eWeJXj 更新到你的最新版本我认为坐标也有问题
    • @Jonasw 我想我需要一些东西,比如将屏幕坐标转换为画布
    猜你喜欢
    • 2010-12-03
    • 1970-01-01
    • 2013-12-26
    • 2018-01-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多