Autor Zpráva
Witiko
Profil
Mám takový menší problém s na první pohled poměrně triviálním algoritmem na generování tabulky. Popíšu v bodech, co algoritmus má dělat a kde mám problém:

1) Máme danou minimální šířku tabulky v buňkách, minimální výšku tabulky v buňkách a výchozí délku strany buňky
2) Algoritmus vezme výchozí délku strany a z rozměrů viewportu spočítá kolik maximálně čtvercových buněk o této délce strany na šířku a na výšku by mohla mít tabulka s cellspacing 1 vykreslená do dokumentu tak, aby tato tabulka viewport nepřesahovala.
3) Pakliže je daná výška či šířka menší než minimální šířka v buňkách nebo minimální výška v buňkách, zmenší algoritmus výchozí délku strany tak, aby ani výška ani šířka nebyly menší než minimální šířka v buňkách nebo minimální výška v buňkách.
4) Algoritmus vygeneruje na základě těchto hodnot danou tabulku.

Účel:
Potřebuji vytvořit tabulku sestávající že čtvercových buněk, která se přizpůsobí rozměrům viewportu a v případě příliš malého počtu buněk na výšku či na šířku jednotlivé čtvercové buňky zmenší právě tak, aby jak výška tak šířka byly nad hranicemi minimálních hodnot.

Problémy:
2) Problém není tak jednoduchý jako šířka, výška viewportu / výchozí délka strany. Díky cellspacingu jsou kolem veškerých buněk jednopixelové okraje. Těchto okrajů je vždy o jedna více než buněk. Daný počet pixelů šířky tohoto ohraničení připadající na jedno políčko ((počet buněk v řádku či sloupci + 1) / počet buněk v řádku či sloupci) je ironicky možné od výchozí délky strany odečíst až poté, co známe výsledek výrazu šířka viewportu / výchozí délka strany a odečtení tento výsledek zpětně znepřesní, což tvoří nekonečnou smyčku. Nemluvě o tom že po odečtení okraje od výchozí délky strany při rozdílné výšce a šířce tabulky změní čtvercové buňky na obdélníčky.
3) Stejný problém jako 2

Doteď jsem používal velice zpatlanou parodii na něco pořádného, která sice tak trochu funguje, ale je nepřesná a nepřesnost se navyšuje s velikostí generované tabulky (tento výřez obsahuje pouze body 2 a 3 algoritmu):
function vypočítejRozměry() {
  šířka = Math.floor(šířkaViewportu / výchozíDélkaStrany) || 1;
  výška = Math.floor(výškaViewportu / výchozíDélkaStrany) || 1;
  šířka += Math.floor((šířka - 1) / (výchozíDélkaStrany - 1 / šířka));
  výška += Math.floor((výška - 1) / (výchozíDélkaStrany - 1 / výška));
  if(šířka < minimálníŠířka || výška < minimálníVýška) {
    výchozíDélkaStrany = Math.min((šířka / minimálníŠířka), (výška / minimálníVýška)) * výchozíDélkaStrany;
    vypočítejRozměry();
    return;
  }
}

Takhle nějak to má vypadat:
Witiko
Profil
Beru to tak, že mi není pomoci.
Moderátor Chamurappi: Porušuješ pravidla. Čekej trpělivě.
Chamurappi
Profil
Reaguji na Witika:
Z toho by měla vylézt nějak rozumně vyřešitelná soustava rovnic, ne? Je pondělí, moc mi to nemyslí, ale na první pohled mi zmíněné postupné přibližování k výsledku nepřipadá nutné.

3) Stejný problém jako 2
Ještě bych doplnil:
4) Neznáme problém 1.
5) Stejný problém jako 5.
Witiko
Profil
Chamurappi:
Ještě bych doplnil:
To nejsou čísla problémů, to jsou čísla kroků algoritmu. Problém mám pouze s druhým a třetím ze 4 zmíněných kroků v Originálním Příspěvku.

Porušuješ pravidla. Čekej trpělivě.
Ten smajlík bych odstranil, ale asi už jsem za časovým limitem na editaci, takže se za to tímto jen omlouvám.

Z toho by měla vylézt nějak rozumně vyřešitelná soustava rovnic, ne?
Matematické řešení mě nenapadá, celkovou šířku okrajů po stranách a mezi buňkami totiž lze vypočítat až po tom, co z délky strany a rozměrů viewportu spočítáme počet segmentů na výšku a na šířku. A jakmile spočítáme celkovou šířku okrajů a započítáme je do výsledku, je vypočítaný počet segmentů na výšku a na šířku opět nepřesný. :-(

Je pondělí, moc mi to nemyslí
A to by jeden čekal, že hnedka po víkendu bude člověk ještě svěží. :-)
_es
Profil
Witiko:
celkovou šířku okrajů po stranách a mezi buňkami totiž lze vypočítat až po tom, co z délky strany a rozměrů viewportu spočítáme počet segmentů na výšku a na šířku.
Počet segmentov, trebárs x, si dáš ako neznámu, potom máš celkovú šírku okrajov pre jednopixelový okraj (x + 1) a normálne to dosadíš do rovnice pre šírku tabuľky v pixeloch.
Stačí ti len tú rovnicu správne zostaviť a vyjadriť z nej x.
Nejaké iterácie nie sú vôbec potrebné.
Witiko
Profil
Ok, přepsal jsem si to na rovnici:
a = délka strany čtverce
b = šířka tabulky (neznámá)
c = výška tabulky (neznámá)
d = šířka viewportu
e = výška viewportu

b = d / (a + 1 / (b + 1))
c = e / (a + 1 / (c + 1))

Po vyjádření (v případě, že jsem to udělal dobře):
b = (-((a - d + 1).pow(2) + 4 * a * d).sqrt() + d - a - 1) / (2 * a)
c = (-((a - e + 1).pow(2) + 4 * a * e).sqrt() + e - a - 1) / (2 * a)
_es
Profil
Witiko:
Nejako tým rovniciam nerozumiem.
Nepomýlil si sa v zátvorkách?
Dĺžkové miery sú všetky v pixeloch?
Alebo sú b a c počet buniek v riadkoch a stĺpcoch?
Witiko
Profil
_es:
Alebo sú b a c počet buniek v riadkoch a stĺpcoch?
Přesně tak, počítám to takto:

počet sloupců = šířka viewportu / (délka strany čtverce + 1 / (počet sloupců + 1))
počet řádků = výška viewportu / (délka strany čtverce + 1 / (počet řádků + 1))

I když to bude chtít ještě zaokrouhlit směrem dolů.
_es
Profil
Základom je zostaviť si najprv rovnice, z ktorých je zrejmé, že sú správne:
b * a + (b + 1) = d
c * a + (c + 1) = e

z toho:
b = (d - 1) / (a + 1)
c = (e - 1) / (a + 1)
A už len treba počty zaokrúhliť na celé číslo dole a zohľadniť tie minimálne hodnoty.
Witiko
Profil
_es:
Jj, je to tak, díky. :-)

Chamurappi
Že to tak na sebe prásknu, tak tady tím pádem porušuji pravidla taky. Tak bych poprosil o smazání, budu tu od nynějška s tagem [img] opatrnější.

Vaše odpověď

Mohlo by se hodit

Neumíte-li správně určit příčinu chyby, vkládejte odkazy na živé ukázky.
Užíváte-li nějakou cizí knihovnu, ukažte odpovídajícím, kde jste ji vzali.

Užitečné odkazy:

Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm: