コード例 #1
0
        private void interpolCurrent(double time)
        {
            TrackParser.Sample result = mCurrInterpol;
            TrackParser.Sample curr   = mCurrSample;
            TrackParser.Sample next   = mCurrSample;

            double progress = 0;

            if (!Double.IsNaN(curr.mAbsEndTime))
            {
                progress = (time - curr.mAbsStartTime) / (curr.mAbsEndTime - curr.mAbsStartTime);
            }
            if (progress > 0 && mCurrIndex < mTrackData.Samples.Count - 1)
            {
                next = mTrackData.Samples[mCurrIndex + 1];
            }

            result.mLap = curr.mLap;

            result.mAbsStartTime = time;
            result.mAbsEndTime   = curr.mAbsEndTime;
            result.mElapsedTime  = interpolate(curr.mElapsedTime, next.mElapsedTime, progress);

            result.mSpeed        = interpolate(curr.mSpeed, next.mSpeed, progress);
            result.mAccel        = interpolate(curr.mAccel, next.mAccel, progress);
            result.mLateralAccel = interpolate(curr.mLateralAccel, next.mLateralAccel, progress);
            result.mLatitude     = interpolate(curr.mLatitude, next.mLatitude, progress);
            result.mLongtiude    = interpolate(curr.mLongtiude, next.mLongtiude, progress);
            result.mAltitude     = interpolate(curr.mAltitude, next.mAltitude, progress);
            result.mBearing      = interpolate(curr.mBearing, next.mBearing, progress);
        }
コード例 #2
0
ファイル: Generator.cs プロジェクト: lipilipii/trackvideo
        private Bitmap prepareTrackBmp(Rectangle trackRect, Gps2PixelProjection trackProj, TrackParser td)
        {
            // We need at least a lap to draw something
            if (!td.HasSamples || trackProj == null)
            {
                return(null);
            }

            // We'll draw one of the laps. Just get the first lap.
            TrackParser.Lap currLap = td.Laps[0];

            int    w   = trackRect.Width;
            int    h   = trackRect.Height;
            Bitmap bmp = new Bitmap(w, h);

            using (Graphics g = Graphics.FromImage(bmp)) {
                using (Brush bgColor = new SolidBrush(Color.Gray),
                       trackColor = new SolidBrush(Color.Yellow)) {
                    using (Pen trackPen = new Pen(trackColor, kTrackWidth)) {
                        g.FillRectangle(bgColor, 0, 0, w, h);

                        List <TrackParser.Sample> samples = td.Samples;
                        TrackParser.Sample        s       = samples[0];
                        CPointF last = new CPointF();
                        CPointF next = new CPointF();

                        transformGpsCoord(s.mLongtiude, s.mLatitude, trackProj, last);

                        float px = (float)trackProj.mPixelOffsetX;
                        float py = (float)trackProj.mPixelOffsetY;

                        last.mX -= px;
                        last.mY -= py;

                        for (int i = 1, n = samples.Count; i < n; i++)
                        {
                            s = samples[i];
                            if (s.mLap != currLap)
                            {
                                continue;
                            }

                            transformGpsCoord(s.mLongtiude, s.mLatitude, trackProj, next);
                            next.mX -= px;
                            next.mY -= py;

                            g.DrawLine(trackPen, last.mX, last.mY, next.mX, next.mY);

                            last.mX = next.mX;
                            last.mY = next.mY;
                        }
                    }
                }
            }

            return(bmp);
        }
コード例 #3
0
        private void findCurrSample(double time)
        {
            List <TrackParser.Sample> samples = mTrackData.Samples;
            int n  = samples.Count;
            int n1 = n - 1;

            if (time < 0)
            {
                // can't go before the first sample
                mCurrSample = samples[0];
                mCurrIndex  = 0;
                return;
            }
            else if (time > samples[n1].mAbsStartTime)
            {
                // can't go past the last sample
                mCurrSample = samples[n1];
                mCurrIndex  = n - 1;
                return;
            }

            // The most common case is that we need to advance to the next sample
            if (mCurrSample != null && mCurrIndex < n1)
            {
                TrackParser.Sample s = samples[mCurrIndex + 1];
                if (time >= s.mAbsStartTime &&
                    (Double.IsNaN(s.mAbsEndTime) || (!Double.IsNaN(s.mAbsEndTime) && time < s.mAbsEndTime)))
                {
                    mCurrIndex++;
                    mCurrSample = s;
                    return;
                }
            }

            // Going forward from current sample
            if (mCurrSample != null && mCurrIndex < n1 && time > mCurrSample.mAbsEndTime)
            {
                while (mCurrIndex < n1 && time > mCurrSample.mAbsEndTime)
                {
                    mCurrIndex++;
                    mCurrSample = samples[mCurrIndex];
                }
                return;
            }

            // Going backwards from current sample
            if (mCurrSample != null && mCurrIndex > 0 && time < mCurrSample.mAbsStartTime)
            {
                while (mCurrIndex > 0 && time < mCurrSample.mAbsStartTime)
                {
                    mCurrIndex--;
                    mCurrSample = samples[mCurrIndex];
                }
                return;
            }

            // The most unlikely case is that we're just from scratch going to
            // a random position. We could do a dichotomic search. We'll just start with the
            // obvious linear search and optimize later if really needed (very unlikely),
            // in which case we could combine the 2 last cases to do a dichotomic search
            // with a preset direction and a preset starting point. Yawn.
            for (int i = 0; i < n; i++)
            {
                TrackParser.Sample s = samples[mCurrIndex + 1];
                if (time >= s.mAbsStartTime &&
                    (Double.IsNaN(s.mAbsEndTime) || (!Double.IsNaN(s.mAbsEndTime) && time < s.mAbsEndTime)))
                {
                    mCurrIndex++;
                    mCurrSample = s;
                    return;
                }
            }

            System.Diagnostics.Debug.Fail("Time not found in samples");
        }
コード例 #4
0
        public Interpolator(TrackParser trackData)
        {
            mTrackData = trackData;

            mCurrInterpol = new TrackParser.Sample();
        }
コード例 #5
0
ファイル: Generator.cs プロジェクト: lipilipii/trackvideo
        private void threadEntryPoint()
        {
            int         fps = mFps;
            int         msx = mMovieSx;
            int         msy = mMovieSy;
            int         tsx = mTrackSx;
            int         tsy = mTrackSy;
            TrackParser td  = mTrackData;

            using (Graphics g = Graphics.FromImage(mAviBmp)) {
                using (Brush chromaColor = new SolidBrush(Color.Blue),
                       bgColor = new SolidBrush(Color.Gray),
                       posColor = new SolidBrush(Color.Red),
                       textColor = new SolidBrush(Color.Orange)) {
                    Rectangle bgRect = new Rectangle(msx - tsx, msy - tsy, tsx, tsy);

                    int nbFrames = (int)(mTrackData.TotalTime * fps);

                    // prepare track drawing (map GPS coord => screen coord: offset + scale)
                    Rectangle           trackRect;
                    Gps2PixelProjection trackProj = prepareTrackProj(bgRect, td, out trackRect);
                    Bitmap trackBmp = prepareTrackBmp(trackRect, trackProj, td);

                    // prepare g-meter pos

                    // prepare text positions

                    PointF[] textPos;
                    using (Font labelFont = prepareText(bgRect, out textPos),
                           numFont = new Font(FontFamily.GenericMonospace, labelFont.Size, FontStyle.Bold)) {
                        Interpolator interp = new Interpolator(td);

                        double invFps = 1 / (double)fps;

                        bool userStopRequested = false;

                        for (int frame = 0, updateFps = 0;
                             frame < nbFrames && !userStopRequested;
                             frame++, updateFps++)
                        {
                            double currTime = (double)frame * invFps;

                            TrackParser.Sample currSample = interp.GoTo(currTime);

                            double currLapTime = interp.CurrLapTime;

                            // keep track of current dot & interpolate between dots

                            // draw background

                            g.FillRectangle(chromaColor, 0, 0, msx, msy);

                            g.FillRectangle(bgColor, bgRect);

                            // draw track + current pos
                            drawTrackPos(g, posColor, trackRect, trackBmp, trackProj,
                                         currSample.mLongtiude, currSample.mLatitude);

                            // draw bearing

                            // TODO

                            // draw text
                            drawText(g, textColor, labelFont, numFont, textPos,
                                     currSample.mSpeed, currSample.mAccel, currSample.mLateralAccel,
                                     currTime,
                                     currLapTime, interp.CurrLapIndex, interp.LastLapDuration);

                            // finally dump frame and update preview/progress
                            MainModule.MainForm.Invoke(mAddFrameFunc);

                            if (updateFps == fps)
                            {
                                updateFps = 0;
                            }
                            if (updateFps == 0)
                            {
                                // Update status, progress, etc.
                                userStopRequested = syncUpdate(frame, nbFrames, new Bitmap(mAviBmp));
                            }

                            if (mThreadMustStop)
                            {
                                break;
                            }
                        }
                    } // using Font

                    // Make sure to tell owner that the generator is done
                    // This one must be async -- this thread will quit and the owner will
                    // try to join to wait for the thread to finish.
                    asyncUpdate(nbFrames, nbFrames, new Bitmap(mAviBmp));
                } // using Brush
            }     // using Graphics
        }