使用HTML5绘制半球

时间:2018-05-19 15:48:59

标签: javascript html 3d

我是一名数学老师,试图在球体,半球和锥体的体积上创建一组随机生成的问题,我希望能够在半径,高度等标记的网页上呈现结果。 / p>

每当我尝试搜索任何涉及2D图形的内容时,我都会得到无数的结果,告诉我如何使用HTML Canvas轻松绘制内容,但在3D中我从搜索中得到的很少,除了一些提到WebGL有多难的内容是!

所以任何人都可以展示我如何能够轻松地生成半球,或者我最好使用像Geogebra这样的数学插件来做这样的事情吗?

目前在我的网站上我使用过jQuery,JavaScript,PHP和SQL。

2 个答案:

答案 0 :(得分:1)

你可以在画布上创建一些很酷的图形......
试试这个



var canvas,
  ctx,
  sphere = new Sphere3D(40),
  distance = 300, 
  mouse = {
    down: false,
    button: 1,
    x: 0,
    y: 0,
    px: 0,
    py: 0
  }, 
  modify = 1;

window.requestAnimFrame =
  window.requestAnimationFrame ||
  window.webkitRequestAnimationFrame ||
  window.mozRequestAnimationFrame ||
  window.oRequestAnimationFrame ||
  window.msRequestAnimationFrame ||
  function(callback) {
    window.setTimeout(callback, 1000 / 60);
  };

Number.prototype.clamp = function(min, max) {
  return Math.min(Math.max(this, min), max);
};

function Point3D() {
  this.x = 0;
  this.y = 0;
  this.z = 0;
}

function Sphere3D(radius) {
  this.point = new Array();
  this.color = "rgb(100,255,0)"
  this.radius = (typeof(radius) == "undefined") ? 20.0 : radius;
  this.radius = (typeof(radius) != "number") ? 20.0 : radius;

  this.numberOfVertexes = 0;

  for (alpha = 0; alpha <= 6.28; alpha += 0.17) {
    p = this.point[this.numberOfVertexes] = new Point3D();

    p.x = Math.cos(alpha) * this.radius;
    p.y = 0;
    p.z = Math.sin(alpha) * this.radius;
    this.numberOfVertexes++;
  }

  for (var direction = 1; direction >= -1; direction -= 2) {
    for (var beta = 0.19; beta < 1.445; beta += 0.17) {
      var radius = Math.cos(beta) * this.radius;
      var fixedY = Math.sin(beta) * this.radius * direction;

      for (var alpha = 0; alpha < 6.28; alpha += 0.17) {
        p = this.point[this.numberOfVertexes] = new Point3D();

        p.x = Math.cos(alpha) * radius;
        p.y = fixedY;
        p.z = Math.sin(alpha) * radius;

        this.numberOfVertexes++;
      }
    }
  }
}

function rotateX(point, radians) {
  var y = point.y;
  point.y = (y * Math.cos(radians)) + (point.z * Math.sin(radians) * -1.0);
  point.z = (y * Math.sin(radians)) + (point.z * Math.cos(radians));
}

function rotateY(point, radians) {
  var x = point.x;
  point.x = (x * Math.cos(radians)) + (point.z * Math.sin(radians) * -1.0);
  point.z = (x * Math.sin(radians)) + (point.z * Math.cos(radians));
}

function rotateZ(point, radians) {
  var x = point.x;
  point.x = (x * Math.cos(radians)) + (point.y * Math.sin(radians) * -1.0);
  point.y = (x * Math.sin(radians)) + (point.y * Math.cos(radians));
}

function drawPoint(ctx, x, y, size, color) {
  ctx.save();
  ctx.beginPath();
  ctx.fillStyle = color;
  ctx.arc(x, y, size, 0, 2 * Math.PI, true);
  ctx.fill();
  ctx.restore();
}

function drawPointWithGradient(ctx, x, y, size, gradient) {
  var reflection;

  reflection = size / 4;
  // 0 - 5
  var middle = canvas.width / 2;
  var a = mouse.y - middle;

  ctx.save();
  ctx.translate(x, y);
  /*var reflectionX = Math.max(Math.min((mouse.px - (canvas.width / 2)) / (canvas.width / 2) * 5, 4), -4);
  var reflectionY = Math.max(Math.min((mouse.py - (canvas.height / 2)) / (canvas.height / 2) * 5, 4), -4);
  var radgrad = ctx.createRadialGradient(reflectionX, reflectionY, 0.5, 0, 0, size);*/
  var radgrad = ctx.createRadialGradient(-reflection, -reflection, reflection, 0, 0, size);

  var r = 1, 
      g = 1, 
      b = 200;

  var color =  "rgb(" + r + "," + g + "," + b + ")";
  radgrad.addColorStop(0, '#FFFFFF');
  radgrad.addColorStop(gradient, color);
  radgrad.addColorStop(1, 'rgba(1,159,98,0)');

  ctx.fillStyle = radgrad;
  ctx.fillRect(-size, -size, size * 2, size * 2);
  ctx.restore();
}

function projection(xy, z, xyOffset, zOffset, distance) {
  return ((distance * xy) / (z - zOffset)) + xyOffset;
}

function update() {
  ctx.save();
  ctx.clearRect(0, 0, canvas.width, canvas.height);

  for (i = 0; i < sphere.numberOfVertexes; i++) {

    p.x = sphere.point[i].x;
    p.y = sphere.point[i].y;
    p.z = sphere.point[i].z;

    rotateX(p, Math.sin(+new Date / 360));
    rotateY(p, Math.cos(+new Date / 360));
    
    //if (mouse.down) {
      modify = Math.min(Math.abs(mouse.px - (canvas.width / 2)) / (canvas.width / 2) * 1.25, 1.25);
    //}
    //else if(modify > 1) {
    //  modify -= .0001;
    //}
    
    x = projection(p.x, p.z * modify, canvas.width / 2.0, 100.0, distance);
    y = projection(p.y, p.z * modify, canvas.height / 2.0, 100.0, distance);

    if ((x >= 0) && (x < canvas.width)) {
      if ((y >= 0) && (y < canvas.height)) {
        if (p.z < 0) {
          drawPoint(ctx, x, y, 1, "rgba(200,200,200,0.6)");
        } else {
          drawPointWithGradient(ctx, x, y, 5, 0.8);
        }
      }
    }
  }
  ctx.restore();

  requestAnimFrame(update);
}

function start() {
  
  canvas.onmousemove = function (e) {
    mouse.px  = mouse.x;
    mouse.py  = mouse.y;
    var rect  = canvas.getBoundingClientRect();
    mouse.x   = e.clientX - rect.left,
    mouse.y   = e.clientY - rect.top,

    e.preventDefault();
  };
  
  canvas.onmouseup = function (e) {
    mouse.down = false;
    e.preventDefault();
  };
  
  canvas.onmousedown = function (e) {
    mouse.down = true;
    e.preventDefault();
  };
  
  update();
}

window.onload = function() {

  canvas = document.getElementById('c');
  ctx = canvas.getContext('2d');
  canvas.width = 800;
  canvas.height = 600;

  start();
};
&#13;
html, 
body {
  background: #111;
  text-align: center;
}

canvas {
  margin: 0 auto;
  box-sizing: content-box;
}
&#13;
<canvas id="c"></canvas>
&#13;
&#13;
&#13;

答案 1 :(得分:0)

我认为这是我想要的3D效果(我想所有2D投影无论如何都是3D效果!)所以我认为我需要看一下它的径向渐变。这个example演示了一些非常简洁的圆圈,看起来像是球体,所以我认为这可能是一个很好的起点。