public UNote HitTestVibrato(Point mousePos) { int tick = (int)(midiVM.CanvasToQuarter(mousePos.X) * Project.Resolution); double pitch = midiVM.CanvasToPitch(mousePos.Y); foreach (UNote note in midiVM.Part.Notes) { if (note.PosTick + note.DurTick * (1 - note.Vibrato.Length / 100) <= tick && note.EndTick >= tick && Math.Abs(note.NoteNum - pitch) < note.Vibrato.Depth / 100) { return(note); } } return(null); }
public PitchPointHitInfo HitTestPitchPoint(Point mousePos) { if (!midiVM.ShowPitch) { return(null); } foreach (var note in midiVM.Part.notes) { // FIXME pitch point maybe in view while note is not. if (midiVM.NoteIsInView(note) && !note.Error) { double lastX = 0, lastY = 0; PitchPointShape lastShape = PitchPointShape.l; for (int i = 0; i < note.pitch.data.Count; i++) { var pit = note.pitch.data[i]; int posTick = note.position + Project.MillisecondToTick(pit.X); double noteNum = note.tone + pit.Y / 10; double x = midiVM.TickToCanvas(posTick); double y = midiVM.NoteNumToCanvas(noteNum) + midiVM.TrackHeight / 2; if (Math.Abs(mousePos.X - x) < 4 && Math.Abs(mousePos.Y - y) < 4) { return new PitchPointHitInfo() { Note = note, Index = i, OnPoint = true } } ; else if (mousePos.X < x && i > 0 && mousePos.X > lastX) { // Hit test curve double castY = MusicMath.InterpolateShape(lastX, x, lastY, y, mousePos.X, lastShape) - mousePos.Y; if (y >= lastY) { if (mousePos.Y - y > 3 || lastY - mousePos.Y > 3) { break; } } else { if (y - mousePos.Y > 3 || mousePos.Y - lastY > 3) { break; } } double castX = MusicMath.InterpolateShapeX(lastX, x, lastY, y, mousePos.Y, lastShape) - mousePos.X; double dis = double.IsNaN(castX) ? Math.Abs(castY) : Math.Cos(Math.Atan2(Math.Abs(castY), Math.Abs(castX))) * Math.Abs(castY); if (dis < 3) { double msX = DocManager.Inst.Project.TickToMillisecond(midiVM.CanvasToQuarter(mousePos.X) * DocManager.Inst.Project.resolution - note.position); double msY = (midiVM.CanvasToPitch(mousePos.Y) - note.tone) * 10; return(new PitchPointHitInfo() { Note = note, Index = i - 1, OnPoint = false, X = (float)msX, Y = (float)msY }); } else { break; } } lastX = x; lastY = y; lastShape = pit.shape; } } } return(null); }