From c019035c3efa8055975dc6a5864086a21268b3a1 Mon Sep 17 00:00:00 2001 From: MERTULAS Date: Tue, 2 Sep 2025 16:32:17 +0300 Subject: [PATCH 1/2] image resize with linear interpolation but should be improve --- lib/shapes/shapes2d.js | 45 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/lib/shapes/shapes2d.js b/lib/shapes/shapes2d.js index 7ab40b3..b8cf409 100644 --- a/lib/shapes/shapes2d.js +++ b/lib/shapes/shapes2d.js @@ -79,9 +79,34 @@ class Transform { ]; this.#calculatePoints(scaleAffineMatrix); + + + if (this instanceof ImageShape) { + + for (let j = 0; j < this.h - 1; ++j) { + for (let i = 0; i < this.w - 1; ++i) { + const point1 = this.points[j * this.w + i]; + const point2 = this.points[j * this.w + i + 1]; + const point3 = this.points[(j + 1) * this.w + i]; + const point4 = this.points[(j + 1) * this.w + i + 1]; + const firstIntermediatePoints = this.#linearInterpolation(point1, point2, scaleX); + const secondIntermediatePoints = this.#linearInterpolation(point3, point4, scaleX); + + + for (let i = 0; i < firstIntermediatePoints.length; i++) { + for (const intermediatePoint of this.#linearInterpolation(firstIntermediatePoints[i], secondIntermediatePoints[i], scaleY)) { + this.points.push(intermediatePoint); + } + } + } + } + this.w *= scaleX; + this.h *= scaleY; + } + } - #calculatePoints (affineMatrix) { + #calculatePoints(affineMatrix) { const pointsLength = this.points.length; for (let i = 0; i < pointsLength; i++) { const point = this.points[i]; @@ -90,6 +115,24 @@ class Transform { point.y = scaledMatrix[1]; } } + + #linearInterpolation(point1, point2, step) { + const newPoints = []; + for (let i = 0; i < step; i++) { + const denominator = i / step; + newPoints.push( + new Pixel( + point1.x + (point2.x - point1.x) * denominator, + point1.y + (point2.y - point1.y) * denominator, + point1.r + (point2.r - point1.r) * denominator, + point1.g + (point2.g - point1.g) * denominator, + point1.b + (point2.b - point1.b) * denominator, + point1.a + (point2.a - point1.a) * denominator + ) + ); + } + return newPoints; + } } class Polygon extends Transform { From 68ebbd11d72654a640e9915af6d2a03e31955f1f Mon Sep 17 00:00:00 2001 From: MERTULAS Date: Sat, 4 Oct 2025 00:51:07 +0300 Subject: [PATCH 2/2] add group structure for 2d shapes --- lib/index.js | 5 +++-- lib/shapes/shapes2d.js | 46 +++++++++++++++++++++++++++++++++++------- 2 files changed, 42 insertions(+), 9 deletions(-) diff --git a/lib/index.js b/lib/index.js index 9fd5f14..0af3151 100644 --- a/lib/index.js +++ b/lib/index.js @@ -1,6 +1,6 @@ -import { Triangle, Rectangle, Polygon, ImageShape } from "./shapes/shapes2d.js"; +import { Triangle, Rectangle, Polygon, ImageShape, Group } from "./shapes/shapes2d.js"; import { Box } from "./shapes/shapes3d.js"; -import { initCanvas } from "./canvas/canvas.js"; +import { initCanvas } from "./canvas"; import { Vector } from "./vector"; import { Matrix } from "./matrix"; import { Point, Point3D, Pixel } from "./shapes/point.js"; @@ -10,6 +10,7 @@ export { Rectangle, Triangle, ImageShape, + Group, Box, initCanvas, Vector, diff --git a/lib/shapes/shapes2d.js b/lib/shapes/shapes2d.js index b8cf409..ef11e3b 100644 --- a/lib/shapes/shapes2d.js +++ b/lib/shapes/shapes2d.js @@ -147,9 +147,9 @@ class Polygon extends Transform { draw(fill = false) { window.__ctx__.beginPath(); window.__ctx__.moveTo(...this.points[0].asArray); - this.points.forEach(point => { + for (const point of this.points) { window.__ctx__.lineTo(...point.asArray); - }) + } window.__ctx__.lineTo(...this.points[0].asArray); if (fill) { @@ -163,10 +163,10 @@ class Polygon extends Transform { let xCenter = 0; let yCenter = 0; - this.points.forEach(point => { + for (const point of this.points) { xCenter += point.x; yCenter += point.y; - }) + } return new Point(xCenter / this.points.length, yCenter / this.points.length); } @@ -215,10 +215,41 @@ class ImageShape extends Transform { } draw() { - this.points.forEach(pixel => { + for (const pixel of this.points) { window.__ctx__.fillStyle = `rgba(${pixel.r}, ${pixel.g}, ${pixel.b}, ${pixel.a})`; window.__ctx__.fillRect(pixel.x, pixel.y, 1, 1); - }); + } + } +} + +class Group extends Transform { + constructor(...shapes) { + super(); + this.points = shapes.map(shape => shape.points).flat(); + this.shapes = shapes; + } + + get center() { + let xCenter = 0; + let yCenter = 0; + + for (const shape of this.shapes) { + xCenter += shape.center.x; + yCenter += shape.center.y; + } + + return new Point(xCenter / this.shapes.length, yCenter / this.shapes.length); + } + + addShape(shape) { + this.shapes.push(shape); + this.points = this.shapes.map(shape => shape.points).flat(); + } + + draw() { + for (const shape of this.shapes) { + shape.draw(); + } } } @@ -226,5 +257,6 @@ export { Triangle, Rectangle, Polygon, - ImageShape + ImageShape, + Group }