How to Draw line in 3D rectangle based on x,y and z?

前端 未结 3 1133
天命终不由人
天命终不由人 2021-02-11 08:04

\"enter

I would like draw 3D points represented in image to 3D rectangle. Any idea how co

相关标签:
3条回答
  • 2021-02-11 08:26

    Okay. Let's look at a simple example of what you are trying to accomplish it, and why this is such a complicated problem.

    First, lets look a some projection functions. You need a way to mathematically describe how to transform a 3D (or higher dimensional) point into a 2D space (your monitor), or a projection.

    The simpiest to understand is a very simple dimetric projection. Something like:

    x' = x + z/2;
    y' = y + z/4;
    

    What does this mean? Well, x' is you x coordinate 2D projection: for every unit you move backwards in space, the projection will move that point half that many units to the right. And y' represents that same projection for your y coordinate: for every unit you move backwards in space, the projection will move that point a quarter unit up.

    So a point at [0,0,0] will get projected to a 2d point of [0,0]. A point at [0,0,4] will get projected to a 2d point of [2,1].

    Implemented in JavaScript, it would look something like this:

    // Dimetric projection functions
    var dimetricTx = function(x,y,z) { return x + z/2; };
    var dimetricTy = function(x,y,z) { return y + z/4; };
    

    Once you have these projection functions -- or ways to translate from 3D space into 2D space -- you can use them to start draw your image. A simple example of that using js canvas. First, some context stuff:

    var c = document.getElementById("cnvs");
    var ctx = c.getContext("2d");
    

    Now, lets make a little helper to draw a 3D point:

      var drawPoint = (function(ctx,tx,ty, size) {
        return function(p) {
          size = size || 3;
    
          // Draw "point"
          ctx.save();
          ctx.fillStyle="#f00";
          ctx.translate(tx.apply(undefined, p), ty.apply(undefined,p));
          ctx.beginPath();
          ctx.arc(0,0,size,0,Math.PI*2);
          ctx.fill();
          ctx.restore();
        };
      })(ctx,dimetricTx,dimetricTy);
    

    This is pretty simple function, we are injecting the canvas context as ctx, as well as our tx and ty functions, which in this case our the dimetric functions we saw earlier.

    And now a polygon drawer:

      var drawPoly = (function(ctx,tx,ty) {
        return function() {
          var args = Array.prototype.slice.call(arguments, 0);
    
          // Begin the path
          ctx.beginPath();
    
          // Move to the first point
          var p = args.pop();
          if(p) {
            ctx.moveTo(tx.apply(undefined, p), ty.apply(undefined, p));
          }
    
          // Draw to the next point
          while((p = args.pop()) !== undefined) {
            ctx.lineTo(tx.apply(undefined, p), ty.apply(undefined, p));
          }
    
          ctx.closePath();
          ctx.stroke();
    
        };
      })(ctx, dimetricTx, dimetricTy);
    

    With those two functions, you could effectively draw the kind of graph you are looking for. For example:

    // The array of points
    var points = [
      // [x,y,z]
      [20,30,40],
      [100,70,110],
      [30,30,75]
    ];
    
    (function(width, height, depth, points) {
      var c = document.getElementById("cnvs");
      var ctx = c.getContext("2d");
    
      // Set some context
      ctx.save();
      ctx.scale(1,-1);
      ctx.translate(0,-c.height);
    
      ctx.save();
    
      // Move our graph
      ctx.translate(100,20);  
    
      // Draw the "container"
      ctx.strokeStyle="#999";
      drawPoly([0,0,depth],[0,height,depth],[width,height,depth],[width,0,depth]);
    
      drawPoly([0,0,0],[0,0,depth],[0,height,depth],[0,height,0]);
      drawPoly([width,0,0],[width,0,depth],[width,height,depth],[width,height,0]);
      drawPoly([0,0,0],[0,height,0],[width,height,0],[width,0,0]);
      ctx.stroke();
    
      // Draw the points
      for(var i=0;i<points.length;i++) {
        drawPoint(points[i]);
      }
    
    })(150,100,150,points);
    

    However, you should now be able to start to see some of the complexity of your actual question emerge. Namely, you asked about rotation, in this example we are using an extremely simple projection (our dimetric projection) which doesn't take much other than an oversimplified relationship between depth and its influences on x,y position. As the projections become more complex, you need to know more about your relationship/orientation in 3D space in order to create a reasonable 2D projection.

    A working example of the above code can be found here. The example also includes isometric projection functions that can be swapped out for the dimetric ones to see how that changes the way the graph looks. It also does some different visualization stuff that I didn't include here, like drawing "shadows" to help "visualize" the actual orientation -- the limitations of 3D to 2D projections.

    It's complicated, and even a superficial discussion is kind of beyond the scope of this stackoverflow. I recommend you read more into the mathematics behind 3D, there are plenty of resources, both online and in print form. Once you have a more solid understanding of the basics of how the math works then return here if you have a specific implementation question about it.

    0 讨论(0)
  • 2021-02-11 08:31

    How to Draw 3D Rectangle? posted in: Parallelogram | updated on: 14 Sep, 2012

    To sketch 3 - Dimensional Rectangle means we are dealing with the figures which are different from 2 – D figures, which would need 3 axes to represent them. So, how to draw 3D rectangle?

    To start with, first make two lines, one vertical and another horizontal in the middle of the paper such that they represent a “t” letter of English. This is what we need to draw for temporary use and will be removed later after the construction of the 3 – D rectangle is complete. Next we draw a Square whose measure of each side is 1 inch. Square must be perfect in Geometry so that 90 degree angles that are formed at respective corners are exact in measure. Now starting from upper right corner of the square we draw a line segment that will be stretched to a measure of 2 inches in the direction at an angle of 45 degrees. Similarly, we repeat the procedure by drawing another Line Segment from the upper left corner of the square and stretching it to 2 inches length in the direction at an angle of 45 degrees. These 2 line segments are considered to be the diagonals with respect to the horizontal line that we drew temporarily in starting. Also these lines will be parallel to each other. Next we draw a line that joins the end Point of these two diagonals.

    Next starting from the very right of the 2 inch diagonal end point, draw a line of measure 1 inch that is supposed to be perpendicular to the temporary horizontal line. Next we need to join the lower left corner of the square with end point of the last 1’’ line we drew in 4th step and finally we get our 3 - D rectangular. Now we can erase our initial “t”. This 3- D rectangle resembles a Cuboid.

    0 讨论(0)
  • 2021-02-11 08:32

    What you want to do is impossible to do using the method you've stated - this is because a box - when rotated in 3 dimensions won't look anything like that diagram of yours. It will also vary based on the type of projection you need. You can, however get started using three.js which is a 3D drawing library for Javascript.

    Hope this helps.

    0 讨论(0)
提交回复
热议问题