Как я могу вычислить границу / обводку, добавленную к треугольнику, учитывая векторы треугольников и ширину обводки?

У меня есть один набор координат треугольника. Один вектор на каждые три балла. На изображении ниже этот треугольник thin yellow один. Мне нужно добавить stroke или же border к этому треугольнику, который выступает как внутрь, так и наружу, с центром в исходных линиях желтого треугольника.

Поэтому, учитывая оригинальный набор из трех треугольников vector координаты и штрих / граница widthКак я могу рассчитать vector координаты для внешнего и внутреннего краев black (обводка / граница) треугольник?

red точки на изображении указывают точки, которые мне нужно рассчитать.

Треугольник можно масштабировать либо по ширине, либо по высоте, и мне нужен черный штрих / рамка, чтобы всегда оставаться на постоянной заданной ширине.

Хотя мне нужно реализовать это отдельно в обоих C++ а также javascript за WebGLМне нужны только математические формулы.

Если мы представим variables Я визуализировал в javascript с верхней левой точкой исходного прямоугольника, ограничивающего прямоугольник (0,0) тогда мы получим следующее:

var width = 300;
var height = 200;
var strokeWidth = 20;
var V1 = {x: 0, y: height};
var V2 = {x: width, y: height};
var V3 = {x: width / 2, y: 0);

Исходя из этого, мне нужно рассчитать все шесть красных точек. Заранее благодарю за любую помощь.

введите описание изображения здесь

2

Решение

Когда вы определяете свои позиции вершин относительно центра, вы можете просто получить направление, нормализуя их, затем умножить направление на ширину штриха и сложить / вычесть результат в ваши вершины, в glsl, что будет:

float strokeWidth = 10.;
vec2 vdir = normalize(vertexPosition);
vec2 outer = vertexPosition + vdir * strokeWidth;
vec2 inner = vertexPosition - vdir * strokeWidth;

В JS без какой-либо математической библиотеки это выглядело бы так:

function Point(x,y){this.x = x, this.y = y}
var strokeWidth = 20;
var V1 = new Point(-100,50);
var V2 = new Point(100,50);
var V3 = new Point(0, -100);

var ctx = triangle.getContext("2d"), ctxRect = ctx.canvas.getBoundingClientRect();

function drawPoints () {
ctx.clearRect(0,0,ctxRect.width,ctxRect.height);

// draw initial points
ctx.strokeStyle = ctx.fillStyle = "#fa0";
ctx.fillRect(V1.x+ctxRect.width / 2,V1.y+ctxRect.height / 2,5,5);
ctx.fillRect(V2.x+ctxRect.width / 2,V2.y+ctxRect.height / 2,5,5);
ctx.fillRect(V3.x+ctxRect.width / 2,V3.y+ctxRect.height / 2,5,5);
// draw triangle lines
ctx.beginPath();
ctx.moveTo(V1.x+ctxRect.width / 2+2,V1.y+ctxRect.height / 2+2);
ctx.lineTo(V2.x+ctxRect.width / 2+2,V2.y+ctxRect.height / 2+2);
ctx.lineTo(V3.x+ctxRect.width / 2+2,V3.y+ctxRect.height / 2+2);
ctx.lineTo(V1.x+ctxRect.width / 2+2,V1.y+ctxRect.height / 2+2);
ctx.closePath();
ctx.stroke();

// get direction
var len = Math.sqrt(V1.x*V1.x+V1.y*V1.y);
var dx = V1.x / len, dy = V1.y / len;
var V1outer = new Point(V1.x + dx * strokeWidth, V1.y + dy * strokeWidth);
var V1inner = new Point(V1.x - dx * strokeWidth, V1.y - dy * strokeWidth);
console.log(V1outer);
len = Math.sqrt(V2.x*V2.x+V2.y*V2.y);
dx = V2.x / len, dy = V2.y / len;
var V2outer = new Point(V2.x + dx * strokeWidth, V2.y + dy * strokeWidth);
var V2inner = new Point(V2.x - dx * strokeWidth, V2.y - dy * strokeWidth);

len = Math.sqrt(V3.x*V3.x+V3.y*V3.y);
dx = V3.x / len, dy = V3.y / len;
var V3outer = new Point(V3.x + dx * strokeWidth, V3.y + dy * strokeWidth);
var V3inner = new Point(V3.x - dx * strokeWidth, V3.y - dy * strokeWidth);

ctx.strokeStyle = ctx.fillStyle = "#F00";
ctx.fillRect(V1outer.x+ctxRect.width / 2, V1outer.y+ctxRect.height / 2, 5,5);
ctx.fillRect(V2outer.x+ctxRect.width / 2, V2outer.y+ctxRect.height / 2, 5,5);
ctx.fillRect(V3outer.x+ctxRect.width / 2, V3outer.y+ctxRect.height / 2, 5,5);

// draw triangle lines
ctx.beginPath();
ctx.moveTo(V1outer.x+ctxRect.width / 2+2,V1outer.y+ctxRect.height / 2+2);
ctx.lineTo(V2outer.x+ctxRect.width / 2+2,V2outer.y+ctxRect.height / 2+2);
ctx.lineTo(V3outer.x+ctxRect.width / 2+2,V3outer.y+ctxRect.height / 2+2);
ctx.lineTo(V1outer.x+ctxRect.width / 2+2,V1outer.y+ctxRect.height / 2+2);
ctx.closePath();
ctx.stroke();

ctx.strokeStyle = ctx.fillStyle = "#0F0";
ctx.fillRect(V1inner.x+ctxRect.width / 2, V1inner.y+ctxRect.height / 2, 5,5);
ctx.fillRect(V2inner.x+ctxRect.width / 2, V2inner.y+ctxRect.height / 2, 5,5);
ctx.fillRect(V3inner.x+ctxRect.width / 2, V3inner.y+ctxRect.height / 2, 5,5);

ctx.beginPath();
ctx.moveTo(V1inner.x+ctxRect.width / 2+2,V1inner.y+ctxRect.height / 2+2);
ctx.lineTo(V2inner.x+ctxRect.width / 2+2,V2inner.y+ctxRect.height / 2+2);
ctx.lineTo(V3inner.x+ctxRect.width / 2+2,V3inner.y+ctxRect.height / 2+2);
ctx.lineTo(V1inner.x+ctxRect.width / 2+2,V1inner.y+ctxRect.height / 2+2);
ctx.closePath();
ctx.stroke();

}
drawPoints();
strokeInput.oninput = function () {strokeWidth = this.value; drawPoints()}
#triangle { border: 1px dashed black; }
<label>Stroke Width: <input id="strokeInput" type="range" min="0" max="50" value="20"/></label><br/>
<canvas id="triangle" width="400" height="400"></canvas>
1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]