/*! First all intersections are calculated. Then duplicates are removed. If only points on the line are required, all points that are outside the lnX[A,B] are removed. If bParallel is true, parallel segmets are checked for overlap and overlap points are included in the solution. \retval VecVertex container of intersection points. */ QVector<Point2D> Polygon2D::GetIntersection( const Line2D& lnX, //!< line that intersects the polygon bool bOnLineOnly, //!< if true, only points between A and B inclusive are counted. bool bParallel //!< check parallel lines for overlap ) const { // results are stored here QVector<Point2D> vecInt; // for each segment for(unsigned int i=0; i<GetCount(); i++) { Line2D ln = GetLine(i); Q_ASSERT(ln.IsValid()); Point2D ptInt; // Check overlaps, if they are wanted if(bParallel && ln.IsParallel(lnX)) { Line2D lnO = ln.GetOverlap(lnX); if(lnO.IsValid()) { vecInt.push_back(lnO.GetA()); vecInt.push_back(lnO.GetB()); } } // check intersections if(ln.GetIntersection(lnX, ptInt) & Line2D::intFirst){ vecInt.push_back(ptInt); } } // Sort the points in the vector. Same point may appear several // times. Point2DSortLineLess pred(lnX); std::sort(vecInt.begin(),vecInt.end(),pred); // remove duplicates, if any QVector<Point2D>::iterator f = std::unique(vecInt.begin(),vecInt.end()); vecInt.erase(f,vecInt.end()); // remove all points that are not inside the line if(bOnLineOnly) { QVector<Point2D>::iterator i=vecInt.begin(); while(i!=vecInt.end()) { if(!(lnX.GetPosition(*i) & Line2D::posInsideEnd)) i = vecInt.erase(i); else i++; } } return vecInt; }
static inline void findNextWords ( QVector<uint64_t> & src, const QVector<uint64_t> & needle ) { for ( int s1 = 0; s1 < src.size(); s1++ ) { bool found = false; uint64_t target_offset = src[s1] + 1; DEBUG_SEARCH (("Offset loop: offset at %u is %u, target %u", (unsigned int) s1, (unsigned int) src[s1], (unsigned int) target_offset)); // Search in the offsets list in attempt to find next word for ( int s2 = 0; s2 < needle.size(); s2++ ) { if ( needle[s2] == target_offset ) { found = true; break; } } if ( !found ) { // Remove this offset, we don't need it anymore DEBUG_SEARCH (("Offset loop failed: offset %u not found", (unsigned int) target_offset)); src.erase ( src.begin() + s1 ); s1--; } else { DEBUG_SEARCH (("Offset loop succeed: offset %u found", (unsigned int) target_offset)); src[s1]++; } } }
QVector< Dwarf_Half > DwarfDie::attributes() const { Dwarf_Attribute* attrList; Dwarf_Signed attrCount; auto res = dwarf_attrlist(m_die, &attrList, &attrCount, nullptr); if (res != DW_DLV_OK) return {}; QVector<Dwarf_Half> attrs; attrs.reserve(attrCount); for (int i = 0; i < attrCount; ++i) { Dwarf_Half attrType; res = dwarf_whatattr(attrList[i], &attrType, nullptr); if (res != DW_DLV_OK) continue; attrs.push_back(attrType); } dwarf_dealloc(dwarfHandle(), attrList, DW_DLA_LIST); if (const auto die = inheritedFrom()) { auto inheritedAttrs = die->attributes(); // remove attributes that must not be inherited inheritedAttrs.erase( std::remove_if(inheritedAttrs.begin(), inheritedAttrs.end(), [](Dwarf_Half at) { return at == DW_AT_declaration || at == DW_AT_sibling; }), inheritedAttrs.end()); attrs += inheritedAttrs; std::sort(attrs.begin(), attrs.end()); attrs.erase(std::unique(attrs.begin(), attrs.end()), attrs.end()); } return attrs; }
QVector<QString> *lc::ReceiptsHandler::GetParticipantsDataFromPaymentFile() { // Create the vector to store the single lines of the file QVector<QString> *participantsData = new QVector<QString>; // Open the payment file for reading and create a QTextStream paymentFile.open( QIODevice::ReadOnly | QIODevice::Text ); QTextStream in( &paymentFile ); in.setCodec( "ISO 8859-1" ); // Read the file line by line and store them in the vector while ( true ) { QString line = in.readLine(); if ( line.isNull() ) { break; } participantsData->append( line ); } // Remove the first line, since it is not needed participantsData->erase( participantsData->begin() ); // Close the file afterwards paymentFile.close(); return participantsData; }
void SelekcjaTurniejowa::selekcja(Populacja *populacja) { std::cout<<"============SELEKCJA TURNIEJOWA=============="<<std::endl; QVector<Osobnik*> tmp; for(int i=0; i<populacja->proporcja;++i) { for(int j=0; j<5; ++j) { int x=qrand()%populacja->populacja.size(); tmp.push_back(populacja->populacja[x]); } qSort(tmp.begin(),tmp.end(),osobnikSelect); tmp.erase(tmp.begin(),tmp.end()); populacja->wynikSelekcji[i]->kopiujOsobnika(tmp[0]); } std::cout<<"============STOP SELEKCJA TURNIEJOWA=============="<<std::endl; }
// Returns true if this node is to be deleted. static bool nodePruneAction_impl( Process::MessageNode& node, const Id<Process::ProcessModel>& proc, QVector<Process::ProcessStateData>& vec, const QVector<Process::ProcessStateData>& other_vec) { int vec_size = vec.size(); if(vec_size > 1) { // We just remove the element // corresponding to this process. auto it = find_if(vec, [&] (const auto& data) { return data.process == proc; }); if(it != vec.end()) { vec.erase(it); } } else if(vec_size == 1) { // We may be able to remove the whole node if(vec.front().process == proc) vec.clear(); // If false, nothing is removed. return vec.isEmpty() && other_vec.isEmpty() && !node.values.userValue; } return false; }
void AbstractResourcesBackend::Filters::filterJustInCase(QVector<AbstractResource *>& input) const { for(auto it = input.begin(); it != input.end();) { if (shouldFilter(*it)) ++it; else it = input.erase(it); } }
Handle(Standard_Type) Subassembly::lookupType ( QVector<uint>& id_path ) const { if ( subassembly_->id() == id_path[0] ) { id_path.erase( id_path.begin() ); return subassembly_->lookupType( id_path ); } return Handle(Standard_Type)(); }
static bool removeFromFileContainer(QVector<FileContainer> &fileContainers, const Document &document) { auto position = std::remove(fileContainers.begin(), fileContainers.end(), document); bool entryIsRemoved = position != fileContainers.end(); fileContainers.erase(position, fileContainers.end()); return entryIsRemoved; }
TopoDS_Shape Subassembly::lookupShape ( QVector<uint>& id_path ) const { TopoDS_Shape shape; if ( subassembly_->id() == id_path[0] ) { id_path.erase( id_path.begin() ); shape = subassembly_->lookupShape( id_path ); shape.Location( location_ * shape.Location() ); } return shape; }
TopoDS_Shape Assembly::lookupShape ( QVector<uint>& id_path ) const { QMap<uint,Figure*>::const_iterator figure = figures_.find( id_path[0] ); if ( figure != figures_.end() ) { id_path.erase( id_path.begin() ); if ( !id_path.empty() ) return figure.value()->lookupShape( id_path ); } return TopoDS_Shape(); // Really an error... }
QString Subassembly::idPath ( QVector<uint> id_path ) const { if ( subassembly_->id() != id_path[0] ) return QString::null; // Really an error... id_path.erase( id_path.begin() ); if ( id_path.empty() ) return subassembly_->name() + '.' + subassembly_->type(); return subassembly_->name() + '.' + subassembly_->type() + '/' + subassembly_->idPath( id_path ); }
QVector<selectableObject *> RubberBand::selectedObjects() const { QVector<selectableObject *> so = selectableObjects(); for( QVector<selectableObject *>::iterator it = so.begin(); it != so.end(); ) { if( ( *it )->isSelected() == false ) { it = so.erase( it ); } else { ++it; } } return( so ); }
QString Assembly::idPath ( QVector<uint> id_path ) const { // The argument path must not have zero length, i.e., it must // refer to a figure (the Model has already taken care of // including *this* page in the path string). QMap<uint,Figure*>::const_iterator f = figures_.find( id_path[0] ); if ( f == figures_.end() ) return QString::null; // Really an error... id_path.erase( id_path.begin() ); if ( id_path.empty() ) return f.value()->name() + '.' + f.value()->type(); return f.value()->name() + '.' + f.value()->type() + '/' + f.value()->idPath( id_path ); }
QVector<UpdateInfo> UpdatesInfo::updatesInfo( int type, int compatLevel ) const { QVector<UpdateInfo> list; if ( compatLevel == -1 ) { if ( type == AllUpdate ) { return d->updateInfoList; } std::remove_copy_if( d->updateInfoList.begin(), d->updateInfoList.end(), std::back_inserter( list ), std::not1( TypeIs( type ) ) ); } else { // first remove all wrong types std::remove_copy_if( d->updateInfoList.begin(), d->updateInfoList.end(), std::back_inserter( list ), std::not1( TypeIs( type ) ) ); // the remove all wrong compat levels list.erase( std::remove_if( list.begin(), list.end(), CompatLevelIsNot( compatLevel ) ), list.end() ); } return list; }
//# if constant-expression newline group[opt] bool Preprocessor::parseIfLikeDirective(IfLikeDirective *node) { //cout << "parse if-like directive" << endl; Q_ASSERT(node->toItemComposite()); TokenSection tokenSection = readLine(); QVector<int> cleanedSection = cleanTokenRange(tokenSection); if(cleanedSection.count() < 3) return false; cleanedSection.erase(cleanedSection.begin(), cleanedSection.begin() + 2); //remove # and if cleanedSection.pop_back(); //remove endl; const TokenList sectionList(m_tokenContainer, cleanedSection); ExpressionBuilder expressionBuilder(sectionList, m_tokenTypeList, m_memoryPool); Expression *expr = expressionBuilder.parse(); node->setTokenSection(tokenSection); node->setExpression(expr); parseGroup(node); return true; }
void principal::on_pushButton_2_clicked() { QMessageBox::StandardButton mensaje; mensaje = QMessageBox::question(this, "Control de eliminacion", "Seguro de Eliminar", QMessageBox::Yes|QMessageBox::No); if (mensaje == QMessageBox::Yes) { lista.erase(lista.begin()+::posicion); QMessageBox::about(this,"Control de Eliminacion","Fue eliminado"); QFile archivo1("/home/jossy/proyecto/llenados.txt"); archivo1.open(QIODevice::WriteOnly | QIODevice::Truncate); QFile archivo("/home/jossy/proyecto/base09.txt"); archivo.open(QIODevice::WriteOnly | QIODevice::Truncate); // QTextStream escribir(&archivo); QTextStream escribir1(&archivo1); for(int i=0; i<lista.size();i++){ QString txt= lista[i]->getplaca()+","+lista[i]->getmarca()+","+QString::number(lista[i]->getcilindraje()); escribir << txt <<endl; QString subtxt =lista[i]->getplaca(); for(int r=0; r<lista[i]->getLista().size();r++){ subtxt +=lista[i]->getLista()[r].toString(); } escribir1 << subtxt <<endl; } archivo.close(); archivo1.close(); ui->combo_2->clear(); for(int i=0; i<lista.size();i++){ ui->combo_2->addItem(lista[i]->getplaca()); } } else { QMessageBox::about(this,"Control de Eliminacion","Proceso Cancelado"); } ui->detalles_2->setText(""); }
QList< QUrl > Index::query(const QStringList &terms, const QStringList &termSeq, const QStringList &seqWords, EBook *chmFile ) { QList<Term> termList; QStringList::ConstIterator it = terms.begin(); for ( it = terms.begin(); it != terms.end(); ++it ) { Entry *e = 0; if ( dict[ *it ] ) { e = dict[ *it ]; termList.append( Term( *it, e->documents.count(), e->documents ) ); } else { return QList< QUrl >(); } } if ( !termList.count() ) return QList< QUrl >(); qSort( termList ); QVector<Document> minDocs = termList.takeFirst().documents; for(QList<Term>::Iterator it = termList.begin(); it != termList.end(); ++it) { Term *t = &(*it); QVector<Document> docs = t->documents; for(QVector<Document>::Iterator minDoc_it = minDocs.begin(); minDoc_it != minDocs.end(); ) { bool found = false; for (QVector<Document>::ConstIterator doc_it = docs.constBegin(); doc_it != docs.constEnd(); ++doc_it ) { if ( (*minDoc_it).docNumber == (*doc_it).docNumber ) { (*minDoc_it).frequency += (*doc_it).frequency; found = true; break; } } if ( !found ) minDoc_it = minDocs.erase( minDoc_it ); else ++minDoc_it; } } QList< QUrl > results; qSort( minDocs ); if ( termSeq.isEmpty() ) { for(QVector<Document>::Iterator it = minDocs.begin(); it != minDocs.end(); ++it) results << docList.at((int)(*it).docNumber); return results; } QUrl fileName; for(QVector<Document>::Iterator it = minDocs.begin(); it != minDocs.end(); ++it) { fileName = docList[ (int)(*it).docNumber ]; if ( searchForPhrases( termSeq, seqWords, fileName, chmFile ) ) results << fileName; } return results; }
QVector<QVector<double>> inverse(QVector<QVector<double>> a) { int m = a.size(); int n = a.front().size(); if(n!=m) { qDebug() << "n!=m"; return a; } //Единичная матрица QVector<double> e(n,0); QVector<QVector<double>> one(n,e); for(int i =0; i<n;i++) { one[i][i]=1; } //Объединение for(int i = 0; i < n; i++) { a[i]+=one[i]; } int nn=n+n; //Прямой ход for(int k = 0; k < m; k++) { double akk = a[k][k]; if(akk==0) { qDebug() << "front element equal 0"; } for(int i = 0; i<nn; i++) { if(a[k][i]!=0) { a[k][i]/=akk; } } for(int i = k+1; i<m; i++) { double front_el = a[i][k]; for(int j = k; j<nn; j++) { a[i][j]-=front_el*a[k][j]; } } } for(int k = m-1; k>=0; k--) { for(int i = k-1; i>=0; i--) { double front_el = a[i][k]; for(int j = k; j<nn;j++) { a[i][j]-=front_el*a[k][j]; } } } QVector<QVector<double>> L; for(int i = 0; i<m;i++) { QVector<double> tmp; tmp = a[i]; tmp.erase(tmp.begin()+n,tmp.end()); L.push_back(tmp); a[i].erase(a[i].begin(),a[i].begin()+n); } return a; }
void QDeclarativeChangeSet::applyRemovals(QVector<Remove> &removals, QVector<Insert> &insertions) { int removeCount = 0; int insertCount = 0; QVector<Insert>::iterator insert = m_inserts.begin(); QVector<Change>::iterator change = m_changes.begin(); QVector<Remove>::iterator rit = removals.begin(); for (; rit != removals.end(); ++rit) { int index = rit->index + removeCount; int count = rit->count; QVector<Insert>::iterator iit = insertions.begin(); for (; rit->moveId != -1 && iit != insertions.end() && iit->moveId != rit->moveId; ++iit) {} for (; change != m_changes.end() && change->end() < rit->index; ++change) {} for (; change != m_changes.end() && change->index > rit->end(); ++change) { change->count -= qMin(change->end(), rit->end()) - qMax(change->index, rit->index); if (change->count == 0) { change = m_changes.erase(change); } else if (rit->index < change->index) { change->index = rit->index; } } for (; insert != m_inserts.end() && insert->end() <= index; ++insert) { insertCount += insert->count; insert->index -= removeCount; } for (; insert != m_inserts.end() && insert->index < index + count; ++insert) { const int offset = insert->index - index; const int difference = qMin(insert->end(), index + count) - qMax(insert->index, index); const int moveId = rit->moveId != -1 ? m_moveCounter++ : -1; if (insert->moveId != -1) { QVector<Remove>::iterator remove = m_removes.begin(); for (; remove != m_removes.end() && remove->moveId != insert->moveId; ++remove) {} Q_ASSERT(remove != m_removes.end()); const int offset = index - insert->index; if (rit->moveId != -1 && offset < 0) { const int moveId = m_moveCounter++; iit = insertions.insert(iit, Insert(iit->index, -offset, moveId)); ++iit; iit->index += -offset; iit->count -= -offset; rit = removals.insert(rit, Remove(rit->index, -offset, moveId)); ++rit; rit->count -= -offset; } if (offset > 0) { const int moveId = m_moveCounter++; insert = m_inserts.insert(insert, Insert(insert->index, offset, moveId)); ++insert; insert->index += offset; insert->count -= offset; remove = m_removes.insert(remove, Remove(remove->index, offset, moveId)); ++remove; remove->count -= offset; rit->index -= offset; index += offset; count -= offset; } if (remove->count == difference) { remove->moveId = moveId; } else { remove = m_removes.insert(remove, Remove(remove->index, difference, moveId)); ++remove; remove->count -= difference; } } else if (rit->moveId != -1 && offset > 0) { const int moveId = m_moveCounter++; iit = insertions.insert(iit, Insert(iit->index, offset, moveId)); ++iit; iit->index += offset; iit->count -= offset; rit = removals.insert(rit, Remove(rit->index, offset, moveId)); ++rit; rit->count -= offset; index += offset; count -= offset; } if (rit->moveId != -1 && difference > 0) { iit = insertions.insert(iit, Insert(iit->index, difference, moveId)); ++iit; iit->index += difference; iit->count -= difference; } insert->count -= difference; rit->count -= difference; if (insert->count == 0) { insert = m_inserts.erase(insert); --insert; } else if (index <= insert->index) { insert->index = rit->index; } else { rit->index -= insert->count; } index += difference; count -= difference; removeCount += difference; } rit->index -= insertCount; removeCount += rit->count; if (rit->count == 0) { if (rit->moveId != -1 && iit->count == 0) insertions.erase(iit); rit = removals.erase(rit); --rit; } else if (rit->moveId != -1) { const int moveId = m_moveCounter++; rit->moveId = moveId; iit->moveId = moveId; } } for (; change != m_changes.end(); ++change) change->index -= removeCount; for (; insert != m_inserts.end(); ++insert) insert->index -= removeCount; removeCount = 0; QVector<Remove>::iterator remove = m_removes.begin(); for (rit = removals.begin(); rit != removals.end(); ++rit) { QVector<Insert>::iterator iit = insertions.begin(); int index = rit->index + removeCount; for (; rit->moveId != -1 && iit != insertions.end() && iit->moveId != rit->moveId; ++iit) {} for (; remove != m_removes.end() && index > remove->index; ++remove) remove->index -= removeCount; while (remove != m_removes.end() && index + rit->count > remove->index) { int count = 0; const int offset = remove->index - index - removeCount; QVector<Remove>::iterator rend = remove; for (; rend != m_removes.end() && rit->moveId == -1 && rend->moveId == -1 && rit->index + rit->count > rend->index; ++rend) { count += rend->count; } if (remove != rend) { const int difference = rend == m_removes.end() || rit->index + rit->count < rend->index - removeCount ? rit->count : offset; count += difference; index += difference; rit->count -= difference; removeCount += difference; remove->index = rit->index; remove->count = count; remove = m_removes.erase(++remove, rend); } else if (rit->moveId != -1) { if (offset > 0) { const int moveId = m_moveCounter++; iit = insertions.insert(iit, Insert(iit->index, offset, moveId)); ++iit; iit->index += offset; iit->count -= offset; remove = m_removes.insert(remove, Remove(rit->index, offset, moveId)); ++remove; rit->count -= offset; } remove->index = rit->index; index += offset; removeCount += offset; ++remove; } else { if (offset > 0) { remove = m_removes.insert(remove, Remove(rit->index, offset)); ++remove; rit->count -= offset; } remove->index = rit->index; index += offset; removeCount += offset; ++remove; } index += count; rit->count -= count; } if (rit->count > 0) { remove = m_removes.insert(remove, *rit); ++remove; } removeCount += rit->count; } for (; remove != m_removes.end(); ++remove) remove->index -= removeCount; }
/*! Initialized the ProxyBase Object. This needs to be run before any other functions are called. See the class description for an example of how to use this function @param funclist A list of strings to be used when searching for functions calls @param callbacklist A list of strings to used when searching for callbacks @param eventlist A list of strings to used when searching for events */ void ProxyBase::init(QStringList functionlist, QStringList callbacklist, QStringList eventlist) { QMutexLocker locker(&qxt_d().mutex); //Initialize method counters int numfunctions = 1000; //clear old lists in case init() is run twice qxt_d().signalHash.clear(); qxt_d().functions.clear(); qxt_d().callbacks.clear(); qxt_d().asyncfunctions.clear(); //Get the meta object so we can see signals and slots const QMetaObject *meta = metaObject(); //Get the number of methods int methods = meta->methodCount(); //loop through all the methods for (int i = 0; i < methods; i++) { QMetaMethod method = meta->method(i); QString type = method.typeName(); Signature sig(method.signature()); // This checks to see if it's a cloned signal, and continues if it is... // Undocumented private API ftl!!! if (method.attributes() && 2) continue; switch (method.methodType()) { case QMetaMethod::Signal: if (functionlist.contains(type)) { //If a function begins with QObject*, char*, then its an asyn function if (sig.numArgs() >= 2 && sig.arg(0) == "QObject*" && (sig.arg(1) == "const char*" || sig.arg(1) == "char*")) { qxt_d().asyncfunctions << numfunctions; //add this function id to the list of async functions QVector<QString> args = sig.args(); //get the list of arguments //remove the first two arguments args.erase(args.begin()); args.erase(args.begin()); sig.setArgs(args); //update the argument list with the new list } Q_ASSERT(sig.validate()); //connect the signal to a local event meta->connect(this, i, this, numfunctions, Qt::DirectConnection); qxt_d().functions[numfunctions] = sig; qxt_d().functiontypes[numfunctions] = method.typeName(); numfunctions++; } else if (eventlist.contains(type)) { Q_ASSERT(sig.validate()); qxt_d().signalHash[i] = sig; } //if its not one of the two, we don't care about it break; case QMetaMethod::Slot: if (callbacklist.contains(type)) { Q_ASSERT(sig.validate()); qxt_d().callbacks[i] = sig; } break; default: //We don't really care about other types of methods break; } } }
void OsmAnd::Utilities::scanlineFillPolygon(const unsigned int verticesCount, const PointF* vertices, std::function<void(const PointI&)> fillPoint) { // Find min-max of Y float yMinF, yMaxF; yMinF = yMaxF = vertices[0].y; for(auto idx = 1u; idx < verticesCount; idx++) { const auto& y = vertices[idx].y; if (y > yMaxF) yMaxF = y; if (y < yMinF) yMinF = y; } const auto rowMin = qFloor(yMinF); const auto rowMax = qFloor(yMaxF); // Build set of edges struct Edge { const PointF* v0; int startRow; const PointF* v1; int endRow; float xOrigin; float slope; int nextRow; }; QVector<Edge*> edges; edges.reserve(verticesCount); auto edgeIdx = 0u; for(auto idx = 0u, prevIdx = verticesCount - 1; idx < verticesCount; prevIdx = idx++) { auto v0 = &vertices[prevIdx]; auto v1 = &vertices[idx]; if (v0->y == v1->y) { // Horizontal edge auto edge = new Edge(); edge->v0 = v0; edge->v1 = v1; edge->startRow = qFloor(edge->v0->y); edge->endRow = qFloor(edge->v1->y); edge->xOrigin = edge->v0->x; edge->slope = 0; edge->nextRow = qFloor(edge->v0->y) + 1; edges.push_back(edge); //LogPrintf(LogSeverityLevel::Debug, "Edge %p y(%d %d)(%f %f), next row = %d", edge, edge->startRow, edge->endRow, edge->v0->y, edge->v1->y, edge->nextRow); continue; } const PointF* pLower = nullptr; const PointF* pUpper = nullptr; if (v0->y < v1->y) { // Up-going edge pLower = v0; pUpper = v1; } else if (v0->y > v1->y) { // Down-going edge pLower = v1; pUpper = v0; } // Fill edge auto edge = new Edge(); edge->v0 = pLower; edge->v1 = pUpper; edge->startRow = qFloor(edge->v0->y); edge->endRow = qFloor(edge->v1->y); edge->slope = (edge->v1->x - edge->v0->x) / (edge->v1->y - edge->v0->y); edge->xOrigin = edge->v0->x - edge->slope * (edge->v0->y - qFloor(edge->v0->y)); edge->nextRow = qFloor(edge->v1->y) + 1; for(auto vertexIdx = 0u; vertexIdx < verticesCount; vertexIdx++) { const auto& v = vertices[vertexIdx]; if (v.y > edge->v0->y && qFloor(v.y) < edge->nextRow) edge->nextRow = qFloor(v.y); } //LogPrintf(LogSeverityLevel::Debug, "Edge %p y(%d %d)(%f %f), next row = %d", edge, edge->startRow, edge->endRow, edge->v0->y, edge->v1->y, edge->nextRow); edges.push_back(edge); } // Sort edges by ascending Y qSort(edges.begin(), edges.end(), [](Edge* l, Edge* r) -> bool { return l->v0->y > r->v0->y; }); // Loop in [yMin .. yMax] QVector<Edge*> aet; aet.reserve(edges.size()); for(auto rowIdx = rowMin; rowIdx <= rowMax;) { //LogPrintf(LogSeverityLevel::Debug, "------------------ %d -----------------", rowIdx); // Find active edges int nextRow = rowMax; for(const auto& edge : constOf(edges)) { const auto isHorizontal = (edge->startRow == edge->endRow); if (nextRow > edge->nextRow && edge->nextRow > rowIdx && !isHorizontal) nextRow = edge->nextRow; if (edge->startRow != rowIdx) continue; if (isHorizontal) { // Fill horizontal edge const auto xMin = qFloor(qMin(edge->v0->x, edge->v1->x)); const auto xMax = qFloor(qMax(edge->v0->x, edge->v1->x)); /*for(auto x = xMin; x <= xMax; x++) fillPoint(PointI(x, rowIdx));*/ continue; } //LogPrintf(LogSeverityLevel::Debug, "line %d. Adding edge %p y(%f %f)", rowIdx, edge, edge->v0->y, edge->v1->y); aet.push_back(edge); continue; } // If there are no active edges, we've finished filling if (aet.isEmpty()) break; assert(aet.size() % 2 == 0); // Sort aet by X qSort(aet.begin(), aet.end(), [](Edge* l, Edge* r) -> bool { return l->v0->x > r->v0->x; }); // Find next row for(; rowIdx < nextRow; rowIdx++) { const unsigned int pairsCount = aet.size() / 2; auto itEdgeL = aet.cbegin(); auto itEdgeR = itEdgeL + 1; for(auto pairIdx = 0u; pairIdx < pairsCount; pairIdx++, itEdgeL = ++itEdgeR, ++itEdgeR) { auto lEdge = *itEdgeL; auto rEdge = *itEdgeR; // Fill from l to r auto lXf = lEdge->xOrigin + (rowIdx - lEdge->startRow + 0.5f) * lEdge->slope; auto rXf = rEdge->xOrigin + (rowIdx - rEdge->startRow + 0.5f) * rEdge->slope; auto xMinF = qMin(lXf, rXf); auto xMaxF = qMax(lXf, rXf); auto xMin = qFloor(xMinF); auto xMax = qFloor(xMaxF); LogPrintf(LogSeverityLevel::Debug, "line %d from %d(%f) to %d(%f)", rowIdx, xMin, xMinF, xMax, xMaxF); /*for(auto x = xMin; x <= xMax; x++) fillPoint(PointI(x, rowIdx));*/ } } // Deactivate those edges that have end at yNext for(auto itEdge = aet.begin(); itEdge != aet.end();) { auto edge = *itEdge; if (edge->endRow <= nextRow) { // When we're done processing the edge, fill it Y-by-X auto startCol = qFloor(edge->v0->x); auto endCol = qFloor(edge->v1->x); auto revSlope = 1.0f / edge->slope; auto yOrigin = edge->v0->y - revSlope * (edge->v0->x - qFloor(edge->v0->x)); auto xMax = qMax(startCol, endCol); auto xMin = qMin(startCol, endCol); for(auto colIdx = xMin; colIdx <= xMax; colIdx++) { auto yf = yOrigin + (colIdx - startCol + 0.5f) * revSlope; auto y = qFloor(yf); LogPrintf(LogSeverityLevel::Debug, "col %d(s%d) added Y = %d (%f)", colIdx, colIdx - startCol, y, yf); fillPoint(PointI(colIdx, y)); } ////////////////////////////////////////////////////////////////////////// auto yMax = qMax(edge->startRow, edge->endRow); auto yMin = qMin(edge->startRow, edge->endRow); for(auto rowIdx_ = yMin; rowIdx_ <= yMax; rowIdx_++) { auto xf = edge->xOrigin + (rowIdx_ - edge->startRow + 0.5f) * edge->slope; auto x = qFloor(xf); LogPrintf(LogSeverityLevel::Debug, "row %d(s%d) added Y = %d (%f)", rowIdx_, rowIdx_ - edge->startRow, x, xf); fillPoint(PointI(x, rowIdx_)); } ////////////////////////////////////////////////////////////////////////// //LogPrintf(LogSeverityLevel::Debug, "line %d. Removing edge %p y(%f %f)", rowIdx, edge, edge->v0->y, edge->v1->y); itEdge = aet.erase(itEdge); } else ++itEdge; } } // Cleanup for(const auto& edge : constOf(edges)) delete edge; }