Есть программа которая рисует параметрически заданную функцию,но в конце соединяет конечную точку с начальной(закрывает контур). Как от этого избавиться? График рисуется в функции 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>
Потому что вы не функцию рисуете, посмотрите на массив точек, который рисуется в вашем примере выведя его лог.
Вот что получается если точки отсортировать:
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>
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Мне нужно достать из апи локацию, но так чтобы если ее не указано, то оставлять место под локацию пустымКогда формирую цикл, то получается...
Хотите улучшить этот вопрос? Обновите вопрос так, чтобы он вписывался в тематику Stack Overflow на русском
У меня есть комнаты с классом chat-list_rooms и список сообщений с классом chat-messageМне нужно, чтобы при превышение body
Прочитал ответ на этот вопрос, где говорилось о выравнивании полей структуры и загорелся идеей пересчитать размер такой структуры: