Обрезать линию внутри диапазона - PullRequest
2 голосов
/ 27 июня 2019

У меня есть график и линия регрессии (синяя).Теперь концы линии могут выходить из черного прямоугольника с размерами (x0, x1, y0, y1).

Мне бы хотелось, чтобы синяя линия отображалась только внутри черного прямоугольника.Как я могу это сделать?

Я знаю координаты: x0, x1, y0, y1, A и B.Я хочу знать координаты C и D.Мне нужна помощь ..

A figure of a rectangle with a line crossing it diagonally

1 Ответ

1 голос
/ 10 июля 2019

Вот реализация JavaScript Лянга-Барского на javascript. Он также выполняет пример расчета с именами переменных:

var x0 = 0;
var y0 = 0;
var x1 = 640;
var y1 = 480;
var xa = 20;
var ya = -40;
var xb = 680;
var yb = 460;

// JS port of https://github.com/w8r/liang-barsky/blob/master/src/liang-barsky.ts

const EPSILON = 1e-6;
const INSIDE = 1;
const OUTSIDE = 0;

/**
 * @param {Number} num
 * @param {Number} denom
 * @param {Number[]} c result [x,y]-array
 */
function clipT(num, denom, c) {
    const [tE, tL] = c;
    if (Math.abs(denom) < EPSILON) return num < 0;
    const t = num / denom;

    if (denom > 0) {
        if (t > tL) return 0;
        if (t > tE) c[0] = t;
    } else {
        if (t < tE) return 0;
        if (t < tL) c[1] = t;
    }
    return 1;
}

/**
 * @param {Number[]} a [x,y]-array
 * @param {Number[]} b [x,y]-array
 * @param {Number[]} box [xmin, ymin, xmax, ymax]-array
 * @param {Number[]} da result [x,y]-array
 * @param {Number[]} db result [x,y]-array
 * @return {Number} Returns OUTSIDE or INSIDE
 */
function clip(a, b, box, da = null, db = null) {
    const [x1, y1] = a;
    const [x2, y2] = b;
    const dx = x2 - x1;
    const dy = y2 - y1;

    if (da === undefined || db === undefined) {
        da = a;
        db = b;
    } else {
        da[0] = a[0];
        da[1] = a[1];
        db[0] = b[0];
        db[1] = b[1];
    }

    if (Math.abs(dx) < EPSILON && Math.abs(dy) < EPSILON && x1 >= box[0] && x1 <= box[2] && y1 >= box[1] && y1 <= box[3]) {
        return INSIDE;
    }

    const c = [0, 1]; // Point
    if (clipT(box[0] - x1, dx, c) && clipT(x1 - box[2], -dx, c) && clipT(box[1] - y1, dy, c) && clipT(y1 - box[3], -dy, c)) {
        const [tE, tL] = c;
        if (tL < 1) {
            db[0] = x1 + tL * dx;
            db[1] = y1 + tL * dy;
        }
        if (tE > 0) {
            da[0] += tE * dx;
            da[1] += tE * dy;
        }
        return INSIDE;
    }
    return OUTSIDE;
}

var da = [null, null];
var db = [null, null];
var res = clip([xa, ya], [xb, yb], [x0, y0, x1, y1], da, db);

var [xc, yc] = da;
var [xd, yd] = db;
console.log(res, xc, yc, xd, yd);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...