Не замыкать фигуры canvas js

230
19 ноября 2020, 20:40

Есть программа которая рисует параметрически заданную функцию,но в конце соединяет конечную точку с начальной(закрывает контур). Как от этого избавиться? График рисуется в функции RenderFunction.

<input type="text" id="a" onkeyup="Draw()"><br> 
<canvas id="canvasId" width="800"  height="800" onMouseUp="activate()" onMouseDown="activate()"></canvas> 
<script> 
	var zoom = 10; 
	var w1 = 0, w2 = 0; 
	function init() { 
		Draw(); 
	} 
 
	var Canvas = document.getElementById('canvasId');   
	var Ctx = null; 
 
	var Width = Canvas.width; 
	var Height = Canvas.height; 
 
	function MaxX() { 
		return zoom; 
	} 
 
	function MinX() { 
		return -zoom; 
	} 
 
	function MaxY() { 
		return MaxX() * Height / Width; 
	} 
 
	function MinY() { 
		return MinX() * Height / Width; 
	} 
 
	function XC(x) { 
		return (x - MinX()) / (MaxX() - MinX()) * Width - w1; 
	} 
 
	function YC(y) { 
		return Height - (y - MinY()) / (MaxY() - MinY()) * Height - w2; 
	} 
 
	var F2 = function(x) { 
	  return (((document.getElementById("a").value)*2)*(Math.cos(x)/Math.sin(x))); 
	}; 
 
	var F1 = function(x) { 
	  return ((document.getElementById("a").value)*(1-Math.cos(2*x))); 
	}; 
 
	function Draw() { 
		if (Canvas.getContext) { 
			Ctx = Canvas.getContext('2d'); 
			Ctx.clearRect(0,0,Width,Height); 
			DrawAxes(); 
			RenderFunction(F1, F2); 
		} 
	} 
 
 
	function XTickDelta() { 
		return 1; 
	} 
 
	function YTickDelta() { 
		return 1; 
	} 
 
	function DrawAxes() { 
		Ctx.strokeStyle="#000"; 
		Ctx.save(); 
		Ctx.lineWidth = 1; 
		Ctx.beginPath(); 
		Ctx.moveTo(XC(0),YC(0)); 
		Ctx.lineTo(XC(0),YC(MaxY())+w2); 
		Ctx.stroke(); 
		 
		var del = Math.floor(zoom / 10); 
 
		Ctx.beginPath(); 
		Ctx.moveTo(XC(0),YC(0)); 
		Ctx.lineTo(XC(0),YC(MinY())+w2); 
		Ctx.stroke(); 
		var delta = YTickDelta(); 
		var tt3 = Math.floor(-w2 / 10); 
		tt3 = (tt3 > 0) ? tt3 : 1; 
		for (var i = 1; (i * delta) < MaxY()+ tt3; ++i) {			//сетка 
			Ctx.beginPath(); 
			if(del < 2){ 
				Ctx.moveTo(XC(0) - Width/2 + w1,YC(i * delta)); 
				Ctx.lineTo(XC(0) + Width/2 + w1,YC(i * delta)); 
				//Ctx.fillText(i, XC(0)+2,YC(i * delta)-3); 
			}else if(del > 1 && i % del == 0){ 
				Ctx.moveTo(XC(0) - Width/2 + w1,YC(i * delta)); 
				Ctx.lineTo(XC(0) + Width/2 + w1,YC(i * delta)); 
				//Ctx.fillText(i, XC(0)+2,YC(i * delta)-3); 
			} 
			Ctx.stroke();   
		} 
 
		var delta = YTickDelta(); 
		var tt4 = Math.floor(-w2 / 10); 
		tt4 = (tt4 < 0) ? tt4 : -1; 
		for (var i = 1; (i * delta) > MinY()+ tt4; --i) {					//сетка 
			Ctx.beginPath(); 
			if(i == 0) Ctx.lineWidth = 3; else Ctx.lineWidth = 1; 
			if(del < 2){ 
				Ctx.moveTo(XC(0) - Width/2 + w1,YC(i * delta)); 
				Ctx.lineTo(XC(0) + Width/2 + w1,YC(i * delta)); 
				//Ctx.fillText(i, XC(0)+2,YC(i * delta)-3); 
			}else if(del > 1 && i % del == 0){ 
				Ctx.moveTo(XC(0) - Width/2 + w1,YC(i * delta)); 
				Ctx.lineTo(XC(0) + Width/2 + w1,YC(i * delta)); 
				//Ctx.fillText(i, XC(0)+2,YC(i * delta)-3); 
			} 
			Ctx.stroke();   
		}   
		 
		Ctx.beginPath(); 
		Ctx.moveTo(XC(0),YC(0)); 
		Ctx.lineTo(XC(MaxX())+w1,YC(0)); 
		Ctx.stroke(); 
		 
		Ctx.beginPath(); 
		Ctx.moveTo(XC(0),YC(0)); 
		Ctx.lineTo(XC(MinX())+w1,YC(0)); 
		Ctx.stroke(); 
		 
		var delta = XTickDelta(); 
		var tt1 = Math.floor(w1 / 10); 
		tt1 = (tt1 > 0) ? tt1 : 1; 
		for (var i = 1; (i * delta) < MaxX() + tt1; ++i) {					//сетка 
			Ctx.beginPath(); 
			if(del < 2){ 
				Ctx.moveTo(XC(i * delta),YC(0)-Height/2 + w2); 
				Ctx.lineTo(XC(i * delta),YC(0)+Height/2 + w2); 
				//Ctx.fillText(i, XC(i * delta)+2,YC(0)-3); 
			}else if(del > 1 && i % del == 0){ 
				Ctx.moveTo(XC(i * delta),YC(0)-Height/2 + w2); 
				Ctx.lineTo(XC(i * delta),YC(0)+Height/2 + w2); 
				//Ctx.fillText(i, XC(i * delta)+2,YC(0)-3); 
			} 
			Ctx.stroke();   
		} 
 
		var delta = XTickDelta(); 
		var tt2 = Math.floor(w1 / 10); 
		tt2 = (tt2 < 0) ? tt2 : -1; 
		for (var i = 1; (i * delta) > MinX()+ tt2; --i) {						//сетка 
			Ctx.beginPath(); 
			if(i == 0) Ctx.lineWidth = 3; else Ctx.lineWidth = 1; 
			if(del < 2){ 
				Ctx.moveTo(XC(i * delta),YC(0)-Height/2 + w2); 
				Ctx.lineTo(XC(i * delta),YC(0)+Height/2 + w2); 
				//Ctx.fillText(i, XC(i * delta)+2,YC(0)-3); 
			}else if(del > 1 && i % del == 0){ 
				Ctx.moveTo(XC(i * delta),YC(0)-Height/2 + w2); 
				Ctx.lineTo(XC(i * delta),YC(0)+Height/2 + w2); 
				//Ctx.fillText(i, XC(i * delta)+2,YC(0)-3); 
			} 
			Ctx.stroke();   
		} 
		Ctx.restore(); 
	} 
 
 
	var XSTEP = (MaxX()-MinX())/Width; 
 
	function RenderFunction(f1, f2){ 
		var first = true; 
		Ctx.beginPath(); 
		Ctx.strokeStyle="#FF0000"; 
		for (var z = MinX(); z <= MaxX(); z += XSTEP){ 
			var y = f1(Math.abs(z)); 
			var x = f2(Math.abs(z)); 
 
			if (first){ 
				Ctx.moveTo(XC(x),YC(y)); 
				first = false; 
			}else{ 
				Ctx.lineTo(XC(x),YC(y)); 
			} 
		} 
		Ctx.stroke(); 
	} 
 
	Canvas.addEventListener("wheel", onWheel); 
	function onWheel(e) { 
		e = e || window.event; 
		var delta = e.deltaY || e.detail || e.wheelDelta; 
		zoom += (-delta > 0 && zoom > 1) ? -1 : 1; 
		Draw(); 
	} 
	 
	var activ=false; 
	function activate() { 
		activ=!activ; 
	} 
	Canvas.addEventListener("mousemove", function(e){ 
		if(activ) { 
			w1 -= e.movementX; 
			w2 -= e.movementY; 
			Draw(); 
		} 
	}); 
	 
</script>

Answer 1

Потому что вы не функцию рисуете, посмотрите на массив точек, который рисуется в вашем примере выведя его лог.

Вот что получается если точки отсортировать:

init()
<input id="a" value="2"/><br> 
<canvas id="canvasId"></canvas> 
 
<script> 
var zoom = 10; 
var w1 = 0, w2 = 0; 
function init() { 
    Draw(); 
} 
 
var Canvas = document.getElementById('canvasId');   
var Ctx = null; 
 
var Width = Canvas.width; 
var Height = Canvas.height; 
 
function MaxX() { 
    return zoom; 
} 
 
function MinX() { 
    return -zoom; 
} 
 
function MaxY() { 
    return MaxX() * Height / Width; 
} 
 
function MinY() { 
    return MinX() * Height / Width; 
} 
 
function XC(x) { 
    return (x - MinX()) / (MaxX() - MinX()) * Width - w1; 
} 
 
function YC(y) { 
    return Height - (y - MinY()) / (MaxY() - MinY()) * Height - w2; 
} 
 
var F2 = function(x) { 
  return (((document.getElementById("a").value)*2)*(Math.cos(x)/Math.sin(x))); 
}; 
 
var F1 = function(x) { 
  return ((document.getElementById("a").value)*(1-Math.cos(2*x))); 
}; 
 
function Draw() { 
    if (Canvas.getContext) { 
        Ctx = Canvas.getContext('2d'); 
        Ctx.clearRect(0,0,Width,Height); 
        DrawAxes(); 
        RenderFunction(F1, F2); 
    } 
} 
 
 
function XTickDelta() { 
    return 1; 
} 
 
function YTickDelta() { 
    return 1; 
} 
 
function DrawAxes() { 
    Ctx.strokeStyle="#000"; 
    Ctx.save(); 
    Ctx.lineWidth = 1; 
    Ctx.beginPath(); 
    Ctx.moveTo(XC(0),YC(0)); 
    Ctx.lineTo(XC(0),YC(MaxY())+w2); 
    Ctx.stroke(); 
 
    var del = Math.floor(zoom / 10); 
 
    Ctx.beginPath(); 
    Ctx.moveTo(XC(0),YC(0)); 
    Ctx.lineTo(XC(0),YC(MinY())+w2); 
    Ctx.stroke(); 
    var delta = YTickDelta(); 
    var tt3 = Math.floor(-w2 / 10); 
    tt3 = (tt3 > 0) ? tt3 : 1; 
    for (var i = 1; (i * delta) < MaxY()+ tt3; ++i) {           //сетка 
        Ctx.beginPath(); 
        if(del < 2){ 
            Ctx.moveTo(XC(0) - Width/2 + w1,YC(i * delta)); 
            Ctx.lineTo(XC(0) + Width/2 + w1,YC(i * delta)); 
            //Ctx.fillText(i, XC(0)+2,YC(i * delta)-3); 
        }else if(del > 1 && i % del == 0){ 
            Ctx.moveTo(XC(0) - Width/2 + w1,YC(i * delta)); 
            Ctx.lineTo(XC(0) + Width/2 + w1,YC(i * delta)); 
            //Ctx.fillText(i, XC(0)+2,YC(i * delta)-3); 
        } 
        Ctx.stroke();   
    } 
 
    var delta = YTickDelta(); 
    var tt4 = Math.floor(-w2 / 10); 
    tt4 = (tt4 < 0) ? tt4 : -1; 
    for (var i = 1; (i * delta) > MinY()+ tt4; --i) {                   //сетка 
        Ctx.beginPath(); 
        if(i == 0) Ctx.lineWidth = 3; else Ctx.lineWidth = 1; 
        if(del < 2){ 
            Ctx.moveTo(XC(0) - Width/2 + w1,YC(i * delta)); 
            Ctx.lineTo(XC(0) + Width/2 + w1,YC(i * delta)); 
            //Ctx.fillText(i, XC(0)+2,YC(i * delta)-3); 
        }else if(del > 1 && i % del == 0){ 
            Ctx.moveTo(XC(0) - Width/2 + w1,YC(i * delta)); 
            Ctx.lineTo(XC(0) + Width/2 + w1,YC(i * delta)); 
            //Ctx.fillText(i, XC(0)+2,YC(i * delta)-3); 
        } 
        Ctx.stroke();   
    }   
 
    Ctx.beginPath(); 
    Ctx.moveTo(XC(0),YC(0)); 
    Ctx.lineTo(XC(MaxX())+w1,YC(0)); 
    Ctx.stroke(); 
 
    Ctx.beginPath(); 
    Ctx.moveTo(XC(0),YC(0)); 
    Ctx.lineTo(XC(MinX())+w1,YC(0)); 
    Ctx.stroke(); 
 
    var delta = XTickDelta(); 
    var tt1 = Math.floor(w1 / 10); 
    tt1 = (tt1 > 0) ? tt1 : 1; 
    for (var i = 1; (i * delta) < MaxX() + tt1; ++i) {                  //сетка 
        Ctx.beginPath(); 
        if(del < 2){ 
            Ctx.moveTo(XC(i * delta),YC(0)-Height/2 + w2); 
            Ctx.lineTo(XC(i * delta),YC(0)+Height/2 + w2); 
            //Ctx.fillText(i, XC(i * delta)+2,YC(0)-3); 
        }else if(del > 1 && i % del == 0){ 
            Ctx.moveTo(XC(i * delta),YC(0)-Height/2 + w2); 
            Ctx.lineTo(XC(i * delta),YC(0)+Height/2 + w2); 
            //Ctx.fillText(i, XC(i * delta)+2,YC(0)-3); 
        } 
        Ctx.stroke();  
  
    } 
 
    var delta = XTickDelta(); 
    var tt2 = Math.floor(w1 / 10); 
    tt2 = (tt2 < 0) ? tt2 : -1; 
    for (var i = 1; (i * delta) > MinX()+ tt2; --i) {                       //сетка 
        Ctx.beginPath(); 
        if(i == 0) Ctx.lineWidth = 3; else Ctx.lineWidth = 1; 
        if(del < 2){ 
            Ctx.moveTo(XC(i * delta),YC(0)-Height/2 + w2); 
            Ctx.lineTo(XC(i * delta),YC(0)+Height/2 + w2); 
            //Ctx.fillText(i, XC(i * delta)+2,YC(0)-3); 
        }else if(del > 1 && i % del == 0){ 
            Ctx.moveTo(XC(i * delta),YC(0)-Height/2 + w2); 
            Ctx.lineTo(XC(i * delta),YC(0)+Height/2 + w2); 
            //Ctx.fillText(i, XC(i * delta)+2,YC(0)-3); 
        } 
        Ctx.stroke();   
    } 
    Ctx.restore(); 
} 
 
 
var XSTEP = (MaxX()-MinX())/Width; 
 
function RenderFunction(f1, f2){ 
    let pts = []; 
    for (var z = MinX(); z <= MaxX(); z += XSTEP) 
        pts.push([XC( f2(Math.abs(z))),YC(f1(Math.abs(z)))]) 
    Ctx.beginPath(); 
    Ctx.strokeStyle="#FF0000"; 
    pts = pts.sort((a,b) => a[0]-b[0]).forEach((e,i) => { 
      Ctx[i?'lineTo':'moveTo'](e[0], e[1]); 
    }); 
    Ctx.stroke(); 
} 
 
Canvas.addEventListener("wheel", onWheel); 
function onWheel(e) { 
    e = e || window.event; 
    var delta = e.deltaY || e.detail || e.wheelDelta; 
    zoom += (-delta > 0 && zoom > 1) ? -1 : 1; 
    Draw(); 
} 
 
var activ=false; 
function activate() { 
    activ=!activ; 
} 
Canvas.addEventListener("mousemove", function(e){ 
    if(activ) { 
        w1 -= e.movementX; 
        w2 -= e.movementY; 
        Draw(); 
    } 
}); 
 
</script>

READ ALSO
Вопрос по api инстаграма

Вопрос по api инстаграма

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

250
обойти overflow hidden [закрыт]

обойти overflow hidden [закрыт]

Хотите улучшить этот вопрос? Обновите вопрос так, чтобы он вписывался в тематику Stack Overflow на русском

162
Как сделать скроллинг для блоков не выходил за рамки границы?

Как сделать скроллинг для блоков не выходил за рамки границы?

У меня есть комнаты с классом chat-list_rooms и список сообщений с классом chat-messageМне нужно, чтобы при превышение body

139
Выравнивание полей структуры

Выравнивание полей структуры

Прочитал ответ на этот вопрос, где говорилось о выравнивании полей структуры и загорелся идеей пересчитать размер такой структуры:

127