vector<Interval> getIntervals() { vector<Interval> ret; for (auto& elm : intervals_) ret.push_back(Interval(elm.first, elm.second)); return ret; }
void test() { testForIntersection(Interval(Point(2,2), Point(5,5)), Interval(Point(2,5), Point(5,2)), true); // да testForIntersection(Interval(Point(2,2), Point(3,3)), Interval(Point(4,7), Point(7,8)), false); // нет // точка: testForIntersection(Interval(Point(2,2), Point(2,2)), Interval(Point(0,0), Point(7,7)), false); // паралельные прямые: testForIntersection(Interval(Point(2,2), Point(2,5)), Interval(Point(3,3), Point(3,6)), false); // один входит в другой: testForIntersection(Interval(Point(2,2), Point(5,5)), Interval(Point(3,3), Point(4,4)), true); // пересекаются в вершине: testForIntersection(Interval(Point(0,0), Point(2,0)), Interval(Point(0,0), Point(0,-4)), true); // -45 deg is 315 deg: angle(Interval(Point(2,2), Point(5,5)), Interval(Point(0,0), Point(3,0))); // angle(Interval(Point(2,2), Point(5,5)), Interval(Point(-2,2), Point(-5,5))); }
IntervalVector SetNodeReg::right_box(const IntervalVector& nodebox) const { IntervalVector rightbox(nodebox); rightbox[var]=Interval(pt,nodebox[var].ub()); return rightbox; }
void VertexPaint::ModifyObject(TimeValue t, ModContext &mc, ObjectState * os, INode *node) { if (!os->obj->IsSubClassOf(triObjectClassID)) return; os->obj->ReadyChannelsForMod(GEOM_CHANNEL|TOPO_CHANNEL|VERTCOLOR_CHANNEL|TEXMAP_CHANNEL); TriObject *tobj = (TriObject*)os->obj; VertexPaintData *d = (VertexPaintData*)mc.localData; Mesh* mesh = &tobj->GetMesh(); if (mesh) { // We don't have any VColors yet, so we allocate the vcfaces // and set all vcolors to black (index 0) if (!mesh->vcFace) { mesh->setNumVCFaces(mesh->getNumFaces()); mesh->setNumVertCol(1); mesh->vertCol[0] = Color(0,0,0); for (int f=0; f<mesh->getNumFaces(); f++) { mesh->vcFace[f].t[0] = 0; mesh->vcFace[f].t[1] = 0; mesh->vcFace[f].t[2] = 0; } } if (!d) mc.localData = d = new VertexPaintData(tobj->GetMesh()); if (!d->GetMesh()) d->SetCache(*mesh); { MeshDelta md(*mesh); //MeshDelta mdc; //if(cache) mdc.InitToMesh(*cache); // If the incoming Mesh had no vertex colors, this will add a default map to start with. // The default map has the same topology as the Mesh (so one color per vertex), // with all colors set to white. if (!mesh->mapSupport(0)) md.AddVertexColors (); //if (cache && !cache->mapSupport(0)) mdc.AddVertexColors (); // We used two routines -- VCreate to add new map vertices, and FRemap to make the // existing map faces use the new verts. frFlags tell FRemap which vertices on a face // should be "remapped", and the ww array contains the new locations. VertColor nvc; int j; for (int v=0; v < d->GetNumColors(); v++) { ColorData cd = d->GetColorData(v); // Edition Mode ?? if(editMod == this) { nvc= Color(cd.color); // change color to view only monochromatic info for this channel; switch(_EditType) { case 0: nvc.y= nvc.z= nvc.x; nvc.y*= 0.7f; nvc.z*= 0.7f; break; case 1: nvc.x= nvc.z= nvc.y; nvc.x*= 0.7f; nvc.z*= 0.7f; break; case 2: nvc.x= nvc.y= nvc.z; nvc.x*= 0.7f; nvc.y*= 0.7f; break; } } else { // replace the VertexColor of the outgoing mesh nvc= Color(cd.color); } DWORD ww[3], frFlags; md.map->VCreate (&nvc); // increase the number of vcol's and set the vcfaces as well for(int i = 0 ; i < d->GetNVert(v).faces.Count() ; i++) { j = d->GetNVert(v).whichVertex[i]; frFlags = (1<<j); ww[j] = md.map->outVNum()-1; md.map->FRemap(d->GetNVert(v).faces[i], frFlags, ww); } } md.Apply(*mesh); } NotifyDependents(FOREVER, PART_VERTCOLOR, REFMSG_CHANGE); os->obj->UpdateValidity(VERT_COLOR_CHAN_NUM, Interval(t,t)); } }
vector<Interval> insert(vector<Interval> &intervals, Interval newInterval) { vector<Interval> r; vector<Interval>::iterator it; int status = 0; // 1: newInterval has started, 2: newInterval has ended. int newStart = newInterval.start; int newEnd = newInterval.end; for(it = intervals.begin(); it != intervals.end(); it++) { if(status == 0) { if(newInterval.end < (*it).start) { r.push_back(newInterval); r.push_back(*it); status = 2; continue; } if(newInterval.start <= (*it).start) { newStart = newInterval.start; if(newInterval.end <= (*it).end) { newEnd = (*it).end; r.push_back(Interval(newStart, newEnd)); status = 2; continue; } status = 1; continue; } if(newInterval.start <= (*it).end) { newStart = (*it).start; if(newInterval.end <= (*it).end) { r.push_back(*it); status = 2; continue; } status = 1; continue; } r.push_back(*it); status = 0; continue; } else if(status == 1) { if(newInterval.end < (*it).start) { newEnd = newInterval.end; r.push_back(Interval(newStart, newEnd)); r.push_back(*it); status = 2; continue; } if(newInterval.end <= (*it).end) { newEnd = (*it).end; r.push_back(Interval(newStart, newEnd)); status = 2; continue; } continue; } else { r.push_back(*it); } } if(status == 0) r.push_back(newInterval); else if(status == 1) r.push_back(Interval(newStart, newEnd)); return r; }
IntervalVector SetNodeReg::left_box(const IntervalVector& nodebox) const { IntervalVector leftbox(nodebox); leftbox[var] =Interval(nodebox[var].lb(),pt); return leftbox; }
/// \brief Construct a new interval by specifying the start and length. /// static Interval withStartLength(ValueT StartValue, ValueT LengthValue) noexcept { assert(LengthValue >= 0); return Interval(StartValue, StartValue + LengthValue); }
namespace Ms { //--------------------------------------------------------- // handleRect //--------------------------------------------------------- QRectF handleRect(const QPointF& pos) { return QRectF(pos.x()-4, pos.y()-4, 8, 8); } //--------------------------------------------------------- // tick2measure //--------------------------------------------------------- Measure* Score::tick2measure(int tick) const { if (tick == -1) return lastMeasure(); Measure* lm = 0; for (Measure* m = firstMeasure(); m; m = m->nextMeasure()) { if (tick < m->tick()) return lm; lm = m; } // check last measure if (lm && (tick >= lm->tick()) && (tick <= lm->endTick())) return lm; qDebug("tick2measure %d (max %d) not found", tick, lm ? lm->tick() : -1); return 0; } //--------------------------------------------------------- // tick2measureMM //--------------------------------------------------------- Measure* Score::tick2measureMM(int tick) const { if (tick == -1) return lastMeasureMM(); Measure* lm = 0; for (Measure* m = firstMeasureMM(); m; m = m->nextMeasureMM()) { if (tick < m->tick()) return lm; lm = m; } // check last measure if (lm && (tick >= lm->tick()) && (tick <= lm->endTick())) return lm; qDebug("tick2measureMM %d (max %d) not found", tick, lm ? lm->tick() : -1); return 0; } //--------------------------------------------------------- // tick2measureBase //--------------------------------------------------------- MeasureBase* Score::tick2measureBase(int tick) const { for (MeasureBase* mb = first(); mb; mb = mb->next()) { int st = mb->tick(); int l = mb->ticks(); if (tick >= st && tick < (st+l)) return mb; } // qDebug("tick2measureBase %d not found", tick); return 0; } //--------------------------------------------------------- // tick2segment //--------------------------------------------------------- Segment* Score::tick2segmentMM(int tick, bool first, Segment::Type st) const { return tick2segment(tick,first,st,true); } Segment* Score::tick2segment(int tick, bool first, Segment::Type st, bool useMMrest ) const { Measure* m; if (useMMrest) { m = tick2measureMM(tick); // When mmRest force tick to the first segment of mmRest. if (m && m->isMMRest()) tick = m->tick(); } else m = tick2measure(tick); if (m == 0) { qDebug(" no segment for tick %d", tick); return 0; } for (Segment* segment = m->first(st); segment;) { int t1 = segment->tick(); Segment* nsegment = segment->next(st); int t2 = nsegment ? nsegment->tick() : INT_MAX; if ((tick == t1) && (first || (tick < t2))) return segment; segment = nsegment; } return 0; } //--------------------------------------------------------- // tick2segmentEnd //--------------------------------------------------------- /** Find a segment containing a note or rest in \a track ending at \a tick Return the segment or null */ Segment* Score::tick2segmentEnd(int track, int tick) const { Measure* m = tick2measure(tick); if (m == 0) { qDebug("tick2segment(): not found tick %d", tick); return 0; } // loop over all segments for (Segment* segment = m->first(Segment::Type::ChordRest); segment; segment = segment->next(Segment::Type::ChordRest)) { ChordRest* cr = static_cast<ChordRest*>(segment->element(track)); if (!cr) continue; // TODO LVI: check if following is correct, see exceptions in // ExportMusicXml::chord() and ExportMusicXml::rest() int endTick = cr->tick() + cr->actualTicks(); if (endTick < tick) continue; // not found yet else if (endTick == tick) { return segment; // found it } else { // endTick > tick (beyond the tick we are looking for) return 0; } } return 0; } //--------------------------------------------------------- // tick2leftSegment /// return the segment at this tick position if any or /// the first segment *before* this tick position //--------------------------------------------------------- Segment* Score::tick2leftSegment(int tick) const { Measure* m = tick2measure(tick); if (m == 0) { qDebug("tick2leftSegment(): not found tick %d", tick); return 0; } // loop over all segments Segment* ps = 0; for (Segment* s = m->first(Segment::Type::ChordRest); s; s = s->next(Segment::Type::ChordRest)) { if (tick < s->tick()) return ps; else if (tick == s->tick()) return s; ps = s; } return ps; } //--------------------------------------------------------- // tick2rightSegment /// return the segment at this tick position if any or /// the first segment *after* this tick position //--------------------------------------------------------- Segment* Score::tick2rightSegment(int tick) const { Measure* m = tick2measure(tick); if (m == 0) { qDebug("tick2nearestSegment(): not found tick %d", tick); return 0; } // loop over all segments for (Segment* s = m->first(Segment::Type::ChordRest); s; s = s->next(Segment::Type::ChordRest)) { if (tick <= s->tick()) return s; } return 0; } //--------------------------------------------------------- // getStaff //--------------------------------------------------------- int getStaff(System* system, const QPointF& p) { QPointF pp = p - system->page()->pos() - system->pos(); for (int i = 0; i < system->page()->score()->nstaves(); ++i) { qreal sp = system->spatium(); QRectF r = system->bboxStaff(i).adjusted(0.0, -sp, 0.0, sp); if (r.contains(pp)) return i; } return -1; } //--------------------------------------------------------- // nextSeg //--------------------------------------------------------- int Score::nextSeg(int tick, int track) { Segment* seg = tick2segment(tick); while (seg) { seg = seg->next1(Segment::Type::ChordRest); if (seg == 0) break; if (seg->element(track)) break; } return seg ? seg->tick() : -1; } //--------------------------------------------------------- // nextSeg1 //--------------------------------------------------------- Segment* nextSeg1(Segment* seg, int& track) { int staffIdx = track / VOICES; int startTrack = staffIdx * VOICES; int endTrack = startTrack + VOICES; while ((seg = seg->next1(Segment::Type::ChordRest))) { for (int t = startTrack; t < endTrack; ++t) { if (seg->element(t)) { track = t; return seg; } } } return 0; } //--------------------------------------------------------- // prevSeg1 //--------------------------------------------------------- Segment* prevSeg1(Segment* seg, int& track) { int staffIdx = track / VOICES; int startTrack = staffIdx * VOICES; int endTrack = startTrack + VOICES; while ((seg = seg->prev1(Segment::Type::ChordRest))) { for (int t = startTrack; t < endTrack; ++t) { if (seg->element(t)) { track = t; return seg; } } } return 0; } //--------------------------------------------------------- // next/prevChordNote // // returns the top note of the next/previous chord. If a chord exists in the same track as note, // it is used. If not, the topmost existing chord is used. // May return nullptr if there is no next/prev note //--------------------------------------------------------- Note* nextChordNote(Note* note) { int track = note->track(); int fromTrack = (track / VOICES) * VOICES; int toTrack = fromTrack + VOICES; // TODO : limit to same instrument, not simply to same staff! Segment* seg = note->chord()->segment()->nextCR(track, true); while (seg) { Element* targetElement = seg->elementAt(track); // if a chord exists in the same track, return its top note if (targetElement != nullptr && targetElement->type() == Element::Type::CHORD) return static_cast<Chord*>(targetElement)->upNote(); // if not, return topmost chord in track range for (int i = fromTrack ; i < toTrack; i++) { targetElement = seg->elementAt(i); if (targetElement != nullptr && targetElement->type() == Element::Type::CHORD) return static_cast<Chord*>(targetElement)->upNote(); } seg = seg->nextCR(track, true); } return nullptr; } Note* prevChordNote(Note* note) { int track = note->track(); int fromTrack = (track / VOICES) * VOICES; int toTrack = fromTrack + VOICES; // TODO : limit to same instrument, not simply to same staff! Segment* seg = note->chord()->segment()->prev1(); while (seg) { if (seg->segmentType() == Segment::Type::ChordRest) { Element* targetElement = seg->elementAt(track); // if a chord exists in the same track, return its top note if (targetElement != nullptr && targetElement->type() == Element::Type::CHORD) return static_cast<Chord*>(targetElement)->upNote(); // if not, return topmost chord in track range for (int i = fromTrack ; i < toTrack; i++) { targetElement = seg->elementAt(i); if (targetElement != nullptr && targetElement->type() == Element::Type::CHORD) return static_cast<Chord*>(targetElement)->upNote(); } } seg = seg->prev1(); } return nullptr; } //--------------------------------------------------------- // pitchKeyAdjust // change entered note to sounding pitch dependend // on key. // Example: if F is entered in G-major, a Fis is played // key -7 ... +7 //--------------------------------------------------------- int pitchKeyAdjust(int step, Key key) { static int ptab[15][7] = { // c d e f g a b { -1, 1, 3, 4, 6, 8, 10 }, // Bes { -1, 1, 3, 5, 6, 8, 10 }, // Ges { 0, 1, 3, 5, 6, 8, 10 }, // Des { 0, 1, 3, 5, 7, 8, 10 }, // As { 0, 2, 3, 5, 7, 8, 10 }, // Es { 0, 2, 3, 5, 7, 9, 10 }, // B { 0, 2, 4, 5, 7, 9, 10 }, // F { 0, 2, 4, 5, 7, 9, 11 }, // C { 0, 2, 4, 6, 7, 9, 11 }, // G { 1, 2, 4, 6, 7, 9, 11 }, // D { 1, 2, 4, 6, 8, 9, 11 }, // A { 1, 3, 4, 6, 8, 9, 11 }, // E { 1, 3, 4, 6, 8, 10, 11 }, // H { 1, 3, 5, 6, 8, 10, 11 }, // Fis { 1, 3, 5, 6, 8, 10, 12 }, // Cis }; return ptab[int(key)+7][step]; } //--------------------------------------------------------- // y2pitch //--------------------------------------------------------- int y2pitch(qreal y, ClefType clef, qreal _spatium) { int l = lrint(y / _spatium * 2.0); return line2pitch(l, clef, Key::C); } //--------------------------------------------------------- // line2pitch // key -7 ... +7 //--------------------------------------------------------- int line2pitch(int line, ClefType clef, Key key) { int l = ClefInfo::pitchOffset(clef) - line; int octave = 0; while (l < 0) { l += 7; octave++; } octave += l / 7; l = l % 7; int pitch = pitchKeyAdjust(l, key) + octave * 12; if (pitch > 127) pitch = 127; else if (pitch < 0) pitch = 0; return pitch; } //--------------------------------------------------------- // quantizeLen //--------------------------------------------------------- int quantizeLen(int len, int raster) { if (raster == 0) return len; return int( ((float)len/raster) + 0.5 ) * raster; //round to the closest multiple of raster } //--------------------------------------------------------- // selectNoteMessage //--------------------------------------------------------- void selectNoteMessage() { if (!MScore::noGui) QMessageBox::information(0, QMessageBox::tr("MuseScore"), QMessageBox::tr("No note selected:\n" "Please select a single note and retry operation\n"), QMessageBox::Ok, QMessageBox::NoButton); } void selectNoteRestMessage() { if (!MScore::noGui) QMessageBox::information(0, QMessageBox::tr("MuseScore"), QMessageBox::tr("No note or rest selected:\n" "Please select a single note or rest and retry operation\n"), QMessageBox::Ok, QMessageBox::NoButton); } void selectNoteSlurMessage() { if (!MScore::noGui) QMessageBox::information(0, QMessageBox::tr("MuseScore"), QMessageBox::tr("Please select a single note or slur and retry operation\n"), QMessageBox::Ok, QMessageBox::NoButton); } void selectStavesMessage() { if (!MScore::noGui) QMessageBox::information(0, QMessageBox::tr("MuseScore"), QMessageBox::tr("Please select one or more staves and retry operation\n"), QMessageBox::Ok, QMessageBox::NoButton); } static const char* vall[] = { QT_TRANSLATE_NOOP("utils", "c"), QT_TRANSLATE_NOOP("utils", "c#"), QT_TRANSLATE_NOOP("utils", "d"), QT_TRANSLATE_NOOP("utils", "d#"), QT_TRANSLATE_NOOP("utils", "e"), QT_TRANSLATE_NOOP("utils", "f"), QT_TRANSLATE_NOOP("utils", "f#"), QT_TRANSLATE_NOOP("utils", "g"), QT_TRANSLATE_NOOP("utils", "g#"), QT_TRANSLATE_NOOP("utils", "a"), QT_TRANSLATE_NOOP("utils", "a#"), QT_TRANSLATE_NOOP("utils", "b") }; static const char* valu[] = { QT_TRANSLATE_NOOP("utils", "C"), QT_TRANSLATE_NOOP("utils", "C#"), QT_TRANSLATE_NOOP("utils", "D"), QT_TRANSLATE_NOOP("utils", "D#"), QT_TRANSLATE_NOOP("utils", "E"), QT_TRANSLATE_NOOP("utils", "F"), QT_TRANSLATE_NOOP("utils", "F#"), QT_TRANSLATE_NOOP("utils", "G"), QT_TRANSLATE_NOOP("utils", "G#"), QT_TRANSLATE_NOOP("utils", "A"), QT_TRANSLATE_NOOP("utils", "A#"), QT_TRANSLATE_NOOP("utils", "B") }; /*! * Returns the string representation of the given pitch. * * Returns the latin letter name, accidental, and octave numeral. * Uses upper case only for pitches 0-24. * * @param v * The pitch number of the note. * * @return * The string representation of the note. */ QString pitch2string(int v) { if (v < 0 || v > 127) return QString("----"); int octave = (v / 12) - 2; QString o; o.sprintf("%d", octave); int i = v % 12; return qApp->translate("utils", octave < 0 ? valu[i] : vall[i]) + o; } /*! * An array of all supported interval sorted by size. * * Because intervals can be spelled differently, this array * tracks all the different valid intervals. They are arranged * in diatonic then chromatic order. */ Interval intervalList[26] = { // diatonic - chromatic Interval(0, 0), // 0 Perfect Unison Interval(0, 1), // 1 Augmented Unison Interval(1, 0), // 2 Diminished Second Interval(1, 1), // 3 Minor Second Interval(1, 2), // 4 Major Second Interval(1, 3), // 5 Augmented Second Interval(2, 2), // 6 Diminished Third Interval(2, 3), // 7 Minor Third Interval(2, 4), // 8 Major Third Interval(2, 5), // 9 Augmented Third Interval(3, 4), // 10 Diminished Fourth Interval(3, 5), // 11 Perfect Fourth Interval(3, 6), // 12 Augmented Fourth Interval(4, 6), // 13 Diminished Fifth Interval(4, 7), // 14 Perfect Fifth Interval(4, 8), // 15 Augmented Fifth Interval(5, 7), // 16 Diminished Sixth Interval(5, 8), // 17 Minor Sixth Interval(5, 9), // 18 Major Sixth Interval(5, 10), // 19 Augmented Sixth Interval(6, 9), // 20 Diminished Seventh Interval(6, 10), // 21 Minor Seventh Interval(6, 11), // 22 Major Seventh Interval(6, 12), // 23 Augmented Seventh Interval(7, 11), // 24 Diminshed Octave Interval(7, 12) // 25 Perfect Octave }; /*! * Finds the most likely diatonic interval for a semitone distance. * * Uses the most common diatonic intervals. * * @param * The number of semitones in the chromatic interval. * Negative semitones will simply be made positive. * * @return * The number of diatonic steps in the interval. */ int chromatic2diatonic(int semitones) { static int il[12] = { 0, // Perfect Unison 3, // Minor Second 4, // Major Second 7, // Minor Third 8, // Major Third 11, // Perfect Fourth 12, // Augmented Fourth 14, // Perfect Fifth 17, // Minor Sixth 18, // Major Sixth 21, // Minor Seventh 22, // Major Seventh // 25 Perfect Octave }; bool down = semitones < 0; if (down) semitones = -semitones; int val = semitones % 12; int octave = semitones / 12; int intervalIndex = il[val]; int steps = intervalList[intervalIndex].diatonic; steps = steps + octave * 7; return down ? -steps : steps; } //--------------------------------------------------------- // searchInterval //--------------------------------------------------------- int searchInterval(int steps, int semitones) { unsigned n = sizeof(intervalList)/sizeof(*intervalList); for (unsigned i = 0; i < n; ++i) { if ((intervalList[i].diatonic == steps) && (intervalList[i].chromatic == semitones)) return i; } return -1; } static int _majorVersion, _minorVersion, _updateVersion; /*! * Returns the program version * * @return * Version in the format: MMmmuu * Where M=Major, m=minor, and u=update */ int version() { QRegExp re("(\\d+)\\.(\\d+)\\.(\\d+)"); if (re.indexIn(VERSION) != -1) { QStringList sl = re.capturedTexts(); if (sl.size() == 4) { _majorVersion = sl[1].toInt(); _minorVersion = sl[2].toInt(); _updateVersion = sl[3].toInt(); return _majorVersion * 10000 + _minorVersion * 100 + _updateVersion; } } return 0; } //--------------------------------------------------------- // majorVersion //--------------------------------------------------------- int majorVersion() { version(); return _majorVersion; } //--------------------------------------------------------- // minorVersion //--------------------------------------------------------- int minorVersion() { version(); return _minorVersion; } //--------------------------------------------------------- // updateVersion //--------------------------------------------------------- int updateVersion() { version(); return _updateVersion; } //--------------------------------------------------------- // diatonicUpDown // used to find the second note of a trill, mordent etc. // key -7 ... +7 //--------------------------------------------------------- int diatonicUpDown(Key k, int pitch, int steps) { static int ptab[15][7] = { // c c# d d# e f f# g g# a a# b { -1, 1, 3, 4, 6, 8, 10 }, // Cb Ces { -1, 1, 3, 5, 6, 8, 10 }, // Gb Ges { 0, 1, 3, 5, 6, 8, 10 }, // Db Des { 0, 1, 3, 5, 7, 8, 10 }, // Ab As { 0, 2, 3, 5, 7, 8, 10 }, // Eb Es { 0, 2, 3, 5, 7, 9, 10 }, // Bb B { 0, 2, 4, 5, 7, 9, 10 }, // F F { 0, 2, 4, 5, 7, 9, 11 }, // C C { 0, 2, 4, 6, 7, 9, 11 }, // G G { 1, 2, 4, 6, 7, 9, 11 }, // D D { 1, 2, 4, 6, 8, 9, 11 }, // A A { 1, 3, 4, 6, 8, 9, 11 }, // E E { 1, 3, 4, 6, 8, 10, 11 }, // B H { 1, 3, 5, 6, 8, 10, 11 }, // F# Fis { 1, 3, 5, 6, 8, 10, 12 }, // C# Cis }; int key = int(k) + 7; int step = pitch % 12; int octave = pitch / 12; // loop through the diatonic steps of the key looking for the given note // or the gap where it would fit int i = 0; while (i < 7) { if (ptab[key][i] >= step) break; ++i; } // neither step nor gap found // reset to beginning if (i == 7) { ++octave; i = 0; } // if given step not found (gap found instead), and we are stepping up // then we've already accounted for one step if (ptab[key][i] > step && steps > 0) --steps; // now start counting diatonic steps up or down if (steps > 0) { // count up while (steps--) { ++i; if (i == 7) { // hit last step; reset to beginning ++octave; i = 0; } } } else if (steps < 0) { // count down while (steps++) { --i; if (i < 0) { // hit first step; reset to end --octave; i = 6; } } } // convert step to pitch step = ptab[key][i]; pitch = octave * 12 + step; if (pitch < 0) pitch = 0; if (pitch > 127) pitch = 128; return pitch; } //--------------------------------------------------------- // searchTieNote // search Note to tie to "note" //--------------------------------------------------------- Note* searchTieNote(Note* note) { Note* note2 = 0; Chord* chord = note->chord(); Segment* seg = chord->segment(); Part* part = chord->part(); int strack = part->staves()->front()->idx() * VOICES; int etrack = strack + part->staves()->size() * VOICES; if (chord->isGraceBefore()) { // grace before // try to tie to note in parent chord chord = static_cast<Chord*>(chord->parent()); note2 = chord->findNote(note->pitch()); if (note2) return note2; } else if (chord->isGraceAfter()) { // grace after // we will try to tie to note in next normal chord, below // meanwhile, set chord to parent chord so the endTick calculation will make sense chord = static_cast<Chord*>(chord->parent()); } else { // normal chord // try to tie to grace note after if present QList<Chord*> gna = chord->graceNotesAfter(); if (!gna.isEmpty()) { Chord* gc = gna[0]; note2 = gc->findNote(note->pitch()); if (note2) return note2; } } // at this point, chord is a regular chord, not a grace chord // and we are looking for a note in the *next* chord (grace or regular) // calculate end of current note duration // but err on the safe side in case there is roundoff in tick count int endTick = chord->tick() + chord->actualTicks() - 1; while ((seg = seg->next1(Segment::Type::ChordRest))) { // skip ahead to end of current note duration as calculated above // but just in case, stop if we find element in current track if (seg->tick() < endTick && !seg->element(chord->track())) continue; for (int track = strack; track < etrack; ++track) { Chord* c = static_cast<Chord*>(seg->element(track)); if (c == 0 || c->type() != Element::Type::CHORD) continue; // if there are grace notes before, try to tie to first one QList<Chord*> gnb = c->graceNotesBefore(); if (!gnb.isEmpty()) { Chord* gc = gnb[0]; Note* gn2 = gc->findNote(note->pitch()); if (gn2) return gn2; } int staffIdx = c->staffIdx() + c->staffMove(); if (staffIdx != chord->staffIdx() + chord->staffMove()) // cannot happen? continue; for (Note* n : c->notes()) { if (n->pitch() == note->pitch()) { if (note2 == 0 || c->track() == chord->track()) note2 = n; } } } if (note2) break; } return note2; } //--------------------------------------------------------- // searchTieNote114 // search Note to tie to "note", tie to next note in // same voice //--------------------------------------------------------- Note* searchTieNote114(Note* note) { Note* note2 = 0; Chord* chord = note->chord(); Segment* seg = chord->segment(); Part* part = chord->part(); int strack = part->staves()->front()->idx() * VOICES; int etrack = strack + part->staves()->size() * VOICES; while ((seg = seg->next1(Segment::Type::ChordRest))) { for (int track = strack; track < etrack; ++track) { Chord* c = static_cast<Chord*>(seg->element(track)); if (c == 0 || (c->type() != Element::Type::CHORD) || (c->track() != chord->track())) continue; int staffIdx = c->staffIdx() + c->staffMove(); if (staffIdx != chord->staffIdx() + chord->staffMove()) // cannot happen? continue; for (Note* n : c->notes()) { if (n->pitch() == note->pitch()) { if (note2 == 0 || c->track() == chord->track()) note2 = n; } } } if (note2) break; } return note2; } //--------------------------------------------------------- // absStep /// Compute absolute step. /// C D E F G A B .... //--------------------------------------------------------- int absStep(int tpc, int pitch) { int line = tpc2step(tpc) + (pitch / 12) * 7; int tpcPitch = tpc2pitch(tpc); if (tpcPitch < 0) line += 7; else line -= (tpcPitch / 12) * 7; return line; } int absStep(int pitch) { // TODO - does this need to be key-aware? int tpc = pitch2tpc(pitch, Key::C, Prefer::NEAREST); return absStep(tpc, pitch); } int absStep(int line, ClefType clef) { return ClefInfo::pitchOffset(clef) - line; } //--------------------------------------------------------- // relStep /// Compute relative step from absolute step /// which depends on actual clef. Step 0 starts on the /// first (top) staff line. //--------------------------------------------------------- int relStep(int line, ClefType clef) { return ClefInfo::pitchOffset(clef) - line; } int relStep(int pitch, int tpc, ClefType clef) { return relStep(absStep(tpc, pitch), clef); } //--------------------------------------------------------- // pitch2step // returns one of { 0, 1, 2, 3, 4, 5, 6 } //--------------------------------------------------------- int pitch2step(int pitch) { // C C# D D# E F F# G G# A A# B static const char tab[12] = { 0, 0, 1, 1, 2, 3, 3, 4, 4, 5, 5, 6 }; return tab[pitch%12]; } //--------------------------------------------------------- // step2pitch // returns one of { 0, 2, 4, 5, 7, 9, 11 } //--------------------------------------------------------- int step2pitch(int step) { static const char tab[7] = { 0, 2, 4, 5, 7, 9, 11 }; return tab[step % 7]; } }
/// \brief Construct a new interval by specifying the start and end. /// static Interval withStartEnd(ValueT StartValue, ValueT EndValue) noexcept { assert(EndValue >= StartValue); return Interval(StartValue, EndValue); }
void SelMaps::select(TimeValue t, CompMap &compMap, Bitmap *bm, RenderGlobalContext *gc) { int type; bm->GetStoragePtr(&type); assert(type == BMM_TRUE_48); m_shadeContext.globContext = gc; // if source bitmap has changed since last call if ( m_lastBMModifyID != bm->GetModifyID() ) { m_lastBMModifyID = bm->GetModifyID(); m_selectValid = m_featherValid = m_compValid = false; if ( (bm->Width() != m_imageW) || (bm->Height() != m_imageH) ) { m_imageW = bm->Width(); m_imageH = bm->Height(); m_imageSz = m_imageW * m_imageH; if (m_imageSz > m_mapSz) { if (mp_radMap) delete[] mp_radMap; mp_radMap = new float[m_imageSz]; m_mapSz = m_imageSz; } } } float fTemp; if (!m_selectValid) { m_brightenMap = NULL; mp_blurMgr->getSelValue(prmMaskMap, 0, m_brightenMap, FOREVER); if (!m_brightenMap) return; m_shadeContext.scale = 1.0f; m_shadeContext.duvw = Point3(1.0f/float(m_imageW), 1.0f/float(m_imageH), 0.0f); m_shadeContext.uvw.z = 0.0f; m_shadeContext.filterMaps = TRUE; m_brightenMap->Update(t, Interval()); m_brightenMap->LoadMapFiles(t); mp_blurMgr->getSelValue(prmMaskChannel, t, m_channel, FOREVER); mp_blurMgr->getSelValue(prmMaskMin, t, fTemp, FOREVER); LimitValue(fTemp, 0.0f, 100.0f); // mjm - 9.30.99 m_min = fTemp*PERCENT2DEC; mp_blurMgr->getSelValue(prmMaskMax, t, fTemp, FOREVER); LimitValue(fTemp, 0.0f, 100.0f); // mjm - 9.30.99 m_max = fTemp*PERCENT2DEC; // get source bitmap data BitmapAccessor bmFrom(bm, TRUE, TRUE); m_selectValid = doSelect(bmFrom); } if (!m_featherValid) { mp_blurMgr->getSelValue(prmMaskFeathRad, t, fTemp, FOREVER); LimitValue(fTemp, 0.0f, 1000.0f); // mjm - 9.30.99 m_feathRad = (int)floor(max(m_imageW, m_imageH)*(fTemp*PERCENT2DEC)); m_featherValid = doFeather(); } mp_blurMgr->getSelValue(prmMaskBrighten, t, fTemp, FOREVER); LimitValue(fTemp, 0.0f, 1000.0f); // mjm - 9.30.99 m_brighten = fTemp*PERCENT2DEC; mp_blurMgr->getSelValue(prmMaskBlend, t, fTemp, FOREVER); LimitValue(fTemp, 0.0f, 100.0f); // mjm - 9.30.99 m_blend = fTemp*PERCENT2DEC; m_compValid = doComposite(t, compMap); }
void div2(const Interval& num, const Interval& div, Interval& out1, Interval& out2) { if (num.is_empty() || div.is_empty()) { out1.set_empty(); out2.set_empty(); return; } const double& a(num.lb()); const double& b(num.ub()); const double& c(div.lb()); const double& d(div.ub()); // notice : we do not consider 0/0=0 but 0/0=emptyset if (c==0 && d==0) { out1.set_empty(); out2.set_empty(); return; } if (a==0 && b==0) { out1 = num; out2.set_empty(); return; } if (c>0 || d<0) { out1 = num/div; out2.set_empty(); return; } if (b<=0 && d==0) { if (c==NEG_INFINITY) out1 = Interval::POS_REALS; else out1 = Interval(INF_DIV(b,c), POS_INFINITY); out2.set_empty(); return; } if (b<=0 && c<0 && d>0) { if (b==0 || (c==NEG_INFINITY && d==POS_INFINITY)) { out1 = Interval::ALL_REALS; out2.set_empty(); return; } else { out1 = Interval(NEG_INFINITY, d==POS_INFINITY? 0 : SUP_DIV(b,d)); out2 = Interval(c==NEG_INFINITY? 0 : INF_DIV(b,c), POS_INFINITY); return; } } if (b<=0 && c==0) { if (d==POS_INFINITY) out1 = Interval::NEG_REALS; else out1 = Interval(NEG_INFINITY, SUP_DIV(b,d)); out2.set_empty(); return; } if (a>=0 && d==0) { if (c==NEG_INFINITY) out1 = Interval::NEG_REALS; else out1 = Interval(NEG_INFINITY, SUP_DIV(a,c)); out2.set_empty(); return; } if (a>=0 && c<0 && d>0) { if (a==0 || (c==NEG_INFINITY && d==POS_INFINITY)) { out1 = Interval::ALL_REALS; out2.set_empty(); return; } else { out1 = Interval(NEG_INFINITY, c==NEG_INFINITY? 0 : SUP_DIV(a,c)); out2 = Interval(d==POS_INFINITY? 0 : INF_DIV(a,d), POS_INFINITY); return; } } if (a>=0 && c==0) { if (d==POS_INFINITY) out1 = Interval::POS_REALS; else out1 = Interval(INF_DIV(a,d), POS_INFINITY); out2.set_empty(); return; } out1 = Interval::ALL_REALS; out2.set_empty(); }
void Main() { vector<Interval> input = {Interval(1, 4), Interval(1, 4)}; print(merge(input)); }
Interval merge(Interval a, Interval b) { return Interval(min(a.start, b.start), max(a.end, b.end)); }