Как динамически идентифицировать области, образованные линиями, заключенными в многоугольник, нарисованный с помощью графика JSX

#javascript #math #jsxgraph

Вопрос:

У меня есть график, на котором пользователи могут создавать точки и рисовать линии. Эти строки могут быть перемещены пользователем. Я также добавил фиксированный многоугольник (EFGH) вокруг линий. Теперь мне нужно найти способ разрешить пользователям нажимать и выбирать область, образованную линиями и EFGH. Я подумал о создании многоугольника для каждой из этих областей и придании цвета заливки при нажатии. Но поскольку эти линии можно перемещать, полигоны должны создаваться динамически. Я не уверен, как определить конечные точки и создать их. Требование состоит в том, чтобы определить область, выбранную пользователем, и затенить ее, поэтому, если есть более простое решение, отличное от создания полигонов, это тоже нормально. Хотя пример кода был бы полезен, я был бы признателен, если бы кто-нибудь мог хотя бы указать мне направление.

На рисунке ниже показан пример с 2 линиями(и 4 областями), хотя их может быть больше.

Требования к Jsxgraph

Пример кода можно посмотреть ниже

 let board = JXG.JSXGraph.initBoard('jxgbox', {boundingbox: [-13, 10, 10, -10], 
axis:true, keepAspectRatio:true});
var p1 = board.create('point', [0, 0]);
var p2 = board.create('point',  [1.0, 1.0]);
var p3 = board.create('point', [3, 0]);
var p4= board.create('point',  [3, 5],);

let l1 = board.create('line', [p1,p2],{dash:4});
let l2 = board.create('line', [p3,p4],{dash:4});


var p1x = board.create('point', [-5, 5],{fixed:true});
var p2x = board.create('point', [5, 5],{fixed:true});
var p3x = board.create('point', [5,-5],{fixed:true});
var p4x = board.create('point', [-5,-5],{fixed:true});

var pol = board.create('polygon', [p1x, p2x, p3x, p4x],{borders:{strokecolor:"green"},fillcolor:"white",highlightfillcolor:"white",fixed:true,});
 

Пример можно попробовать в этой скрипке Jsxgraph скрипка

Я использовал JSXGraph
Мое требование аналогично этому

ОБНОВЛЕНИЕ 1:
Я попытался использовать заливку заливкой на холсте JSXGraph. Но я не смог выбрать правильную точку на графике, а также, поскольку линии сетки и оси были разных цветов, это помешало заливке, так что это тоже не сработало. Это то, что я пытался заполнить скрипкой

Ответ №1:

Для начала можно было бы использовать одну линию, добавить два элемента неравенства для этой линии и пересечь их с многоугольником. Кроме того, в следующем примере используется метод Джордана «точка в многоугольнике», чтобы определить, находится ли щелчок внутри одного из путей пересечения.

 const board = JXG.JSXGraph.initBoard('jxgbox', { 
    boundingbox: [-5, 5, 5, -5], axis:true
});

var isInside = function(pos, path) {
    var len = path.numberPoints, i, j,
        x = pos[0],
        y = pos[1],
        c = false;

    // Jordan's method, see https://en.wikipedia.org/wiki/Point_in_polygon
    for (i = 0, j = len - 1; i < len; j = i  ) {
        if (( (path.points[i].usrCoords[2] > y) !== (path.points[j].usrCoords[2] > y) ) amp;amp;
            (x < (path.points[j].usrCoords[1] - path.points[i].usrCoords[1]) * (y - path.points[i].usrCoords[2]) /
                  (path.points[j].usrCoords[2] - path.points[i].usrCoords[2])   path.points[i].usrCoords[1])) {
            c = !c;
        }
    }
    return c;
};

var pol = board.create('polygon', [[-3, -3], [3, -3], [3, 3], [-3, 3]]);
var li  = board.create('line', [[3, -4], [-2, 4]]);
var in1  = board.create('inequality', [li]);
var in2  = board.create('inequality', [li], {inverse: true, fillColor: 'pink'});
var isect1 = board.create('curve', [[], []], {fillColor: 'yellow', fillOpacity: 0.3});
    isect1.updateDataArray = function() {
        var a = JXG.Math.Clip.intersection(pol, in1, this.board);
        this.dataX = a[0];
        this.dataY = a[1];
    };
var isect2 = board.create('curve', [[], []], {fillColor: 'blue', fillOpacity: 0.3});
    isect2.updateDataArray = function() {
        var a = JXG.Math.Clip.intersection(pol, in2, this.board);
        this.dataX = a[0];
        this.dataY = a[1];
    };
    
board.on('down', function(evt) {
    var pos = this.getUsrCoordsOfMouse(evt),
        path, isIn,
        list = [isect1, isect2];

    for (path of list) {
        isIn = isInside(pos, path);
        if (isIn) {
            path.setAttribute({fillColor: 'gray'});
        }
    }
});
 

Посмотрите это вживую на https://jsfiddle.net/e64qyLxt/1/.