Perspective view with horizon
This commit is contained in:
1 parent
aa349624e3
commit
09f1e9a1cb
1 file changed
+66
-42
+66
-42
@@ -24,25 +24,24 @@
|
||||
window.addEventListener('resize', resize);
|
||||
resize();
|
||||
|
||||
var offX = 0, offY = 0;
|
||||
var offX = 0, offZ = 0;
|
||||
|
||||
function project(x, y, z) {
|
||||
var scale = 600 / (600 + z);
|
||||
var sx = (x - y) * scale + W / 2;
|
||||
var sy = ((x + y) * 0.5 - z) * scale + H / 2;
|
||||
var fov = 800;
|
||||
var scale = fov / (fov + z);
|
||||
var isoX = (x - y) * 0.5;
|
||||
var isoY = ((x + y) * 0.5) - z;
|
||||
var sx = isoX * scale + W / 2;
|
||||
var sy = isoY * scale + H / 2;
|
||||
return [sx, sy];
|
||||
}
|
||||
|
||||
function generateTriangle(p1, p2, p3, water) {
|
||||
return { p1: p1, p2: p2, p3: p3, water: water, depth: (p1[2] + p2[2] + p3[2]) / 3 };
|
||||
}
|
||||
|
||||
function getHeight(x, y) {
|
||||
function getHeight(x, z) {
|
||||
var h = 0;
|
||||
h += Math.sin(x / 300) * 50;
|
||||
h += Math.cos(y / 300) * 50;
|
||||
h += Math.sin(x / 150 + y / 300) * 25;
|
||||
h += Math.cos(y / 150 - x / 300) * 20;
|
||||
h += Math.sin(x / 200) * 60;
|
||||
h += Math.cos(z / 200) * 60;
|
||||
h += Math.sin(x / 100 + z / 200) * 30;
|
||||
h += Math.cos(z / 100 - x / 200) * 25;
|
||||
return h;
|
||||
}
|
||||
|
||||
@@ -53,20 +52,20 @@
|
||||
var range = 25;
|
||||
var size = 100;
|
||||
for (var x = -range; x <= range; x++) {
|
||||
for (var y = -range; y <= range; y++) {
|
||||
for (var z = -range; z <= range; z++) {
|
||||
var wx = x * size + offX;
|
||||
var wy = y * size + offY;
|
||||
var h1 = getHeight(wx, wy);
|
||||
var h2 = getHeight(wx + size, wy);
|
||||
var h3 = getHeight(wx + size, wy + size);
|
||||
var h4 = getHeight(wx, wy + size);
|
||||
var wz = z * size + offZ;
|
||||
var h1 = getHeight(wx, wz);
|
||||
var h2 = getHeight(wx + size, wz);
|
||||
var h3 = getHeight(wx + size, wz + size);
|
||||
var h4 = getHeight(wx, wz + size);
|
||||
var water = (h1 < 30 || h2 < 30 || h3 < 30 || h4 < 30);
|
||||
var p1 = [wx, h1, wy];
|
||||
var p2 = [wx + size, h2, wy];
|
||||
var p3 = [wx + size, h3, wy + size];
|
||||
var p4 = [wx, h4, wy + size];
|
||||
triangles.push(generateTriangle(p1, p2, p3, water));
|
||||
triangles.push(generateTriangle(p1, p3, p4, water));
|
||||
var p1 = [wx, h1, wz];
|
||||
var p2 = [wx + size, h2, wz];
|
||||
var p3 = [wx + size, h3, wz + size];
|
||||
var p4 = [wx, h4, wz + size];
|
||||
triangles.push({ p1: p1, p2: p2, p3: p3, water: water, depth: (p1[2] + p2[2] + p3[2]) / 3 });
|
||||
triangles.push({ p1: p1, p2: p3, p3: p4, water: water, depth: (p1[2] + p3[2] + p4[2]) / 3 });
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -75,9 +74,11 @@
|
||||
triangles.sort(function(a, b) { return b.depth - a.depth; });
|
||||
for (var i = 0; i < triangles.length; i++) {
|
||||
var t = triangles[i];
|
||||
var p1 = project(t.p1[0], t.p1[2], t.p1[1]);
|
||||
var p2 = project(t.p2[0], t.p2[2], t.p2[1]);
|
||||
var p3 = project(t.p3[0], t.p3[2], t.p3[1]);
|
||||
var p1 = project(t.p1[0], t.p1[1], t.p1[2]);
|
||||
var p2 = project(t.p2[0], t.p2[1], t.p2[2]);
|
||||
var p3 = project(t.p3[0], t.p3[1], t.p3[2]);
|
||||
|
||||
if (p1[1] < -200 || p1[1] > H + 200) continue;
|
||||
|
||||
ctx.fillStyle = t.water ? 'rgba(0, 80, 200, 0.85)' : 'rgba(0, 160, 0, 0.85)';
|
||||
ctx.beginPath();
|
||||
@@ -93,6 +94,16 @@
|
||||
}
|
||||
}
|
||||
|
||||
function drawHorizon() {
|
||||
var hY = H / 2 - 50;
|
||||
ctx.strokeStyle = 'rgba(255, 200, 100, 0.3)';
|
||||
ctx.lineWidth = 1;
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(0, hY);
|
||||
ctx.lineTo(W, hY);
|
||||
ctx.stroke();
|
||||
}
|
||||
|
||||
var planeVertices = [];
|
||||
function initPlane() {
|
||||
planeVertices = [];
|
||||
@@ -111,12 +122,10 @@
|
||||
planeVertices.push([40, 30, 0]);
|
||||
}
|
||||
|
||||
var yawT = 0, rollT = 0, pitchT = 0;
|
||||
|
||||
function drawPlane() {
|
||||
var yaw = -0.4;
|
||||
var roll = 0;
|
||||
var pitch = 0.2;
|
||||
var pitch = 0.15;
|
||||
|
||||
var transformed = planeVertices.map(function(v) {
|
||||
var x = v[0], y = v[1], z = v[2];
|
||||
@@ -138,27 +147,42 @@
|
||||
ctx.shadowColor = '#ff0000';
|
||||
|
||||
for (var i = 0; i < transformed.length; i++) {
|
||||
var p = project(transformed[i][0], transformed[i][2], transformed[i][1]);
|
||||
var p = project(transformed[i][0], transformed[i][1], transformed[i][2]);
|
||||
ctx.fillStyle = '#ff0000';
|
||||
ctx.beginPath();
|
||||
ctx.arc(p[0], p[1], 3, 0, Math.PI * 2);
|
||||
ctx.fill();
|
||||
}
|
||||
|
||||
for (var i = 0; i < transformed.length - 1; i++) {
|
||||
if (i >= 7 && i <= 10) continue;
|
||||
var p1 = project(transformed[i][0], transformed[i][2], transformed[i][1]);
|
||||
var p2 = project(transformed[i + 1][0], transformed[i + 1][2], transformed[i + 1][1]);
|
||||
for (var i = 0; i < 7; i++) {
|
||||
var p1 = project(transformed[i][0], transformed[i][1], transformed[i][2]);
|
||||
var p2 = project(transformed[i + 1][0], transformed[i + 1][1], transformed[i + 1][2]);
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(p1[0], p1[1]);
|
||||
ctx.lineTo(p2[0], p2[1]);
|
||||
ctx.stroke();
|
||||
}
|
||||
ctx.beginPath();
|
||||
var pFirst = project(transformed[0][0], transformed[0][1], transformed[0][2]);
|
||||
var pLast = project(transformed[7][0], transformed[7][1], transformed[7][2]);
|
||||
ctx.moveTo(pFirst[0], pFirst[1]);
|
||||
ctx.lineTo(pLast[0], pLast[1]);
|
||||
ctx.stroke();
|
||||
|
||||
for (var i = 8; i <= 11; i++) {
|
||||
var j = (i + 1 > 11) ? 8 : i + 1;
|
||||
var p1 = project(transformed[i][0], transformed[i][1], transformed[i][2]);
|
||||
var p2 = project(transformed[j][0], transformed[j][1], transformed[j][2]);
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(p1[0], p1[1]);
|
||||
ctx.lineTo(p2[0], p2[1]);
|
||||
ctx.stroke();
|
||||
}
|
||||
|
||||
for (var i = 7; i <= 10; i++) {
|
||||
var j = (i + 1 > 10) ? 7 : i + 1;
|
||||
var p1 = project(transformed[i][0], transformed[i][2], transformed[i][1]);
|
||||
var p2 = project(transformed[j][0], transformed[j][2], transformed[j][1]);
|
||||
for (var i = 12; i <= 15; i++) {
|
||||
var j = (i + 1 > 15) ? 12 : i + 1;
|
||||
var p1 = project(transformed[i][0], transformed[i][1], transformed[i][2]);
|
||||
var p2 = project(transformed[j][0], transformed[j][1], transformed[j][2]);
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(p1[0], p1[1]);
|
||||
ctx.lineTo(p2[0], p2[1]);
|
||||
@@ -175,10 +199,10 @@
|
||||
ctx.fillRect(0, 0, W, H);
|
||||
|
||||
offX -= 1.5;
|
||||
offY -= 0.7;
|
||||
offZ -= 0.7;
|
||||
generateLandscape();
|
||||
drawLandscape();
|
||||
|
||||
drawHorizon();
|
||||
drawPlane();
|
||||
|
||||
requestAnimationFrame(frame);
|
||||
|
||||
Reference in new issue
Block a user