#javascript #math #jsxgraph
Вопрос:
У меня есть график, на котором пользователи могут создавать точки и рисовать линии. Эти строки могут быть перемещены пользователем. Я также добавил фиксированный многоугольник (EFGH) вокруг линий. Теперь мне нужно найти способ разрешить пользователям нажимать и выбирать область, образованную линиями и EFGH. Я подумал о создании многоугольника для каждой из этих областей и придании цвета заливки при нажатии. Но поскольку эти линии можно перемещать, полигоны должны создаваться динамически. Я не уверен, как определить конечные точки и создать их. Требование состоит в том, чтобы определить область, выбранную пользователем, и затенить ее, поэтому, если есть более простое решение, отличное от создания полигонов, это тоже нормально. Хотя пример кода был бы полезен, я был бы признателен, если бы кто-нибудь мог хотя бы указать мне направление.
На рисунке ниже показан пример с 2 линиями(и 4 областями), хотя их может быть больше.
Пример кода можно посмотреть ниже
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/.