Naloga 1
This commit is contained in:
5
naloga_1/.prettierrc
Normal file
5
naloga_1/.prettierrc
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"semi": true,
|
||||
"trailingComma": "all",
|
||||
"tabWidth": 4
|
||||
}
|
||||
13
naloga_1/index.html
Normal file
13
naloga_1/index.html
Normal file
@@ -0,0 +1,13 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>Domača Naloga 1</title>
|
||||
|
||||
<script defer src="script.js"></script>
|
||||
</head>
|
||||
<body style="margin: 0; padding: 0;">
|
||||
<canvas id="canvas" width="512px" height="512px"></canvas>
|
||||
</body>
|
||||
</html>
|
||||
169
naloga_1/script.js
Normal file
169
naloga_1/script.js
Normal file
@@ -0,0 +1,169 @@
|
||||
async function main() {
|
||||
const canvas = document.getElementById("canvas");
|
||||
|
||||
/**
|
||||
* @type RenderingContext
|
||||
*/
|
||||
const ctx = canvas.getContext("2d");
|
||||
|
||||
const { models, scene } = await fetch("test.json").then(res => res.json());
|
||||
|
||||
for (const { model, transforms } of scene) {
|
||||
let m = Matrix.identity();
|
||||
|
||||
for (const transform of transforms) {
|
||||
switch (transform.type) {
|
||||
case "scale":
|
||||
m = m.scale(transform.factor[0], transform.factor[1]);
|
||||
break;
|
||||
case "rotate":
|
||||
m = m.rotate(transform.angle);
|
||||
break;
|
||||
case "translate":
|
||||
m = m.translate(transform.vector[0], transform.vector[1]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
m = m.screen(0, 0, canvas.width, canvas.height);
|
||||
|
||||
for (const line of models[model]) {
|
||||
const p1 = m.multiply(Matrix.vector(...line[0], 1));
|
||||
ctx.moveTo(p1.vector[0], p1.vector[1]);
|
||||
|
||||
const p2 = m.multiply(Matrix.vector(...line[1], 1));
|
||||
ctx.lineTo(p2.vector[0], p2.vector[1]);
|
||||
}
|
||||
ctx.stroke();
|
||||
}
|
||||
}
|
||||
|
||||
main();
|
||||
|
||||
class Matrix extends Array {
|
||||
/**
|
||||
* @param {number[][]} matrix
|
||||
*/
|
||||
constructor(matrix) {
|
||||
super();
|
||||
this.push(...matrix);
|
||||
}
|
||||
|
||||
static identity() {
|
||||
return new Matrix([
|
||||
[1, 0, 0],
|
||||
[0, 1, 0],
|
||||
[0, 0, 1],
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {number} vector
|
||||
*/
|
||||
static vector(...vector) {
|
||||
const matrix = Array(vector.length);
|
||||
for (let i = 0; i < vector.length; i++) {
|
||||
matrix[i] = [vector[i]];
|
||||
}
|
||||
return new Matrix(matrix);
|
||||
}
|
||||
|
||||
get width() {
|
||||
if (this.length === 0) {
|
||||
return 0;
|
||||
}
|
||||
return this[0].length;
|
||||
}
|
||||
|
||||
get height() {
|
||||
return this.length;
|
||||
}
|
||||
|
||||
get vector() {
|
||||
const v = [];
|
||||
for (const l of this) {
|
||||
v.push(l[0]);
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
toString() {
|
||||
let str = "";
|
||||
for (const line of this) {
|
||||
str += line.join(", ") + "\n";
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Matrix} matrix
|
||||
*/
|
||||
multiply(matrix) {
|
||||
if (this.width !== matrix.height) {
|
||||
throw Error("Can not multiply");
|
||||
}
|
||||
|
||||
const m = Array.from({ length: this.height },
|
||||
() => Array.from(
|
||||
{ length: matrix.width }, () => 0,
|
||||
),
|
||||
);
|
||||
|
||||
for (let i = 0; i < m.length; i++) {
|
||||
for (let j = 0; j < m[0].length; j++) {
|
||||
let sum = 0;
|
||||
for (let k = 0; k < this.width; k++) {
|
||||
sum += this[i][k] * matrix[k][j];
|
||||
}
|
||||
m[i][j] = sum;
|
||||
}
|
||||
}
|
||||
|
||||
return new Matrix(m);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {number} x
|
||||
* @param {number} y
|
||||
*/
|
||||
scale(x, y) {
|
||||
return new Matrix([
|
||||
[x, 0, 0],
|
||||
[0, y, 0],
|
||||
[0, 0, 1],
|
||||
]).multiply(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {number} angle
|
||||
*/
|
||||
rotate(angle) {
|
||||
return new Matrix([
|
||||
[Math.cos(angle), -Math.sin(angle), 0],
|
||||
[Math.sin(angle), Math.cos(angle), 0],
|
||||
[0, 0, 1],
|
||||
]).multiply(this);
|
||||
}
|
||||
|
||||
translate(x, y) {
|
||||
return new Matrix([
|
||||
[1, 0, x],
|
||||
[0, 1, y],
|
||||
[0, 0, 1],
|
||||
]).multiply(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {number} x0
|
||||
* @param {number} y0
|
||||
* @param {number} x1
|
||||
* @param {number} y1
|
||||
*/
|
||||
screen(x0, y0, x1, y1) {
|
||||
return new Matrix([
|
||||
[(x1 - x0) / 2, 0, (x0 + x1) / 2],
|
||||
[0, -(y1 - y0) / 2, (y0 + y1) / 2],
|
||||
[0, 0, 1],
|
||||
]).multiply(this);
|
||||
}
|
||||
}
|
||||
198
naloga_1/test.json
Normal file
198
naloga_1/test.json
Normal file
@@ -0,0 +1,198 @@
|
||||
{
|
||||
"models": [
|
||||
[
|
||||
[[-1, -1], [1, -1]],
|
||||
[[1, -1], [0, 1]],
|
||||
[[0, 1], [-1, -1]]
|
||||
],
|
||||
[
|
||||
[[0, 1], [-0.5878, -0.8090]],
|
||||
[[-0.5878, -0.8090], [0.9511, 0.3090]],
|
||||
[[0.9511, 0.3090], [-0.9511, 0.3090]],
|
||||
[[-0.9511, 0.3090], [0.5878, -0.8090]],
|
||||
[[0.5878, -0.8090], [0, 1]]
|
||||
]
|
||||
],
|
||||
"scene": [
|
||||
{
|
||||
"model": 0,
|
||||
"transforms": [
|
||||
{ "type": "scale", "factor": [0.01, 0.01] },
|
||||
{ "type": "rotate", "angle": 1 },
|
||||
{ "type": "translate", "vector": [0.05, 0] },
|
||||
{ "type": "rotate", "angle": 0.5 }
|
||||
]
|
||||
},
|
||||
{
|
||||
"model": 1,
|
||||
"transforms": [
|
||||
{ "type": "scale", "factor": [0.02, 0.02] },
|
||||
{ "type": "rotate", "angle": 2 },
|
||||
{ "type": "translate", "vector": [0.1, 0] },
|
||||
{ "type": "rotate", "angle": 1 }
|
||||
]
|
||||
},
|
||||
{
|
||||
"model": 0,
|
||||
"transforms": [
|
||||
{ "type": "scale", "factor": [0.03, 0.03] },
|
||||
{ "type": "rotate", "angle": 3 },
|
||||
{ "type": "translate", "vector": [0.15, 0] },
|
||||
{ "type": "rotate", "angle": 1.5 }
|
||||
]
|
||||
},
|
||||
{
|
||||
"model": 1,
|
||||
"transforms": [
|
||||
{ "type": "scale", "factor": [0.04, 0.04] },
|
||||
{ "type": "rotate", "angle": 4 },
|
||||
{ "type": "translate", "vector": [0.2, 0] },
|
||||
{ "type": "rotate", "angle": 2 }
|
||||
]
|
||||
},
|
||||
{
|
||||
"model": 0,
|
||||
"transforms": [
|
||||
{ "type": "scale", "factor": [0.05, 0.05] },
|
||||
{ "type": "rotate", "angle": 5 },
|
||||
{ "type": "translate", "vector": [0.25, 0] },
|
||||
{ "type": "rotate", "angle": 2.5 }
|
||||
]
|
||||
},
|
||||
{
|
||||
"model": 1,
|
||||
"transforms": [
|
||||
{ "type": "scale", "factor": [0.06, 0.06] },
|
||||
{ "type": "rotate", "angle": 6 },
|
||||
{ "type": "translate", "vector": [0.3, 0] },
|
||||
{ "type": "rotate", "angle": 3 }
|
||||
]
|
||||
},
|
||||
{
|
||||
"model": 0,
|
||||
"transforms": [
|
||||
{ "type": "scale", "factor": [0.07, 0.07] },
|
||||
{ "type": "rotate", "angle": 7 },
|
||||
{ "type": "translate", "vector": [0.35, 0] },
|
||||
{ "type": "rotate", "angle": 3.5 }
|
||||
]
|
||||
},
|
||||
{
|
||||
"model": 1,
|
||||
"transforms": [
|
||||
{ "type": "scale", "factor": [0.08, 0.08] },
|
||||
{ "type": "rotate", "angle": 8 },
|
||||
{ "type": "translate", "vector": [0.4, 0] },
|
||||
{ "type": "rotate", "angle": 4 }
|
||||
]
|
||||
},
|
||||
{
|
||||
"model": 0,
|
||||
"transforms": [
|
||||
{ "type": "scale", "factor": [0.09, 0.09] },
|
||||
{ "type": "rotate", "angle": 9 },
|
||||
{ "type": "translate", "vector": [0.45, 0] },
|
||||
{ "type": "rotate", "angle": 4.5 }
|
||||
]
|
||||
},
|
||||
{
|
||||
"model": 1,
|
||||
"transforms": [
|
||||
{ "type": "scale", "factor": [0.1, 0.1] },
|
||||
{ "type": "rotate", "angle": 10 },
|
||||
{ "type": "translate", "vector": [0.5, 0] },
|
||||
{ "type": "rotate", "angle": 5 }
|
||||
]
|
||||
},
|
||||
{
|
||||
"model": 0,
|
||||
"transforms": [
|
||||
{ "type": "scale", "factor": [0.11, 0.11] },
|
||||
{ "type": "rotate", "angle": 11 },
|
||||
{ "type": "translate", "vector": [0.55, 0] },
|
||||
{ "type": "rotate", "angle": 5.5 }
|
||||
]
|
||||
},
|
||||
{
|
||||
"model": 1,
|
||||
"transforms": [
|
||||
{ "type": "scale", "factor": [0.12, 0.12] },
|
||||
{ "type": "rotate", "angle": 12 },
|
||||
{ "type": "translate", "vector": [0.6, 0] },
|
||||
{ "type": "rotate", "angle": 6 }
|
||||
]
|
||||
},
|
||||
{
|
||||
"model": 0,
|
||||
"transforms": [
|
||||
{ "type": "scale", "factor": [0.13, 0.13] },
|
||||
{ "type": "rotate", "angle": 13 },
|
||||
{ "type": "translate", "vector": [0.65, 0] },
|
||||
{ "type": "rotate", "angle": 6.5 }
|
||||
]
|
||||
},
|
||||
{
|
||||
"model": 1,
|
||||
"transforms": [
|
||||
{ "type": "scale", "factor": [0.14, 0.14] },
|
||||
{ "type": "rotate", "angle": 14 },
|
||||
{ "type": "translate", "vector": [0.7, 0] },
|
||||
{ "type": "rotate", "angle": 7 }
|
||||
]
|
||||
},
|
||||
{
|
||||
"model": 0,
|
||||
"transforms": [
|
||||
{ "type": "scale", "factor": [0.15, 0.15] },
|
||||
{ "type": "rotate", "angle": 15 },
|
||||
{ "type": "translate", "vector": [0.75, 0] },
|
||||
{ "type": "rotate", "angle": 7.5 }
|
||||
]
|
||||
},
|
||||
{
|
||||
"model": 1,
|
||||
"transforms": [
|
||||
{ "type": "scale", "factor": [0.16, 0.16] },
|
||||
{ "type": "rotate", "angle": 16 },
|
||||
{ "type": "translate", "vector": [0.8, 0] },
|
||||
{ "type": "rotate", "angle": 8 }
|
||||
]
|
||||
},
|
||||
{
|
||||
"model": 0,
|
||||
"transforms": [
|
||||
{ "type": "scale", "factor": [0.17, 0.17] },
|
||||
{ "type": "rotate", "angle": 17 },
|
||||
{ "type": "translate", "vector": [0.85, 0] },
|
||||
{ "type": "rotate", "angle": 8.5 }
|
||||
]
|
||||
},
|
||||
{
|
||||
"model": 1,
|
||||
"transforms": [
|
||||
{ "type": "scale", "factor": [0.18, 0.18] },
|
||||
{ "type": "rotate", "angle": 18 },
|
||||
{ "type": "translate", "vector": [0.9, 0] },
|
||||
{ "type": "rotate", "angle": 9 }
|
||||
]
|
||||
},
|
||||
{
|
||||
"model": 0,
|
||||
"transforms": [
|
||||
{ "type": "scale", "factor": [0.19, 0.19] },
|
||||
{ "type": "rotate", "angle": 19 },
|
||||
{ "type": "translate", "vector": [0.95, 0] },
|
||||
{ "type": "rotate", "angle": 9.5 }
|
||||
]
|
||||
},
|
||||
{
|
||||
"model": 1,
|
||||
"transforms": [
|
||||
{ "type": "scale", "factor": [0.2, 0.2] },
|
||||
{ "type": "rotate", "angle": 20 },
|
||||
{ "type": "translate", "vector": [1, 0] },
|
||||
{ "type": "rotate", "angle": 10 }
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user