void REORDER::initFront( ELEM* elem ) { num = updateFront( elem, &frnt, num, 1 ); if( num > max ) max = num; square += num*num; nel--; elem->mark = true; if( prev_el ) prev_el = elem; prev_el = elem; elem->link = (ELEM*) 0; }
void GLWorld::mousePressEvent(QMouseEvent *event) { last_pos = event->pos(); if(!(event->buttons() & Qt::RightButton && current_selection.type != TYPE_NOTHING && editable)) return; WorldObject &here = getObject(current_selection.coords); bool steve_is_here = current_selection.coords == steve; QPoint pos = mapToGlobal(event->pos()); QMenu menu; QAction steve_here(trUtf8("Steve hierher teleportieren"), &menu); steve_here.setDisabled(here.has_cube || steve_is_here); menu.addAction(&steve_here); QAction cube_here(trUtf8("Würfel"), &menu); cube_here.setCheckable(true); cube_here.setChecked(here.has_cube); cube_here.setDisabled(steve_is_here); //No cube into steve menu.addAction(&cube_here); QAction stack_here(trUtf8("Stapel"), &menu); stack_here.setCheckable(true); if(here.stack_size > 0) { stack_here.setChecked(true); stack_here.setText(trUtf8("Stapel (%1)").arg(here.stack_size)); } menu.addAction(&stack_here); QAction mark_here(trUtf8("Markierung"), &menu); mark_here.setCheckable(true); mark_here.setChecked(here.has_mark); menu.addAction(&mark_here); QAction *selected = menu.exec(pos); if(selected == &steve_here) { steve = current_selection.coords; //The user can't be really fast, so animations always on setSpeed(2000); setAnimation(ANIM_STEP); updateAnimationTarget(); updateFront(); fbo_dirty = true; } else if(selected == &cube_here) { here.has_cube = !here.has_cube; here.stack_size = 0; here.has_mark = false; fbo_dirty = true; emit changed(); } else if(selected == &stack_here) { bool ok; int s = QInputDialog::getInt(this, trUtf8("Stapelhöhe"), trUtf8("Stapelhöhe auswählen:"), here.stack_size, 0, World::max_height, 1, &ok); if(ok) { if(s > 0) here.has_cube = false; here.stack_size = s; if(steve == current_selection.coords) { setAnimation(ANIM_STEP); updateAnimationTarget(); } fbo_dirty = true; emit changed(); } } else if(selected == &mark_here) { here.has_mark = !here.has_mark; here.has_cube = false; fbo_dirty = true; emit changed(); } updateSelection(); }
int REORDER::frontWidth( REOFRONT **frnt, int num, int depth, double *square ) { int i; int dp, m, size, min; double sqr, min_sqr; REOFRONT* fr; ELEM** list; if( num == 0 || depth == 0 ) return num; // Anzahl der Elemente an der Front bestimmen size = 0; fr = *frnt; while( fr ) { size += fr->node->noel; fr = fr->next; } list = new ELEM* [size]; if( !list ) REPORT::rpt.Error ("Could not allocate memory - frontWidth (1)"); // Liste der Frontelemente erstellen, die noch nicht erfasst wurden size = frontListOfElems( *frnt, list ); if( size==0 ) { delete[] list; REPORT::rpt.Error ("Unexpected error - frontWidth (2)"); } dp = (minDepth<depth)? (minDepth):(depth-1); do { m = 0; min_sqr = 0.0; for( i=0; i<size; i++ ) { int n; if( !list[i] ) continue; // Front an die Hinzunahme des Elementes list[0] anpassen min = updateFront( list[i], frnt, num, 0 ); // und dann rekursiv weiter sqr = *square + min*min; n = frontWidth( frnt, min, dp, &sqr ); removeFront( list[i], frnt, min ); if( min > n ) n = min; if( !m || n < m ) m = n; if( min_sqr>0.1 && sqr>min_sqr ) { list[i] = (ELEM *) 0; } else if( min_sqr<0.1 || sqr<min_sqr ) { register int j; // wenn list[i] zu einer guenstigeren Frontweite fuehrt ... min_sqr = sqr; for( j=0; j<i; j++ ) list[j] = (ELEM *)0; } } dp++; } while( dp<depth ); delete[] list; *square = min_sqr; return m; }
void REORDER::start() { int min; // minimale Anzahl aktiver Knoten int size; // Anzahl der Elemente an der Front REOFRONT* fr; // Listenzeiger fuer aktiven Knoten ELEM** list; // Liste der Elemente an der Front ELEM* elem; // ausgewaehltes Element aus *list if( !prev_el ) { REPORT::rpt.Error( "no starting element for reordering (REORDER::start - 1)" ); } for( ;; ) { if( num > max ) max = num; if( nel == 0 ) REPORT::rpt.Error( "unexpected error (nel == 0) (REORDER::start - 2)" ); if( num == 0 ) { REPORT::rpt.Error( "\nunexpected error (num == 0) (REORDER::start - 3)\n" ); } // find number of elements at actual front size = 0; fr = frnt; while ( fr ) { size += fr->node->noel; fr = fr->next; } list = new ELEM* [size]; if ( !list ) REPORT::rpt.Error( "can not allocate memory (REORDER::start - 4)" ); // create list of front elements size = frontListOfElems (frnt, list); if ( size == 0 ) { delete[] list; REPORT::rpt.Error ("Unexpected error - reorder (3)"); } elem = list[0]; if ( nel == 1 ) { prev_el->link = elem; elem->link = (ELEM *)0; delete[] list; REPORT::rpt.Screen( 5, " element count down %7d; front width: 0\r", nel ); break; } if ( size > 1 ) { register int i; int depth, m, found; double sqr, min_sqr; // square sum of front width ELEM *el; depth = minDepth; do { found = -1; m = 0; min_sqr = 0.0; for (i=0; i<size; i++) { int n; if (!list[i]) continue; found++; // Front an die Hinzunahme des Elementes list[i] anpassen min = updateFront (list[i], &frnt, num, 0); // maximale Frontweite bis zur Rekursionstiefe depth sqr = square + min*min; n = frontWidth (&frnt, min, depth, &sqr); removeFront (list[i], &frnt, min); if (min > n) n = min; if (!m || n < m) m = n; if (min_sqr>0.1 && sqr>min_sqr) { list[i] = (ELEM *)0; } else if (min_sqr<0.1 || sqr<min_sqr) { register int j; // wenn list[i] zu einer guenstigeren Frontweite fuehrt ... min_sqr = sqr; elem = list[i]; for (j=0; j<i; j++) list[j] = (ELEM *)0; } } depth++; } while ( found > 0 && depth <= maxDepth); // aus allen guenstigen Frontelementen dasjenige waehlen, das // am laengsten in der Liste steht if( found > 1 ) el = chooseElem( list, size ); if( found > 1 && el ) elem = el; } delete[] list; prev_el->link = elem; elem->link = (ELEM *)0; // Front an die Hinzunahme des ausgewaehlten Elementes elem anpassen min = updateFront (elem, &frnt, num, 1); REPORT::rpt.Screen( 5, " element count down %7d; front width: %d \r", nel, min ); nel--; prev_el = elem; num = min; square += num*num; // und dann weiter im 'reordering' } }