Ejemplo n.º 1
0
        /// <summary>
        /// Calculate the closest distance to a track, as well as the 'longitude' along it.
        /// </summary>
        /// <param name="trackVectorSection">The vectorsection for which we want to know the distance</param>
        /// <param name="trackSection">The corresponding tracksection</param>
        /// <returns>Distance Squared to the track as well as length along track.</returns>
        /// <remarks>Partly the same code as in Traveller.cs, but here no culling, and we just want the distance.
        /// The math here is not perfect (it is quite difficult to calculate the distances to a curved line
        /// for all possibilities) but good enough. The math was designed (in Traveller.cs) to work well for close distances.
        /// Math is modified to prevent NaN and to combine straight and curved tracks.</remarks>
        DistanceLon CalcRealDistanceSquared(TrVectorSection trackVectorSection, TrackSection trackSection)
        {
            //Calculate the vector from start of track to the mouse
            Vector3 vectorToMouse = new Vector3
            {
                X = storedMouseLocation.Location.X - trackVectorSection.X,
                Z = storedMouseLocation.Location.Z - trackVectorSection.Z
            };

            vectorToMouse.X += (storedMouseLocation.TileX - trackVectorSection.TileX) * 2048;
            vectorToMouse.Z += (storedMouseLocation.TileZ - trackVectorSection.TileZ) * 2048;

            //Now rotate the vector such that a direction along the track is in a direction (x=0, z=1)
            vectorToMouse = Vector3.Transform(vectorToMouse, Matrix.CreateRotationY(-trackVectorSection.AY));

            float lon, lat;

            if (trackSection.SectionCurve == null)
            {
                //Track is straight. In this coordinate system, the distance along track (lon) and orthogonal to track (lat) are easy.
                lon = vectorToMouse.Z;
                lat = vectorToMouse.X;
            }
            else
            {
                // make sure the vector is as if the vector section turns to the left.
                // The center of the curved track is now a (x=-radius, z=0), track starting at (0,0), pointing in positive Z
                if (trackSection.SectionCurve.Angle > 0)
                {
                    vectorToMouse.X *= -1;
                }

                //make vector relative to center of curve. Track now starts at (radius,0)
                vectorToMouse.X += trackSection.SectionCurve.Radius;

                float radiansAlongCurve = (float)Math.Atan2(vectorToMouse.Z, vectorToMouse.X);

                //The following calculations make sense when close to the track. Otherwise they are not necessarily sensible, but at least well-defined.
                // Distance from mouse to circle through track section.
                lat = (float)Math.Sqrt(vectorToMouse.X * vectorToMouse.X + vectorToMouse.Z * vectorToMouse.Z) - trackSection.SectionCurve.Radius;
                lon = radiansAlongCurve * trackSection.SectionCurve.Radius;
            }


            float trackSectionLength = DrawTrackDB.GetLength(trackSection);

            if (lon < 0)
            {   // distance from start of track
                return(new DistanceLon(lat * lat + lon * lon, 0));
            }
            if (lon > trackSectionLength)
            {                                                                                                                     // distance from end of track
                return(new DistanceLon(lat * lat + (lon - trackSectionLength) * (lon - trackSectionLength), trackSectionLength)); //idem
            }
            // somewhere along track. Distance is only in lateral direction
            return(new DistanceLon(lat * lat, lon));
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Find the exact distance of the start of the current tracksection (from the beginning of the vector node)
        /// </summary>
        /// <returns></returns>
        private float GetSectionStartDistance()
        {
            float           distanceFromStart = 0;
            TrackVectorNode tn = TrackDB.TrackNodes[TvnIndex] as TrackVectorNode;

            for (int tvsi = 0; tvsi < TrackVectorSectionIndex; tvsi++)
            {
                TrackVectorSection tvs          = tn.TrackVectorSections[tvsi];
                TrackSection       trackSection = TsectionDat.TrackSections.Get(tvs.SectionIndex);
                if (trackSection != null)  // if trackSection is missing somehow, well, do without.
                {
                    distanceFromStart += DrawTrackDB.GetLength(trackSection);
                }
            }
            return(distanceFromStart);
        }