[JS] Beschikbare plekken op een raster berekenen

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Blue-eagle
  • Registratie: September 2000
  • Niet online
Voor een proof of concept wil ik een webpagina opzetten met daarop een raster. Er zijn 25 kolommen en evenveel rijen van cellen hebben die elk de afmeting van 40px bij 40px hebben.

Nu kan het zijn dat een aantal cellen bezet zijn, ik wil dan een script maken welke een positie opzoekt waar ik tenminste 3 kolommen en 3 rijen ruimte heb. Deze laatste twee getallen zouden variabel zijn, te bepalen aan de hand van de inhoud welke ik er wil neerzetten.

Nu heb ik gezocht op "determine grid availability" en allerlei variaties hierop, maar ik kom bijzonder weinig tegen met Google. Het is inmiddels ook weer een jaar of 5 geleden dat ik überhaupt iets met ruimtelijke programmatuur heb gedaan.

Kortom: Waar moet ik op zoeken? Is het een rekenkundige functie, moet ik simpelweg recursief loopen? Een duwtje in de juiste richting zou geweldig zijn!

(Dit staat niet in Programming omdat 't mij toch echt specifiek om JS gaat, al zou de gewenste techniek uit alle talen kunnen komen natuurlijk.)

Acties:
  • 0 Henk 'm!

  • Bosmonster
  • Registratie: Juni 2001
  • Laatst online: 22-09 16:31
Gewoon alle mogelijke 3x3 (of andere grootte) spots bekijken of er iets instaat? Vast niet de meest efficiente methode, maar met zo'n simpel vraagstuk maakt dat ook niet zo heel veel uit.

Acties:
  • 0 Henk 'm!

  • Juup
  • Registratie: Februari 2000
  • Niet online
Of je loopt eerst 1x over alle rows heen en houdt bij vanaf welke kolommen er 3 (of meer) plekken leeg zijn.
Daarna loop je alleen over deze cellen heen om tekijken of er 3x3 (of meer) vrij is vanaf die cel (naar rechtsonder)


edit: eigenlijk is dit hetzelfde als wat Bosmonster voorstelt.

[ Voor 13% gewijzigd door Juup op 25-10-2010 23:34 ]

Een wappie is iemand die gevallen is voor de (jarenlange) Russische desinformatiecampagnes.
Wantrouwen en confirmation bias doen de rest.


Acties:
  • 0 Henk 'm!

  • Blue-eagle
  • Registratie: September 2000
  • Niet online
Daar was ik al een beetje bang voor, ik hoopte eigenlijk op iets rekenkundigs wat in enorme rasters gebruikt wordt en qua performance en schaalbaarheid slim zou zijn om te gebruiken..

Huidige oplossing: loop door alle rijen en kolommen, als de cel en zijn onderste X cellen leeg zijn (en per iedere cel ook hun rechter Y cellen leeg zijn) dan heb ik een plek gevonden.

Stress testen op een raster van een paar duizend cellen met random gevulde cellen en het constant opnieuw laten berekenen van beschikbare ruimte met variabele breedtes en hoogtes wisselt nogal qua performance.

Edit: Toch thanks ;)

[ Voor 3% gewijzigd door Blue-eagle op 25-10-2010 23:40 ]


Acties:
  • 0 Henk 'm!

  • Bosmonster
  • Registratie: Juni 2001
  • Laatst online: 22-09 16:31
Dan kun je het ook omdraaien en kijken naar de random ingevulde velden.

Of je cachet alle mogelijke posities van je blokgroottes van te voren.

Sowieso wil je een array-representatie van je matrix en niet continu DOM lookups doen natuurlijk.

Maar goed, misschien dat een wiskundige hier een betere oplossing voor heeft :P

Acties:
  • 0 Henk 'm!

  • Juup
  • Registratie: Februari 2000
  • Niet online
Bosmonster schreef op maandag 25 oktober 2010 @ 23:43:
Sowieso wil je een array-representatie van je matrix.
Misschien kun je het als een bitmap opslaan en dan een mask eroverheen om de aaneengesloten nullen te vinden?

Een wappie is iemand die gevallen is voor de (jarenlange) Russische desinformatiecampagnes.
Wantrouwen en confirmation bias doen de rest.


Acties:
  • 0 Henk 'm!

  • BtM909
  • Registratie: Juni 2000
  • Niet online

BtM909

Watch out Guys...

Ik denk niet dat het een JS probleem is, maar meer een wiskundig probleem.

Ik roep maar even wat, maar heb je ook gezocht op grid path finding. Er zal vast wel een algoritme te verzinnen zijn om hier snel doorheen te scannen :)

Ace of Base vs Charli XCX - All That She Boom Claps (RMT) | Clean Bandit vs Galantis - I'd Rather Be You (RMT)
You've moved up on my notch-list. You have 1 notch
I have a black belt in Kung Flu.


Acties:
  • 0 Henk 'm!

  • Kompaan
  • Registratie: Juni 2009
  • Laatst online: 02-12-2022
Eerste idee om het sneller te maken:

Naast je 2D array ook een 2x 1D array bijhouden hoeveel vrije posities er per rij en kolom zijn, vanuit daar kan je een betere gok doen dan random of alles brute forcen.

Acties:
  • 0 Henk 'm!

  • X-Lars
  • Registratie: Januari 2004
  • Niet online

X-Lars

Just GoT it.

Leuke vrijdagmiddagklus :9

Regel 88 en 95 is de optimalisatie (kun je // commenten om verschil te zien). In het voorbeeld is dat een winst van 63 versus 130 lookups.

De "3" in de aanroep (onload) is de block size. Heb het getest met 3, 4, 5 en 6 (alhoewel 4 en 6 dubieuze centers hebben...).

Het kan vast nog wel beter, ik doe bijvoorbeeld niets recursief. Toch denk ik dat de performance wel in orde is.

HTML:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <title>Grid availability</title>
        <style type="text/css">
            td {
                height:40px;
                width:40px;
                color:white;
                vertical-align:middle;
                text-align:center;
                border:2px solid white;
            }
        </style>
        <script type="text/javascript">
        
            Array.min = function( array ){
                return Math.min.apply( Math, array );
            };

            var app = {};
            
            app.findSweetSpot = function(iBlockSize) {
                
                var iStart = Math.ceil(iBlockSize / 2) - iBlockSize;
                var iNumberOfLookups = 0, iNumberOfCellsAnalyzed = 0;
                
                var oGrid = document.getElementById('grid');
                var aGrid = [], aGridCache = [], aRows = oGrid.getElementsByTagName('tr'), aCells = [];

                // Populate array (representing table/grid in DOM)
                var i, j, k, l;
                for(i = 0, iLength = aRows.length; i < iLength; i++) {
                    aCells[i] = aRows[i].getElementsByTagName('td');
                    aGrid[i] = [];
                    for(j = 0, jLength = aCells[i].length; j < jLength; j++) {
                        aCells[i][j].style.backgroundColor = 'orange';
                        aGrid[i][j] = aCells[i][j].innerHTML === ''; // The evaluation for "available" cell
                    }
                }
                
                // Lookup surrounding array elements (depending on block size)
                var isBlockAvailable = function(x, y) {
                    var m, n;
                    for(m = 0; m < iBlockSize; m++) {
                        for(n = 0; n < iBlockSize; n++) {
                            xm = x + iStart + m;
                            yn = y + iStart + n
                            
                            // Debug stuff
                            console.info('Analyzing', 'cell:', x+1, y+1, 'blockcell:', m+1, n+1, 'avail:', aGrid[xm][yn]);
                            aCells[xm][yn].innerHTML = aCells[xm][yn].innerHTML && aCells[xm][yn].innerHTML !== 'X' ? parseInt(aCells[xm][yn].innerHTML) + 1 : 1;
                            iNumberOfLookups++;
                            if(!aCells[xm][yn]._analyzed) {
                                iNumberOfCellsAnalyzed++;
                                aCells[xm][yn]._analyzed = true;
                                aCells[xm][yn].style.backgroundColor = 'blue';
                            }
                            // End debug stuff

                            if(aGrid[xm][yn] === false) {
                                return [false, m, n];
                            }
                        }
                    }
                    return [true];
                };
                
                // Walk rows and columns
                // Use center cell as basis
                // Skip outer rows and columns based on block size
                // Optimize route by skipping rows/columns
                var searchAvailableBlock = function(aGrid) {
                    var aRow, aOptimizer, aOptimizerY = [];
                    for(k = 0 - iStart, kLength = aGrid.length + iStart; k < kLength; k++) {
                        aRow = aGrid[k];
                        for(l = 0 - iStart, lLength = aRow.length + iStart; l < lLength; l++) {
                            console.group('Lookup availability for', 'row', k+1, 'column', l+1);
                            aOptimizer = isBlockAvailable(k, l);
                            if(aOptimizer[0]) {
                                console.groupEnd();
                                return [k, l];                              
                            } else {
                                console.info('Skipping ' + aOptimizer[2] + ' columns');
                                l += aOptimizer[2];
                                aOptimizerY.push(aOptimizer[1]);
                            }
                            console.groupEnd();
                        }
                        if(aOptimizerY.length > 0) {
                            console.info('Skipping ' + Array.min(aOptimizerY) + ' rows')
                            k += Array.min(aOptimizerY);
                            aOptimizerY = [];
                        }                       
                    }
                };

                var aResult = searchAvailableBlock(aGrid);
                if(aResult) {
                    aCells[aResult[0]][aResult[1]].style.backgroundColor = 'red';
                }
                console.info('Number of cells analyzed: ' + iNumberOfCellsAnalyzed)
                console.info('Number of total cell lookups: ' + iNumberOfLookups)               
                
            };
            
        </script>
    </head>
    <body onload="app.findSweetSpot(3);">
        <table id="grid">
            <tr>
                <td></td>
                <td></td>
                <td></td>
                <td></td>
                <td></td>
                <td></td>
                <td></td>
                <td></td>
                <td></td>
            </tr>
            <tr>
                <td></td>
                <td></td>
                <td style="border-color:red;">X</td>
                <td></td>
                <td></td>
                <td></td>
                <td></td>
                <td></td>
                <td style="border-color:red;">X</td>
            </tr>
            <tr>
                <td></td>
                <td></td>
                <td></td>
                <td></td>
                <td></td>
                <td style="border-color:red;">X</td>
                <td></td>
                <td></td>
                <td></td>
            </tr>
            <tr>
                <td></td>
                <td></td>
                <td></td>
                <td></td>
                <td></td>
                <td></td>
                <td></td>
                <td style="border-color:red;">X</td>
                <td></td>
            </tr>
            <tr>
                <td></td>
                <td style="border-color:red;">X</td>
                <td></td>
                <td style="border-color:red;">X</td>
                <td></td>
                <td></td>
                <td></td>
                <td></td>
                <td></td>
            </tr>
            <tr>
                <td></td>
                <td></td>
                <td></td>
                <td></td>
                <td></td>
                <td></td>
                <td></td>
                <td></td>
                <td></td>
            </tr>
            <tr>
                <td></td>
                <td></td>
                <td></td>
                <td></td>
                <td></td>
                <td></td>
                <td></td>
                <td></td>
                <td></td>
            </tr>
            <tr>
                <td></td>
                <td></td>
                <td style="border-color:red;">X</td>
                <td></td>
                <td></td>
                <td></td>
                <td></td>
                <td></td>
                <td></td>
            </tr>
            <tr>
                <td></td>
                <td></td>
                <td></td>
                <td></td>
                <td></td>
                <td></td>
                <td></td>
                <td></td>
                <td></td>
            </tr>
        </table>
    </body>
</html>



PS Nog nooit was "Zen coding" in Textmate zo nuttig: met "table#grid>tr*9>td*9" en Cmd-e stond de tabel er.

Acties:
  • 0 Henk 'm!

  • tonyisgaaf
  • Registratie: November 2000
  • Niet online
X-Lars schreef op vrijdag 29 oktober 2010 @ 17:19:
[...]
PS Nog nooit was "Zen coding" in Textmate zo nuttig: met "table#grid>tr*9>td*9" en Cmd-e stond de tabel er.
offtopic:
You've made my day. Dat kende ik nog niet. De overtreffende trap van snippets. Dank!

NL Weerradar widget Euro Stocks widget Brandstofprijzen widget voor 's Dashboard

Pagina: 1