Определите, пересекаются ли линии в Google Charts или Plot.ly - PullRequest
0 голосов
/ 18 марта 2020

Я видел сценарии, которые утверждают, что вводят координаты, и он скажет вам, если они пересекаются, но у меня есть массив значений X, Y для пары «линий», но как мне циклически проходить через точки, чтобы выяснить, если они пересекаются?

Я включил фотографию своего графика и, как вы видите, в конечном итоге мои графики пересекаются, я просто хочу знать, пересекаются ли мои значения (пересекаются).

text

Как мне пройти через это, чтобы узнать, происходит ли какое-либо пересечение?

var Test = {
 x: [8043, 10695, 13292, 17163, 20716, 25270],
 y: [1000,   274,   100,  27.4,    10,  2.74],
 fill: 'tozeroy',
 type: 'scatter',
 name: 'Test'
};


var Test2 = {
 x: [8043, 10063, 12491, 16081, 19408, 23763],
 y: [1000,   274,   100,  27.4,    10,  2.74],
 fill: 'tozeroy',
 type: 'scatter',
 name: 'Test2'
};

var Test3 = {
 x: [4700,  5943,  7143,  8841, 10366, 13452],
 y: [1000,   274,   100,  27.4,    10,  2.74],
 fill: 'tozeroy',
 type: 'scatter',
 name: 'Test3'
};


var data = [Test, Test2, Test3];

var layout = {
width: 700,
height: 700,
xaxis: {
 type: 'log',
 range: [3,5] 
},
yaxis: {
 type: 'log',
 range: [-2,3] 
}

};

Plotly.newPlot('myDiv', data,layout);

1 Ответ

1 голос
/ 27 марта 2020

Перехват пути

Этот ответ является продолжением моего ответа на ваш самый последний вопрос.

Фрагмент кода ниже найдет перехват путей в Таблицы, структурированные в этом примере данных, с использованием модифицированной функции перехвата из ссылки на ответ, могут комментировать вышеупомянутый ответ.

Примечание Я предполагаю, что каждая таблица, например, Test в вашем Пример данных представляет собой кривую (путь как набор сегментов линии), и перехваты ожидаются не внутри таблицы, а между таблицами.

Basi c решение

Это выполняется путем проверки каждый отрезок строки в одной таблице против каждого отрезка линии в другой и хранит все перехваты в массиве.

Примечание , что если перехват найден в начальной или конечной точке строки, он может появиться в массиве перехватов дважды, поскольку тест перехвата включает эти точки.

Примечание параллельные линии, даже если у них совпадают начальная и / или конечная точки не будут считаться перехватами.

Пример выполняется с данными примера и имеет подробный вывод на консоль, который при необходимости поможет вам работать с любыми наборами данных, которые вы обрабатываете , Журналы консоли могут быть удалены без вреда.

var Test = {
 x: [8043, 10695, 13292, 17163, 20716, 25270],
 y: [1000,   274,   100,  27.4,    10,  2.74],
 fill: 'tozeroy',
 type: 'scatter',
 name: 'Test'
};


var Test2 = {
 x: [8043, 10063, 12491, 16081, 19408, 23763],
 y: [1000,   274,   100,  27.4,    10,  2.74],
 fill: 'tozeroy',
 type: 'scatter',
 name: 'Test2'
};

var Test3 = {
 x: [4700,  5943,  7143,  8841, 10366, 13452],
 y: [1000,   274,   100,  27.4,    10,  2.74],
 fill: 'tozeroy',
 type: 'scatter',
 name: 'Test3'
};


// Copy from here to end comment and place into you page (code base)

// lines outputting to the console eg console.log are just there to help you out
// and can be removed
const lineIntercepts = (() => {
	const Point = (x, y) => ({x, y});
	const Line = (p1, p2) => ({p1, p2});
	const Vector = line => Point(line.p2.x - line.p1.x, line.p2.y - line.p1.y);
	function interceptSegs(line1, line2) {
		const a = Vector(line1), b = Vector(line2);
		const c = a.x * b.y - a.y * b.x;
		if (c) {
			const e = Point(line1.p1.x - line2.p1.x, line1.p1.y - line2.p1.y);
			const u = (a.x * e.y - a.y * e.x) / c;
			if (u >= 0 && u <= 1) {
				const u = (b.x * e.y - b.y * e.x) / c;
				if (u >= 0 && u <= 1) {
					return Point(line1.p1.x + a.x * u, line1.p1.y + a.y * u);
				}
			}
		}
	}	
	const PointFromTable = (t, idx) => Point(t.x[idx], t.y[idx]);
	const LineFromTable = (t, idx) => Line(PointFromTable(t, idx++), PointFromTable(t, idx));
	return function (table1, table2) {
		const results = [];
		var i = 0, j;
		while (i < table1.x.length - 1) {
			
			const line1 = LineFromTable(table1, i);
			j = 0;
			while (j < table2.x.length - 1) {
				const line2 = LineFromTable(table2, j);
				const point = interceptSegs(line1, line2);
				if (point) { 
					results.push({
						description: `'${table1.name}' line seg index ${i}-${i+1} intercepts '${table2.name}' line seg index ${j} - ${j+1}`,

                    // The description (line above) can be replaced 
                    // with relevant data as follows
/*  remove this line to include additional info per intercept
                        tableName1: table1.name,
                        tableName2: table2.name,
                        table_1_PointStartIdx: i,
                        table_1_PointEndIdx: i + 1,   
                        table_2_PointStartIdx: j,
                        table_2_PointEndIdx: j + 1,   
and remove this line */

						x: point.x,
						y: point.y,
					});
				}
				j ++;
			}
			i++;
		}
		if (results.length) {
			console.log("Found " + results.length + " intercepts for '" + table1.name + "' and '" + table2.name + "'");
			console.log(results);
			return results;
		} 
		console.log("No intercepts found for  '" + table1.name + "' and '" + table2.name + "'");
	}
})();

// end of code



// Test and example code only from here down.					
var res1 = lineIntercepts(Test, Test2);    
var res2 = lineIntercepts(Test, Test3);    
var res3 = lineIntercepts(Test2, Test3);    
          
          

		

Использование вышеуказанной функции

Этот фрагмент кода иллюстрирует, как вы извлекаете перехваты из результатов функции

// find all the intercepts for the paths in tabels Test and Test2
const results = lineIntercepts(Test, Test2); // pass two tables

// If results not undefined then intercepts have been found
if (results) { // results is an array of found intercepts

    // to get the point/s as there could be several
    for (const intercept of results) {  // loop over every intercept 

        // a single intercept coordinate
        const x = intercept.x;  // get x
        const y = intercept.y;  // get y
    }
}

Лучшие решения

Пути выглядят очень похоже на график какой-то функции, поэтому есть даже более простые решения.

Вместо того, чтобы перечислять строки кода, я направлю вас к графическим калькуляторам на случай, если вы не знают о таких полезных экономит время. Они бы решили вашу проблему за время, необходимое для ввода данных (копирование и вставка, что не очень долго)

Онлайн-калькуляторы, примеры приложений Геогебра и Desmos и еще много.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...