I would like draw 3D points represented in image to 3D rectangle. Any idea how co
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
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.