Wątek przeniesiony 2021-12-03 14:08 z Nietuzinkowe tematy przez Patryk27.

Algorytm rysowania szlaczku (pseudokod)

0

Dzień dobry.

Walczę z tym od dłuższego czasu i nie mogę się ogarnąć. Mam napisany algorytm rysowania szlaczku oraz ich klonów, które są przesunięte od niego w pionie do dołu o x px.

Próbuję napisać 2 wersję algorytmu, która będzie rysować klony szlaczku, ale oddalone nie o x w pionie, tylko ze stałą odległością w każdym punkcie o x. Czyli jednym słowem, chcę narysować proste równoległe do każdego z fragmentu szlaczku, odległe od niego o x * n, gdzie n to numer klonu szlaczku, oddalony coraz to dalej, które zostają przycięte w punktach wspólnych.

Mam jednak problem z algorytmem. Bo o ile algorytm nr 1:

function mprjs_drawCustomPttn(svg, sz, parts, n, shift, cstmStr, dl, type) {
    let paths = [];

    for (var i = 0; i < n; i++) {
        paths.push(svg.path((type == "Simple") ? mprjs_genPattnStrSimple(sz, parts, i, cstmStr, shift) : mprjs_genPattnStrTricky(sz, parts, i, cstmStr, shift)));
        paths[i].attr({stroke: "#000", "stroke-width": 3, class: "mp_patt"});
    }

    paths = $(document).find(".mp_patt");
    let fcts = [];
    fcts.push(function () {
        mprjs_completeHelper(paths[paths.length - 1], dl, null);
    });

    for (let i = paths.length - 2; i >= 0; i--) {
        fcts.push(function () {
            mprjs_completeHelper(paths[i], dl, fcts.pop());
        });
    }

    clearAllPaths(paths);

    fcts.pop()();
}

wygląda tak, ,a funkcja prostego patha wygląda tak:

function mprjs_genPattnStrSimple(sz, parts, i, cstmStr, shift) {
    var elms = parseElemsFloat(cstmStr);
    var cellLength = countForwardElems(elms);

    var zeroLvl = (sz * 0.25 * 0.5 + i * shift * 2)
    var pathStr = "m10 " + zeroLvl;
    var len = parts * cellLength;
    var partW = sz / len * 0.95;
    
    for (var clone = 0; clone < parts; clone++) {
        var lvlx = 0;
        var lvly = 0;

        for (var i = 0; i < elms.length; i++) {
            if (elms[i][0] == "f")
                switch (elms[i][1]) {
                    case 0:  pathStr += "h" + partW; lvlx++; break;

                case 0.5:  pathStr += "l" + (2 * partW) + ",-" + (0.5 * partW); lvlx += 2; lvly += 0.5; break;
                case -0.5: pathStr += "l" + (2 * partW) + "," + (0.5 * partW); lvlx += 2; lvly -= 0.5; break;

                    case 1:  pathStr += "l" + partW + ",-" + partW; lvlx++; lvly++; break;
                    case -1: pathStr += "l" + partW + "," + partW; lvlx++; lvly--; break;

                    case 2:  pathStr += "l" + partW + ",-" + (2 * partW); lvlx++; lvly += 2; break;
                    case -2: pathStr += "l" + partW + "," + (2 * partW); lvlx++; lvly -= 2; break;

                    case 3:  pathStr += "v-" + partW; lvly++; break;
                    case -3: pathStr += "v" + partW; lvly--; break;
                    default: throw "error";
                }

            else
                switch (elms[i][1]) {
                    case 0:  pathStr += "h" + partW; lvlx++; break;

                case 0.5:  pathStr += "l" + (-2 * partW) + ",-" + (0.5 * partW); lvlx -= 2; lvly += 0.5; break;
                case -0.5: pathStr += "l" + (-2 * partW) + "," + (0.5 * partW); lvlx -= 2; lvly -= 0.5; break;

                    case 1:  pathStr += "l" + (-partW) + ",-" + partW; lvlx--; lvly++; break;
                    case -1: pathStr += "l" + (-partW) + "," + partW; lvlx--; lvly--; break;

                    case 2:  pathStr += "l" + (-partW) + ",-" + (2 * partW); lvlx--; lvly += 2; break;
                    case -2: pathStr += "l" + (-partW) + "," + (2 * partW); lvlx--; lvly -= 2; break;

                    case 3:  pathStr += "v-" + partW; lvly++; break;
                    case -3: pathStr += "v" + partW; lvly--; break;
                    default: throw "error";
                }
        }

        if (lvly != 0)
            pathStr += "m0," + (lvly * partW);
    }

    return pathStr;
}

to nie wiem, jak kurcze ogarnąć ten drugi problem, czyli rysowania o x * n w stałej odległości.

Proszę tylko o pomoc w opisie słownym albo pseudokodzie. W razie pytań, służę wyjaśnieniem ;)

PS. Dodam, że odległość na podstawie której można wyliczyć punkt przecięcia 2 prostych wyraża się wzorem:
d * (1/sin(kąt) - 1/tg(kąt))

Matma => odległość między wysokościami równoległoboku

PS2.

Użycie funkcji:

var patt1 = "0,3,0,3,0,-2,1,1,-3,0,-3,1,-1";
var patt2 = "0,-3,0,-3,0,2,-1,-1,0,3,0,3,-1,1";
var patt3 = "1,-1,-1,1";
var patt4 = "0,0,-1,1,0,0,1,-1";
mprjs_drawPttn("myWG", 1600, 2, 1, 10, patt3, "Simple", 0);

1 par - id w html
2 par - szerokość svg na stronie
3 par - ilość duplikatów ustalonego patternu w 1 szlaczku
4 par - ilość klonów całego szlaczku
5 par - odległość klonów w pionie
6 par - układ jednej komórki szlaczku, która jest replikowana w ramach 1 szlaczku na podstawie par 3.
7 par - typ replikacji
8 par - opóźnienie rysowanego szlaczku

0

Chodzi o to, że może być taka sytuacja jak poniżej, że wykres będzie zbyt wąski u góry i trzeba w sklonowanym wykresie ten element ominąć. Ale nie wiem jak to zrobić :(

screenshot-20211203184021.png

1 użytkowników online, w tym zalogowanych: 0, gości: 1