コード例 #1
0
ファイル: Bouy.cs プロジェクト: brookpatten/VisualSail
        public Bouy(Mark mark,Coordinate latitude,Coordinate longitude)
        {
            _markId = mark.Id;
            _latitude = latitude;
            _longitude = longitude;

            _new = true;
            _changed = true;
        }
コード例 #2
0
ファイル: ReplayBoat.cs プロジェクト: brookpatten/VisualSail
        public void Move(DateTime time,Course course,float windDirection,DateTime raceStart)
        {
            //cheat and jump to the time for the very first move.
            //kindof hacky, but it keeps the user from having to wait for the boats to get 
            //intialized when the race starts.  Also, we probably don't want stats for <race time
            if (!_positionInitialized)
            {
                while (_boatDataRows[_currentBoatDataRow].datetime < raceStart && _currentBoatDataRow < _boatDataRows.Count - 2)
                {
                    _currentBoatDataRow++;
                }
                //if (_currentBoatDataRow > 0)
                //{
                //    _currentBoatDataRow = _currentBoatDataRow - 1;
                //}
                _positionInitialized = true;
            }

            windAngle = windDirection;

            if (_lastUpdate == null)
            {
                _lastUpdate = time;
            }
            
            CoordinatePoint cp;
            ProjectedPoint current=null;

            CoordinatePoint np;
            ProjectedPoint next=null;

            long ticksBetween;
            long actualTicks;
            double percent=0.0;


            //bool changedIndex = false;
            bool doMove = false;
            if (_lastUpdate.Ticks < time.Ticks && _currentBoatDataRow < _boatDataRows.Count - 2)
            {
                doMove = true;
                direction = BoatDirection.Forward;
                while (_boatDataRows[_currentBoatDataRow].datetime < time && _currentBoatDataRow < _boatDataRows.Count - 2)
                {
                    _currentBoatDataRow++;
                    //changedIndex = true;

                    if ((_lowWaterMark == null || _highWaterMark == null) || (time < _lowWaterMark || time > _highWaterMark))
                    {

                        cp = new CoordinatePoint(new Coordinate(_boatDataRows[_currentBoatDataRow + 1].latitude), new Coordinate(_boatDataRows[_currentBoatDataRow + 1].longitude), 0);
                        current = cp.Project();

                        np = new CoordinatePoint(new Coordinate(_boatDataRows[_currentBoatDataRow].latitude), new Coordinate(_boatDataRows[_currentBoatDataRow].longitude), 0);
                        next = np.Project();

                        ProjectedPoint = current;

                        if (_currentMarkIndex.GetValue(_boatDataRows[_currentBoatDataRow].datetime) < course.Route.Count)
                        {
                            NavigateCourse(_boatDataRows[_currentBoatDataRow].datetime, course, cp, np);
                        }
                        double distance = CoordinatePoint.TwoDimensionalDistance(current.Easting, current.Northing, next.Easting, next.Northing);
                        TimeSpan ts = _boatDataRows[_currentBoatDataRow + 1].datetime - _boatDataRows[_currentBoatDataRow].datetime;
                        double kmh = ((distance / 1000.0) / ts.TotalHours);
                        speed = (float)kmh;
                        //float oldWindAngle = RelativeAngleToWind;
                        arrowAngle = (float)AngleHelper.FindAngle(current, next);
                        float newWindAngle = RelativeAngleToWind;
                        if (CurrentRacingStatus == RacingStatus.Racing)
                        {
                            float deadZone = MathHelper.PiOver4 / 2f;//use to be /4f;
                            Tack.TackDirection newTack = Tack.TackDirection.Undetermined;
                            if (newWindAngle < -deadZone && newWindAngle > -MathHelper.Pi + deadZone)
                            {
                                newTack = Tack.TackDirection.Starboard;
                            }
                            else if (newWindAngle > deadZone && newWindAngle < MathHelper.Pi - deadZone)
                            {
                                newTack = Tack.TackDirection.Port;
                            }

                            if (newTack != Tack.TackDirection.Undetermined && (_tacks.Count - 1 < _currentTackIndex.GetValue(_boatDataRows[_currentBoatDataRow].datetime) || _tacks[_currentTackIndex.GetValue(_boatDataRows[_currentBoatDataRow].datetime)].Direction != newTack))
                            {
                                PerformTack(_boatDataRows[_currentBoatDataRow].datetime);
                            }
                        }
                        //set the current and previous marks
                        if (_currentMarkIndex.GetValue(_boatDataRows[_currentBoatDataRow].datetime) < course.Route.Count)
                        {
                            _currentMark = course.Route[_currentMarkIndex.GetValue(_boatDataRows[_currentBoatDataRow].datetime)];
                        }
                        else
                        {
                            _currentMark = null;
                        }
                        if (_currentMarkIndex.GetValue(_boatDataRows[_currentBoatDataRow].datetime) > 0 && course.Route.Count > 0)
                        {
                            _previousMark = course.Route[_currentMarkIndex.GetValue(_boatDataRows[_currentBoatDataRow].datetime) - 1];
                        }
                        else
                        {
                            _previousMark = null;
                        }
                        UpdateStatistics(_boatDataRows[_currentBoatDataRow].datetime, distance / 1000.0);
                        Thread.Sleep(0);
                    }
                }
            }
            else if (_lastUpdate.Ticks > time.Ticks && _currentBoatDataRow > 0)
            {
                doMove = true;
                direction = BoatDirection.Backwards;
                while (_boatDataRows[_currentBoatDataRow].datetime > time && _currentBoatDataRow > 1)
                {
                    _currentBoatDataRow--;
                    //changedIndex = true;

                    if ((_lowWaterMark == null || _highWaterMark == null) || (time < _lowWaterMark || time > _highWaterMark))
                    {

                        cp = new CoordinatePoint(new Coordinate(_boatDataRows[_currentBoatDataRow - 1].latitude), new Coordinate(_boatDataRows[_currentBoatDataRow - 1].longitude), 0);
                        current = cp.Project();

                        np = new CoordinatePoint(new Coordinate(_boatDataRows[_currentBoatDataRow].latitude), new Coordinate(_boatDataRows[_currentBoatDataRow].longitude), 0);
                        next = np.Project();

                        //ProjectedPoint = cp.Project();

                        //double distance = CoordinatePoint.TwoDimensionalDistance(current.easting, current.northing, next.easting, next.northing);
                        //TimeSpan ts = _boatDataRows[_currentBoatDataRow].datetime - _boatDataRows[_currentBoatDataRow - 1].datetime;
                        //double kmh = ((distance / 1000.0) / ts.TotalHours);
                        //speed = (float)kmh;
                        arrowAngle = (float)AngleHelper.FindAngle(current, next);
                        //UpdateStatistics(_boatDataRows[_currentBoatDataRow].datetime, distance / 1000.0);
                        Thread.Sleep(0);
                    }
                }
            }

            //set the current and previous marks
            if (_currentMarkIndex.GetValue(_boatDataRows[_currentBoatDataRow].datetime) < course.Route.Count)
            {
                _currentMark = course.Route[_currentMarkIndex.GetValue(_boatDataRows[_currentBoatDataRow].datetime)];
            }
            else
            {
                _currentMark = null;
            }
            if (_currentMarkIndex.GetValue(_boatDataRows[_currentBoatDataRow].datetime) > 0 && course.Route.Count > 0)
            {
                _previousMark = course.Route[_currentMarkIndex.GetValue(_boatDataRows[_currentBoatDataRow].datetime) - 1];
            }
            else
            {
                _previousMark = null;
            }
            
            if (doMove && _currentBoatDataRow > 0 && _currentBoatDataRow < _boatDataRows.Count - 2)
            {
                int currentOffset;
                if (direction == BoatDirection.Forward)
                {
                    currentOffset = -1;
                }
                else
                {
                    currentOffset = 1;
                }

                cp = new CoordinatePoint(new Coordinate(_boatDataRows[_currentBoatDataRow + currentOffset].latitude), new Coordinate(_boatDataRows[_currentBoatDataRow + currentOffset].longitude), 0);
                current = cp.Project();

                np = new CoordinatePoint(new Coordinate(_boatDataRows[_currentBoatDataRow].latitude), new Coordinate(_boatDataRows[_currentBoatDataRow].longitude), 0);
                next = np.Project();

                CoordinatePoint pp = new CoordinatePoint(new Coordinate(_boatDataRows[_currentBoatDataRow - currentOffset].latitude), new Coordinate(_boatDataRows[_currentBoatDataRow - currentOffset].longitude), 0);
                ProjectedPoint previous = pp.Project();

                ticksBetween = _boatDataRows[_currentBoatDataRow].datetime.Ticks - _boatDataRows[_currentBoatDataRow + currentOffset].datetime.Ticks;
                actualTicks = time.Ticks - _boatDataRows[_currentBoatDataRow + currentOffset].datetime.Ticks;
                percent = (double)actualTicks / (double)ticksBetween;

                double northingDiff = next.Northing - current.Northing;
                double eastingDiff = next.Easting - current.Easting;

                double northing = current.Northing + (northingDiff * percent);
                double easting = current.Easting + (eastingDiff * percent);

                ProjectedPoint actual = new ProjectedPoint();
                actual.Easting = easting;
                actual.Northing = northing;

                ProjectedPoint = actual;

                double distance = CoordinatePoint.TwoDimensionalDistance(current.Easting, current.Northing, next.Easting, next.Northing);
                TimeSpan ts = new TimeSpan(ticksBetween);
                double kmh = ((distance / 1000.0) / ts.TotalHours);
                speed = (float)kmh;

                if (Math.Abs(kmh) > 2)
                {
                    float startingAngle = (float)AngleHelper.FindAngle(previous, current);
                    float desiredAngle = (float)AngleHelper.FindAngle(next, current);
                    desiredAngle = AngleHelper.NormalizeAngle(desiredAngle);
                    float deltaAngle = AngleHelper.AngleDifference(startingAngle, desiredAngle);
                    arrowAngle = startingAngle + (deltaAngle * (float)percent);
                    arrowAngle = AngleHelper.NormalizeAngle(arrowAngle);
                    
                }

                SetHeel(time,kmh);
                SetSailCurve(time);
                SetBoomAngle(time);
                
                //if (changedIndex)
                //{
                //    _updateStatistics();
                //}
                _lastUpdate = time;
            }
            else if(_currentBoatDataRow==0||_currentBoatDataRow==_boatDataRows.Count-1)
            {
                ProjectedPoint = new CoordinatePoint(new Coordinate(_boatDataRows[_currentBoatDataRow].latitude), new Coordinate(_boatDataRows[_currentBoatDataRow].longitude), 0).Project();
            }

            if (_lowWaterMark==null||time < _lowWaterMark)
            {
                _lowWaterMark = time;
            }
            if (_highWaterMark == null || time > _highWaterMark)
            {
                _highWaterMark = time;
            }

        }
コード例 #3
0
ファイル: Bouy.cs プロジェクト: brookpatten/VisualSail
        public static List<Bouy> FindAllByMark(Mark mark)
        {
            var query = from r in Persistance.Data.Bouy.AsEnumerable()
                        where (int)r["mark_id"] == mark.Id
                        select r;

            List<Bouy> bouys = new List<Bouy>();
            foreach (SkipperDataSet.BouyRow rr in query)
            {
                bouys.Add(new Bouy(rr));
            }
            return bouys;
        }
コード例 #4
0
ファイル: EditCourses.cs プロジェクト: brookpatten/VisualSail
 private Bouy NewBouy(Mark m)
 {
     CoordinatePoint bouyC = ScreenToCoordinates(new Point(lakePNL.Width / 2, lakePNL.Height / 2));
     Bouy b = new Bouy(m, bouyC.Latitude, bouyC.Longitude);
     b.Save();
     return b;
 }
コード例 #5
0
ファイル: EditCourses.cs プロジェクト: brookpatten/VisualSail
        private void addBTN_Click(object sender, EventArgs e)
        {
            Mark m = new Mark("New Mark", "Mark", _course);
            m.Save();

            double lakeWidth = _lake.West - _lake.East;
            double lakeHeight = _lake.North - _lake.South;

            Bouy b = NewBouy(m);
            marksLB.Items.Add(m);
            marksLB.SelectedIndex = marksLB.Items.Count - 1;
        }
コード例 #6
0
ファイル: Mark.cs プロジェクト: brookpatten/VisualSail
        public bool IsRounding(ProjectedPoint a, ProjectedPoint b, Mark previousMark,Mark nextMark)
        {
            if (Bouys.Count == 1)
            {
                
                if (previousMark != null && nextMark != null)
                {
                    //I know this is WAY more complicated than it needs to be, but it works
                    //I'll clean it later... maybe after I got back to college and take trig again.

                    Vector2 a2 = new Vector2((float)a.Easting, (float)a.Northing);
                    Vector2 b2 = new Vector2((float)b.Easting, (float)b.Northing);

                    ProjectedPoint myA = Bouys[0].CoordinatePoint.Project();
                    Vector2 myA2 = new Vector2((float)myA.Easting, (float)myA.Northing);

                    ProjectedPoint myB=FindMarkRoundPoint(previousMark, nextMark);
                    Vector2 myB2 = new Vector2((float)myB.Easting, (float)myB.Northing); ;

                    Vector2 intersect;
                    return GeometryHelper.TryFindIntersection(a2,b2,myA2,myB2, out intersect);
                }
                else
                {
                    float markRoundDistance = 20f;
                    return DistanceTo(a) <= markRoundDistance;
                }
            }
            else if (Bouys.Count == 2)
            {
                ProjectedPoint myA = Bouys[0].CoordinatePoint.Project();
                ProjectedPoint myB = Bouys[1].CoordinatePoint.Project();

                //Vector3 aV = a.ToWorld();
                //Vector3 bV = b.ToWorld();
                //Vector3 myAV = myA.ToWorld();
                //Vector3 myBV = myB.ToWorld();

                Vector2 intersect;
                return GeometryHelper.TryFindIntersection(new Vector2((float)a.Easting, (float)a.Northing), new Vector2((float)b.Easting, (float)b.Northing), new Vector2((float)myA.Easting, (float)myA.Northing), new Vector2((float)myB.Easting, (float)myB.Northing), out intersect);
            }
            else
            {
                throw new Exception("Not Implemented");
            }
        }
コード例 #7
0
ファイル: Mark.cs プロジェクト: brookpatten/VisualSail
        public ProjectedPoint FindMarkRoundPoint(Mark previousMark, Mark nextMark)
        {
            ProjectedPoint myA = AveragedLocation.Project();

            float previousAngle = (float)AngleHelper.FindAngleWTF(previousMark.AveragedLocation.Project(), myA);
            previousAngle = AngleHelper.NormalizeAngle(-previousAngle);

            float nextAngle = (float)AngleHelper.FindAngleWTF(nextMark.AveragedLocation.Project(), myA);
            nextAngle = AngleHelper.NormalizeAngle(-nextAngle);
            
            float roundingAngle = AngleHelper.FindHalfwayCounterClockwiseAngle(previousAngle, nextAngle);

            ProjectedPoint pp=AngleHelper.PolarToRectangular(myA,(double)roundingAngle,1000.0);
            return pp;
        }