Почему в jsxgraph параболу не проводят через пять точек на одной плоскости? - PullRequest
0 голосов
/ 24 мая 2019

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

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

В моем коде ниже, функция конструктора PPoint создает объекты, которые имеют соответствующие атрибуты pcoord , который является геометрическим объектом типа "точка", созданным с использованием собственного конструктора jsxgraph для точки. pcoord назначается при вызове метода draw для рисования точек I_1-I-4 и p_1.

В последних строках кода параболу следует рисовать, ссылаясь на pcoord s объектов I_1-I_4 и p_1, но по какой-то причине парабола не рисуется.

Как это можно исправить? Ссылка на jsfiddle . Код выполняется без уведомлений об ошибках при отладке.

HTML

<div id="jxgbox" class="jxgbox" style="width:500px; height:500px">
</div>

JS

const board = JXG.JSXGraph.initBoard('jxgbox', {
  boundingbox: [-10, 10, 10, -10],
  axis: true,
  showCopyright: true,
  showNavigation: true,
  pan: false,
  grid: false,

  zoom: {
    factorX: 1.25,
    factorY: 1.25,
    wheel: false
  }
});

//create z axis
var zAxis = board.create('axis', [
  [0, 0],
  [-1, -1]
], {
  ticks: {
    majorHeight: 10,
    drawLabels: false
  }
});

//create direction of view for projections
var cam = [4, 4, 30]; // [x,y,z]
var r = 6.0;
var origin = [0, 0, 0];

// Function for parallel projection
var project = function(crd, cam) {
  var d = -crd[2] / cam[2];
  return [1, crd[0] + d * cam[0], crd[1] + d * cam[1]];
};

//create slider for rotating the parabola
var sRadius = board.create('slider', [
  [1, -8.5],
  [6, -8.5],
  [-10, 0, 10]
], {
  name: 'angle',
  needsRegularUpdate: true
  //snapWidth: 1
});

//create slider for adjusting the angular speed
var sOmega = board.create('slider', [
  [1, -7.5],
  [6, -7.5],
  [0, 0, 10]
], {
  name: 'Omega',
  needsRegularUpdate: true
  //snapWidth: 1,
});

//fix parameters
const g = 9.81 //gravitational acceleration
const h0 = 5 //initial height of the water surface

//define radius from the y-axis for I3 and I4
const R34 = Math.sqrt(2);


// Function for parallel projection
var project = function(crd, cam) {
  var d = -crd[2] / cam[2];
  return [1, crd[0] + d * cam[0], crd[1] + d * cam[1]];
};


//function creates points for drawing conic sections
function PPoint(radius, sign, namep, fixval) {
  this.R = radius;
  this.S = sign;
  this.Namep = namep;
  this.Fixval = fixval;
  this.pcoord = undefined; //Cartesian coordinates of the point, stored as a point
}

//method for drawing each Point
PPoint.prototype.draw = function(pp) {
  board.create('point', [function() {
    var K1 = sOmega.Value() * sOmega.Value() / g,
      KK = 1 / 4 * sOmega.Value() * sOmega.Value() / g,
      v = sRadius.Value() * Math.PI * 0.5 / 10.0,
      c = [pp.S * pp.R * Math.sin(v), K1 / 2 * pp.R * pp.R - KK + h0, pp.S * pp.R * Math.cos(v)];
    //store the dynamically assigned coordinates of the point for drawing the parabola
    pp.pcoord = board.create('point', [function() {
      return project(c, cam);
    }], {
        visible: false
        }); //end storing pp.coord
    return project(c, cam);
  }], {
    fixed: this.Fixval,
    name: this.Namep,
    visible: true
  })
}


//create and draw points
var p_1 = new PPoint(0, -1, 'p_1', 'false');
var I_1 = new PPoint(r, 1, 'I_1', 'false');
var I_2 = new PPoint(r, -1, 'I_2', 'false');
var I_3 = new PPoint(R34, 1, 'I_3', 'false');
var I_4 = new PPoint(R34, -1, 'I_4', 'false');
p_1.draw(p_1)
I_1.draw(I_1)
I_2.draw(I_2)
I_3.draw(I_3)
I_4.draw(I_4)



//draw the rotating parabola
var prbl = board.create('conic', [I_1.pcoord, I_2.pcoord, I_3.pcoord, I_4.pcoord, p_1.pcoord], {
  strokeColor: '#CA7291',
  strokeWidth: 2,
  trace :true
});

//debugger

1 Ответ

1 голос
/ 25 мая 2019

Есть два вопроса с этим кодом:

1) В PPoint.draw ссылка на две точки JSXGraph не работает: при каждом обновлении создается новая точка JSXGraph. Это делает код медленным и, более того, не влияет на начальные точки, поставляемые в коническую часть. Я бы предложил изменить draw на это:

PPoint.prototype.draw = function(pp) {
  pp.pcoord = board.create('point', [function() {
    var K1 = sOmega.Value() * sOmega.Value() / g,
      KK = 1 / 4 * sOmega.Value() * sOmega.Value() / g,
      v = sRadius.Value() * Math.PI * 0.5 / 10.0,
      c = [pp.S * pp.R * Math.sin(v), 
           K1 / 2 * pp.R * pp.R - KK + h0, 
           pp.S * pp.R * Math.cos(v)];
      return project(c, cam);
  }], {
    fixed: this.Fixval,
    name: this.Namep,
    visible: true});

2) Вторая проблема заключается в том, что JSXGraph не может вывести вырожденные коники через пять точек и страдает от точности, если коника близка к вырождению (существуют общие проблемы с общими параболами). Это случай здесь для начального значения omega = 0.

Вот рабочий пример: https://jsfiddle.net/L2d4zt8q/

...