Javascript-форум (https://javascript.ru/forum/)
-   Элементы интерфейса (https://javascript.ru/forum/dom-window/)
-   -   Есть ли в SVG возможность рисовать линии математическими функциями? (https://javascript.ru/forum/dom-window/76349-est-li-v-svg-vozmozhnost-risovat-linii-matematicheskimi-funkciyami.html)

RX200 02.01.2019 16:13

Есть ли в SVG возможность рисовать линии математическими функциями?
 
Здравствуйте. Есть ли в SVG возможность рисовать линии математическими функциями? Если нет в SVG то есть ли другие технологии в Вебе с помощью которых можно легко и просто рисовать векторную графику через функции?
Я искал уже в интернете ответ, но на запрос с "функции" поисковик не понимает о каких функциях речь.
Кстати если в гугле в поисковике ввести функцию, например "cos(7 * x) + sin(x)" то рисуется график, я посмотрел код, там хоть и SVG но не совсем вектор, то есть кривая задана не через функцию.
Ниже написал пример, но там рисуется как у гугла отрезками линий. А мне бы хотелось чисто вектором задать линию через математическую функцию.
<html><head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>test</title>
<script type="text/javascript">
var f_draw_a_graph = function(){
	let from_x = document.getElementById("from_x").value*1;
	let to_x = document.getElementById("to_x").value*1;
	let from_y = document.getElementById("from_y").value*1;
	let to_y = document.getElementById("to_y").value*1;
	let step_map = document.getElementById("step_map").value*1;
	let width_svg = (to_x - from_x) * step_map;
	let height_svg = (to_y - from_y) * step_map;
	let math_f = document.getElementById("math_f").value;
	let distance_axis_y = height_svg + (from_y * step_map);
	let curve_d = "";
	for(let i = 0; i <= width_svg; i++){
		if(i == 0){
			let x = from_x;
			let y = eval(math_f);
			let y_d = distance_axis_y - y * step_map;
			curve_d = "M0,"+y_d+" ";
		}else{
			let x = from_x + i / step_map;
			let y = eval(math_f);
			let y_d = distance_axis_y - y * step_map;
*!*
			curve_d += "L"+i+","+y_d+" ";
*/!*
		}
	}
	svg_curve.setAttributeNS(null, "d", curve_d);
	svg.setAttributeNS(null, "width", width_svg);
	svg.setAttributeNS(null, "height", height_svg);
	let grid_d = "";
	if(from_x <= 0 && to_x >= 0){
		let distance_axis_x = Math.abs(from_x * step_map);
		grid_d += "M"+distance_axis_x+",0 v"+height_svg+" ";
		for(let i = 0; i <= (to_y - from_y); i++){
			grid_d += "M"+(distance_axis_x - 5)+","+(i * step_map)+" h10 ";
		}
	}
	if(from_y <= 0 && to_y >= 0){
		grid_d += "M0,"+distance_axis_y+" h"+width_svg+" ";
		for(let i = 0; i <= (to_x - from_x); i++){
			grid_d += "M"+(i * step_map)+","+(distance_axis_y - 5)+" v10 ";
		}
	}
	svg_grid.setAttributeNS(null, "d", grid_d);
}
var svgns = "http://www.w3.org/2000/svg";
var svg = null;
var svg_grid = null;
var svg_curve = null;
window.onload = function(){
	svg = document.getElementById('grafika');
	svg.style['background-color'] = "#002a00";
	svg_grid = document.createElementNS(svgns, "path");
	svg_grid.setAttributeNS(null, "fill", "none");
	svg_grid.setAttributeNS(null, "stroke", "#888");
	svg_grid.setAttributeNS(null, "stroke-width", 2);
	svg.appendChild(svg_grid);
	svg_curve = document.createElementNS(svgns, "path");
	svg_curve.setAttributeNS(null, "fill", "none");
	svg_curve.setAttributeNS(null, "stroke", "#f00");
	svg_curve.setAttributeNS(null, "stroke-width", 2);
	svg.appendChild(svg_curve);
	f_draw_a_graph();
}
</script>
</head>
<body>
	От: <input type="text" size="2" id="from_x" value="-5"> x До: <input type="text" size="2" id="to_x" value="5"> x Шаг: <input type="text" size="2" id="step_map" value="100"> в пикселях.
	<br>
	От: <input type="text" size="2" id="from_y" value="-4"> y До: <input type="text" size="2" id="to_y" value="4"> y
	<br>
	y = <input type="text" size="30" id="math_f" value="Math.cos(7 * x) + Math.sin(x)">  <input type="button" value="Нарисовать график" onClick="f_draw_a_graph()">
	<br>
	<svg xmlns="http://www.w3.org/2000/svg" id="grafika"></svg>
</body>
</html>

senex 02.01.2019 20:59

В SVG рисование кривых линий основано на теории кривых Безье. Указывают координаты начальной и конечной точки кривой, а кривизну задают контрольными точками (проще говоря, "ползунки") - одна для квадратичной кривой Безье или две - для кубической. То же самое в графических векторных редакторах CorelDraw и др.


Математические функции для построения кривых в SVG можно использовать, но не напрямую, а преобразуя их через яваскрипт в координаты для кривых Безье. Но это конечно немалый кусок работы. Думаю, начать следует с изучения теории кривых Безье. Спецификация w3org для создания кривых в SVG здесь

Например, поведение кривой Безье задается атрибутом "d" (в данном случае квадратичная кривая):
<path d="M200,300 Q400,50 600,300" />


где M200,300 - координаты начальной точки,
Q400,50 -координаты ползунка
600,300 -координаты конечной точки

В явасктипт преобразуем математическую функцию в значение этого атрибута и устанавливаем его:

svg_grid.setAttributeNS(null, "d", "M200,300 Q400,50 600,300");

RX200 02.01.2019 21:17

senex,
Этих кривых Безье недостаточно, хотя может как то и можно математические функции перевести в них, но я даже не представляю как, и скорее всего это будет для ЯваСкрипта еще более затратно чем как щас у меня, а щас у меня уже ЯваСкрипт немного притормаживает, ЯваСкрипт не предназначен чтоб через него каждый пиксель прописывать, для этого как мне кажется чтонить более низкоуровневое должно предоставить интерфейс ЯвеСкрипту, чтоб ЯваСкрипт ограничился написанием только самой математической функцией а не прорисовкой линии по ней.

senex 02.01.2019 21:32

Например, такой фреймворк для мат. функций для SVG

RX200 02.01.2019 21:50

senex,
Спасибо конечно за фреймворк, я его посмотрел, но там опять же ЯваСкрипт делает то чего он по идеи делать не должен, а должен делать SVG.


Часовой пояс GMT +3, время: 08:18.