Settransform Визуально неверно для отраженного изображения (переведено/вращение/масштабирование), но Matrixtransform, прJavascript

Форум по Javascript
Ответить
Anonymous
 Settransform Визуально неверно для отраженного изображения (переведено/вращение/масштабирование), но Matrixtransform, пр

Сообщение Anonymous »

My Vanilla JS -программа имеет два полотна. Пользователь рисует произвольные прямые линии на изображении на первом холсте, а части, взятые из разделения холста на линии, нарисованы на втором холсте, некоторые из них отражаются вокруг линии (с использованием отражания ). Я рисую отраженные точки пьесы непосредственно на втором холсте, а затем применяю преобразование матрицы отражения (полученное с помощью GetReflectionMatrix ), чтобы я мог повернуть/масштабировать изображение соответствующим образом, затем нарисовать изображение, подрезанное. Это как если бы отражение не применяет (или удваивается) или что -то в этом роде, поэтому изображение вращается под неправильным углом, и его угол не соответствует немодифицированному контуру отраженных точек. Dompoint.matrixtransform < /code> в
преобразовать исходные точки с помощью матрицы отражения, чтобы показать, что матрица
не работает одно и то же время - и заполнено как с
желтым, так и синим (зеленое). Это предполагаемые точки. Один, который окрашен в зеленый цвет. < /li>
< /ol>
Я уверен, что это что -то действительно простое, и я чувствую себя глупо, спрашиваю, но я как -то застрял в течение нескольких дней :( Геометрия не моя. src = "https://i.sstatic.net/8lgq0btk.png"/>
Работа:
Изображение

const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");
const img = document.getElementById("image");

const intersects = [new DOMPoint(143.07549812764975, 58.35350167526056),
new DOMPoint(198.3825597334491, 8.86823602796649)];
const points = [
new DOMPoint(198.38255973344914, 8.868236027966528),
new DOMPoint(162.65825355141538, 359.09787638799855),
new DOMPoint(112.9163540869709, 354.0240772523315),
new DOMPoint(143.0754981276499, 58.3535016752607),
];
const line = { startX: 250.4616879421679, startY: -37.7288786850976, endX: 103.53831205783209, endY: 93.7288786850976 };

const reflected = reflectPiece(points, line);
const transform = getReflectionMatrix(line);
const mapped = mapTransform(points, transform);

const canvasTransform = new DOMMatrix().translateSelf(canvas.width/2, canvas.height/2);
const drawTransform = canvasTransform.multiply(transform);
ctx.setTransform(canvasTransform);

img.onload = () => {
debug();
}

function debug() {
drawMatrixTransformedPoints();
drawReflectedWithTransform();
drawReflectedPoints();
drawImage();
}

function drawMatrixTransformedPoints() {
ctx.strokeStyle = "black";
tracePiecePath(mapped);
ctx.stroke();
ctx.fillStyle = "yellow";
ctx.fill();
}

function drawReflectedPoints() {
ctx.strokeStyle = "blue";
tracePiecePath(reflected);
ctx.stroke();
ctx.globalAlpha = 0.25;
ctx.fillStyle = "cyan";
ctx.fill();
ctx.globalAlpha = 1;
}

function drawReflectedWithTransform() {
ctx.save();
ctx.strokeStyle = "red";
ctx.setTransform(drawTransform);
tracePiecePath(reflected);
ctx.stroke();
ctx.restore();
}

function drawImage() {
ctx.globalAlpha = 0.5;
ctx.save();
ctx.setTransform(drawTransform);
ctx.drawImage(img, 0, 0);
ctx.restore();
ctx.globalAlpha = 1;
}

function tracePiecePath(points) {
ctx.beginPath();
const firstPoint = points[0];
ctx.moveTo(firstPoint.x, firstPoint.y);
points.slice(1).forEach(point => {
ctx.lineTo(point.x, point.y);
});
ctx.closePath();
}

function getReflectionMatrix(line) {
const matrix = new DOMMatrix();
const origin = getMidlinePoint(...intersects);
const angle = getAngleFromOrigin(line);
const angleInDegrees = angle * 180 / Math.PI;
matrix.translateSelf(origin.x, origin.y);
matrix.rotateSelf(angleInDegrees);
matrix.scaleSelf(1, -1);
matrix.rotateSelf(-angleInDegrees);
matrix.translateSelf(-origin.x, -origin.y);
return matrix;
}

function getMidlinePoint(pt1, pt2) {
const x = (pt1.x + pt2.x)/2;
const y = (pt1.y + pt2.y)/2;
return new DOMPoint(x, y);
}

function getAngleFromOrigin(line) {
const { startX, endX, startY, endY } = line;
const dx = endX - startX;
const dy = endY - startY;
return Math.atan2(dy, dx);
}

function reflectPiece(points, line) {
const normal = this.getNormalVector(line);
const newPoints = [];
for (let i = 0; i < points.length; i++) {
newPoints.push(this.reflectPoint(line, points, normal));
};
return newPoints;
}

function getNormalVector(line) {
const { startX, endX, startY, endY } = line;
const dx = endX - startX;
const dy = endY - startY;
const len = Math.hypot(dx, dy);

const nx = -dy / len;
const ny = dx / len;
return { nx, ny };
}
function reflectPoint(line, point, normal) {
const { x, y } = point;
const { startX, startY } = line;
const { nx, ny } = normal;

const vx = x - startX;
const vy = y - startY;
const dot = vx * nx + vy * ny;
const rx = startX + vx - 2 * dot * nx;
const ry = startY + vy - 2 * dot * ny;
return new DOMPoint(rx, ry);
}

function mapTransform(points, m) {
return points.map(point => point.matrixTransform(m));
}

< /code>
Вот пример рабочей формы (выравнивается с зеленой формой, а не красной): < /p>

Код: Выделить всё

const intersects = [new DOMPoint(256.8378378378378, 50),
new DOMPoint(258.18918918918916)];
const points = [new DOMPoint(369.29268292682923, 50),
new DOMPoint(256.83783783783787, 50),
new DOMPoint(258.1891891891892, 0),
new DOMPoint(316.8536585365853, 0)];
const line = { startX: 267.0952908723996, startY: -329.5257622787839, endX: 247.90470912760043, endY: 380.5257622787839 };
debug.png:
Спасибо!

Подробнее здесь: https://stackoverflow.com/questions/796 ... ted-scaled
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Javascript»