matlab如何绘制伪彩色
Pane for drawing in pseudo 3D Today we are going to go back to the practical lessons for html5. I think we have already done a good break in our lessons. In this tutorial I will show you how to create a pane for drawing which is spinning on its axis (on html5 canvas object). Each of your drawn shape will be spinning in pseudo 3D mode. Two objects (prototypes) are defined here: Point and Shape (each shape consists of multiple points). The main idea – to project and be rotated points of figures, as well as to draw a curved line between these points.
用于绘制伪3D的窗格今天,我们将回到html5的实际课程。 我认为我们已经在课程中取得了不错的成绩。 在本教程中,我将向您展示如何创建一个在其轴上旋转的绘图窗格(在html5 canvas对象上)。 您绘制的每个形状都将以伪3D模式旋转。 此处定义了两个对象(原型):点和形状(每个形状由多个点组成)。 主要思想是投影和旋转图形的点,并在这些点之间绘制曲线。
现场演示
[sociallocker]
[社交储物柜]
打包下载
[/sociallocker]
[/ sociallocker]
Now we can download the source package, unpack it, and start looking at the code
现在我们可以下载源代码包,将其解压缩,然后开始查看代码
(Step 1. HTML)
In the first step we have to prepare some basic html code:
第一步,我们必须准备一些基本的html代码:
(index.html)
<!-- add scripts -->
<script src="js/pointer.js"></script>
<script src="js/main.js"></script>
....
<canvas id="scene" height="600" width="800" tabindex="1"></canvas>
<!-- add scripts -->
<script src="js/pointer.js"></script>
<script src="js/main.js"></script>
....
<canvas id="scene" height="600" width="800" tabindex="1"></canvas>
As usual, we include scripts in the header section of the document, but, in our case, it doesn’t actually matter where it is exactly. Our JS code will be executed only when the document will be downloaded
像往常一样,我们在文档的标题部分中包含脚本,但就我们而言,确切位置实际上并不重要。 仅当文档下载后,我们的JS代码才会执行
(Step 2. JS (HTML5))
As usual, in the beginning of every JS code, we can define several global variables:
像往常一样,在每个JS代码的开头,我们可以定义几个全局变量:
(js/main.js)
// Variables
var canvas, ctx; // canvas and context objects
var vPointer; // draw pointer pbject
var aShapes = []; // shapes array
var iLMx = iLMy = 0; // last pointer positions
var vActShape; // active shape object
// Variables
var canvas, ctx; // canvas and context objects
var vPointer; // draw pointer pbject
var aShapes = []; // shapes array
var iLMx = iLMy = 0; // last pointer positions
var vActShape; // active shape object
Now, we can introduce our first low level object – Point:
现在,我们可以介绍我们的第一个低级对象–点:
// Point object
var Point = function (x, y, z) {
this.x = x;
this.y = y;
this.z = z;
this.x0 = x;
this.z0 = z;
this.xp = 0;
this.yp = 0;
this.zp = 0;
this.fov = 2000;
}
Point.prototype.project = function () {
this.zp = this.fov / (this.fov + this.z);
this.xp = this.x * this.zp;
this.yp = this.y * this.zp;
}
Point.prototype.rotate = function (ax, ay) {
this.x = parseInt(Math.round(this.x0 * ax + this.z0 * ay));
this.z = parseInt(Math.round(this.x0 * -ay + this.z0 * ax));
}
// Point object
var Point = function (x, y, z) {
this.x = x;
this.y = y;
this.z = z;
this.x0 = x;
this.z0 = z;
this.xp = 0;
this.yp = 0;
this.zp = 0;
this.fov = 2000;
}
Point.prototype.project = function () {
this.zp = this.fov / (this.fov + this.z);
this.xp = this.x * this.zp;
this.yp = this.y * this.zp;
}
Point.prototype.rotate = function (ax, ay) {
this.x = parseInt(Math.round(this.x0 * ax + this.z0 * ay));
this.z = parseInt(Math.round(this.x0 * -ay + this.z0 * ax));
}
For an object ‘Point’ we have a whole set of internal properties and only two functions: project and rotate. Another object ‘Shape’ is a more complex object:
对于对象“点”,我们具有一整套内部属性,只有两个功能:投影和旋转。 另一个对象“形状”是一个更复杂的对象:
// Shape object
var Shape = function () {
this.angle = 0;
this.color = '#000';
this.halfheight = canvas.height / 2;
this.halfwidth = canvas.width / 2;
this.len = 0;
this.points = [];
return this;
}
// Add point to shape
Shape.prototype.addPoint = function (x, y, z) {
this.points.push(
new Point(Math.round(x), Math.round(y), Math.round(z))
);
this.len++;
}
// Rotate shape
Shape.prototype.rotate = function () {
this.angle += Math.PI / 180; // offset by 1 degree (radians in one degrees)
var ax = Math.cos(this.angle);
var ay = Math.sin(this.angle);
// Rotate all the points of the shape object
for (var i = 0; i < this.len; i++) {
this.points[i].rotate(ax, ay);
}
}
Shape.prototype.draw = function () {
// points projection
for (var i = 0; i < this.len; i++) {
this.points[i].project();
}
// draw a curved line between points
var p0 = this.points[0];
ctx.beginPath();
ctx.moveTo(p0.xp + this.halfwidth, p0.yp + this.halfheight);
for (var i = 1, pl = this.points.length; i < pl; i++) {
var apnt = this.points[i];
var xc = (p0.xp + apnt.xp) / 2;
var yc = (p0.yp + apnt.yp) / 2;
ctx.quadraticCurveTo(p0.xp + this.halfwidth, p0.yp + this.halfheight, xc + this.halfwidth, yc + this.halfheight);
p0 = apnt;
}
// stroke properties
ctx.lineWidth = 8;
ctx.strokeStyle = this.color;
ctx.lineCap = 'round'; // rounded end caps
ctx.stroke();
}
// Shape object
var Shape = function () {
this.angle = 0;
this.color = '#000';
this.halfheight = canvas.height / 2;
this.halfwidth = canvas.width / 2;
this.len = 0;
this.points = [];
return this;
}
// Add point to shape
Shape.prototype.addPoint = function (x, y, z) {
this.points.push(
new Point(Math.round(x), Math.round(y), Math.round(z))
);
this.len++;
}
// Rotate shape
Shape.prototype.rotate = function () {
this.angle += Math.PI / 180; // offset by 1 degree (radians in one degrees)
var ax = Math.cos(this.angle);
var ay = Math.sin(this.angle);
// Rotate all the points of the shape object
for (var i = 0; i < this.len; i++) {
this.points[i].rotate(ax, ay);
}
}
Shape.prototype.draw = function () {
// points projection
for (var i = 0; i < this.len; i++) {
this.points[i].project();
}
// draw a curved line between points
var p0 = this.points[0];
ctx.beginPath();
ctx.moveTo(p0.xp + this.halfwidth, p0.yp + this.halfheight);
for (var i = 1, pl = this.points.length; i < pl; i++) {
var apnt = this.points[i];
var xc = (p0.xp + apnt.xp) / 2;
var yc = (p0.yp + apnt.yp) / 2;
ctx.quadraticCurveTo(p0.xp + this.halfwidth, p0.yp + this.halfheight, xc + this.halfwidth, yc + this.halfheight);
p0 = apnt;
}
// stroke properties
ctx.lineWidth = 8;
ctx.strokeStyle = this.color;
ctx.lineCap = 'round'; // rounded end caps
ctx.stroke();
}
It has less params, but more functions (addPoint, rotate and draw). Now, we can start adding few main scene functions: main scene (canvas) initialization (sceneInit), rendering function (drawScene) and random color generator (getRandomColor):
它具有更少的参数,但是具有更多的功能(addPoint,rotate和draw)。 现在,我们可以开始添加一些主要场景功能:主要场景(画布)初始化(sceneInit),渲染功能(drawScene)和随机颜色生成器(getRandomColor):
// Get random color
function getRandomColor() {
var letters = '0123456789ABCDEF'.split('');
var color = '#';
for (var i = 0; i < 6; i++ ) {
color += letters[Math.round(Math.random() * 15)];
}
return color;
}
// Draw main scene function
function drawScene() {
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height); // Clear canvas
if (vPointer.bDown) { // on mouse down
var iDx = iLMx - vPointer.X;
var iDy = iLMy - vPointer.Y;
var dif = Math.sqrt(iDx * iDx + iDy * iDy); // difference between two last points
if (dif > 5) {
if (! vActShape) {
aShapes.push( // prepare a new shape object
vActShape = new Shape()
);
vActShape.color = getRandomColor();
}
iLMx = vPointer.X;
iLMy = vPointer.Y;
vActShape.addPoint(vPointer.X - canvas.width * 0.5, vPointer.Y - canvas.height * 0.5, 0);
}
} else {
// Once mouse is released - cleanup
if (vActShape) {
vActShape = '';
iLMx = iLMy = 0;
}
// Rotate the shapes
aShapes.forEach(function(sh) {
sh.rotate();
});
}
// Draw all shapes
aShapes.forEach(function(sh) {
sh.draw();
});
}
// Initialization
function sceneInit() {
// Prepare canvas and context objects
canvas = document.getElementById('scene');
// Canvas resize
canvas.width = canvas.clientWidth;
canvas.height = window.innerHeight;
ctx = canvas.getContext('2d');
// Add two custom shapes
var oShape = new Shape();
oShape.addPoint(-200,-200,50);
oShape.addPoint(0,0,0);
oShape.addPoint(-400,200,0);
oShape.addPoint(200,-400,-50);
aShapes.push(oShape);
var oShape2 = new Shape();
oShape2.addPoint(200,200,-50);
oShape2.addPoint(0,0,0);
oShape2.addPoint(400,-200,0);
oShape2.addPoint(-200,400,50);
aShapes.push(oShape2);
// Mouse pointer event handler
vPointer = new CPointer(canvas);
// Main scene loop
setInterval(drawScene, 20);
}
// Window onload init
if (window.attachEvent) {
window.attachEvent('onload', sceneInit);
} else {
if (window.onload) {
var curronload = window.onload;
var newonload = function() {
curronload();
sceneInit();
};
window.onload = newonload;
} else {
window.onload = sceneInit;
}
}
// Get random color
function getRandomColor() {
var letters = '0123456789ABCDEF'.split('');
var color = '#';
for (var i = 0; i < 6; i++ ) {
color += letters[Math.round(Math.random() * 15)];
}
return color;
}
// Draw main scene function
function drawScene() {
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height); // Clear canvas
if (vPointer.bDown) { // on mouse down
var iDx = iLMx - vPointer.X;
var iDy = iLMy - vPointer.Y;
var dif = Math.sqrt(iDx * iDx + iDy * iDy); // difference between two last points
if (dif > 5) {
if (! vActShape) {
aShapes.push( // prepare a new shape object
vActShape = new Shape()
);
vActShape.color = getRandomColor();
}
iLMx = vPointer.X;
iLMy = vPointer.Y;
vActShape.addPoint(vPointer.X - canvas.width * 0.5, vPointer.Y - canvas.height * 0.5, 0);
}
} else {
// Once mouse is released - cleanup
if (vActShape) {
vActShape = '';
iLMx = iLMy = 0;
}
// Rotate the shapes
aShapes.forEach(function(sh) {
sh.rotate();
});
}
// Draw all shapes
aShapes.forEach(function(sh) {
sh.draw();
});
}
// Initialization
function sceneInit() {
// Prepare canvas and context objects
canvas = document.getElementById('scene');
// Canvas resize
canvas.width = canvas.clientWidth;
canvas.height = window.innerHeight;
ctx = canvas.getContext('2d');
// Add two custom shapes
var oShape = new Shape();
oShape.addPoint(-200,-200,50);
oShape.addPoint(0,0,0);
oShape.addPoint(-400,200,0);
oShape.addPoint(200,-400,-50);
aShapes.push(oShape);
var oShape2 = new Shape();
oShape2.addPoint(200,200,-50);
oShape2.addPoint(0,0,0);
oShape2.addPoint(400,-200,0);
oShape2.addPoint(-200,400,50);
aShapes.push(oShape2);
// Mouse pointer event handler
vPointer = new CPointer(canvas);
// Main scene loop
setInterval(drawScene, 20);
}
// Window onload init
if (window.attachEvent) {
window.attachEvent('onload', sceneInit);
} else {
if (window.onload) {
var curronload = window.onload;
var newonload = function() {
curronload();
sceneInit();
};
window.onload = newonload;
} else {
window.onload = sceneInit;
}
}
In sceneInit we added two shapes. As you have already noticed, in order to handle with mouse events we use an instance of CPointer class. Here is it:
在sceneInit中,我们添加了两个形状。 正如您已经注意到的,为了处理鼠标事件,我们使用CPointer类的实例。 就这个:
(js/pointer.js)
CPointer = function (canvas) {
var self = this;
this.body = document.body;
this.html = document.documentElement;
this.elem = canvas;
this.X = 0;
this.Y = 0;
this.Xi = 0;
this.Yi = 0;
this.Xr = 0;
this.Yr = 0;
this.startX = 0;
this.startY = 0;
this.bDrag = false;
this.bMoved = false;
this.bDown = false;
this.bXi = 0;
this.bYi = 0;
this.sX = 0;
this.sY = 0;
this.left = canvas.offsetLeft;
this.top = canvas.offsetTop;
self.elem.onmousedown = function (e) {
self.bDrag = false;
self.bMoved = false;
self.bDown = true;
self.Xr = e.clientX;
self.Yr = e.clientY;
self.X = self.sX = self.Xr - self.left;
self.Y = self.sY = self.Yr - self.top + ((self.html && self.html.scrollTop) || self.body.scrollTop);
}
self.elem.onmousemove = function(e) {
self.Xr = (e.clientX !== undefined ? e.clientX : e.touches[0].clientX);
self.Yr = (e.clientY !== undefined ? e.clientY : e.touches[0].clientY);
self.X = self.Xr - self.left;
self.Y = self.Yr - self.top + ((self.html && self.html.scrollTop) || self.body.scrollTop);
if (self.bDown) {
self.Xi = self.bXi + (self.X - self.sX);
self.Yi = self.bYi - (self.Y - self.sY);
}
if (Math.abs(self.X - self.sX) > 2 || Math.abs(self.Y - self.sY) > 2) {
self.bMoved = true;
if (self.bDown) {
if (! self.bDrag) {
self.startX = self.sX;
self.startY = self.sY;
self.bDrag = true;
}
} else {
self.sX = self.X;
self.sY = self.Y;
}
}
}
self.elem.onmouseup = function() {
self.bXi = self.Xi;
self.bYi = self.Yi;
if (! self.bMoved) {
self.X = self.sX;
self.Y = self.sY;
}
self.bDrag = false;
self.bDown = false;
self.bMoved = false;
}
}
CPointer = function (canvas) {
var self = this;
this.body = document.body;
this.html = document.documentElement;
this.elem = canvas;
this.X = 0;
this.Y = 0;
this.Xi = 0;
this.Yi = 0;
this.Xr = 0;
this.Yr = 0;
this.startX = 0;
this.startY = 0;
this.bDrag = false;
this.bMoved = false;
this.bDown = false;
this.bXi = 0;
this.bYi = 0;
this.sX = 0;
this.sY = 0;
this.left = canvas.offsetLeft;
this.top = canvas.offsetTop;
self.elem.onmousedown = function (e) {
self.bDrag = false;
self.bMoved = false;
self.bDown = true;
self.Xr = e.clientX;
self.Yr = e.clientY;
self.X = self.sX = self.Xr - self.left;
self.Y = self.sY = self.Yr - self.top + ((self.html && self.html.scrollTop) || self.body.scrollTop);
}
self.elem.onmousemove = function(e) {
self.Xr = (e.clientX !== undefined ? e.clientX : e.touches[0].clientX);
self.Yr = (e.clientY !== undefined ? e.clientY : e.touches[0].clientY);
self.X = self.Xr - self.left;
self.Y = self.Yr - self.top + ((self.html && self.html.scrollTop) || self.body.scrollTop);
if (self.bDown) {
self.Xi = self.bXi + (self.X - self.sX);
self.Yi = self.bYi - (self.Y - self.sY);
}
if (Math.abs(self.X - self.sX) > 2 || Math.abs(self.Y - self.sY) > 2) {
self.bMoved = true;
if (self.bDown) {
if (! self.bDrag) {
self.startX = self.sX;
self.startY = self.sY;
self.bDrag = true;
}
} else {
self.sX = self.X;
self.sY = self.Y;
}
}
}
self.elem.onmouseup = function() {
self.bXi = self.Xi;
self.bYi = self.Yi;
if (! self.bMoved) {
self.X = self.sX;
self.Y = self.sY;
}
self.bDrag = false;
self.bDown = false;
self.bMoved = false;
}
}
现场演示
(Conclusion)
Today, we have built the rotating panel where we can draw (with the mouse) using HTML5. I hope you enjoyed our lesson. Good luck and welcome back.
今天,我们已经建立了旋转面板,可以在其中使用HTML5绘制(使用鼠标)。 希望您喜欢我们的课程。 祝你好运,欢迎回来。
翻译自: https://www.script-tutorials.com/pane-for-drawing-in-pseudo-3d/
matlab如何绘制伪彩色