Esempio n. 1
0
        /// <summary>
        /// Recomputes and reformats the graphics that comprise the scale.
        /// </summary>
        protected virtual void UpdateScale()
        {
            // no point recomputing the scale if client code has made us invisible or we aren't on screen
            if (!this.Visible || (base.ParentPresentationImage != null && base.ParentPresentationImage.ClientRectangle.IsEmpty))
            {
                _isDirty = true;
                return;
            }

            base.CoordinateSystem = CoordinateSystem.Destination;
            try
            {
                PointF pt0 = this.Point1;
                PointF pt1 = this.Point2;

                // draw base line
                FormatBaseLine(_baseLine, pt0, pt1);

                // compute normal to the base line
                TickOffset unitNormal = new TickOffset(pt0.Y - pt1.Y, pt1.X - pt0.X).GetUnitOffset();

                // compute tick marks
                IList <PointF> majorTicks;
                IList <PointF> minorTicks;
                ComputeTickMarks(out majorTicks, out minorTicks, pt0, pt1, false);

                if (majorTicks == null || minorTicks == null)
                {
                    _baseLine.Visible = false;
                    return;
                }

                // draw tick marks
                if (majorTicks.Count + minorTicks.Count > 1)                 // must be at least 2 ticks for this to be useful
                {
                    IList <LinePrimitive> ticks = AllocateTicks(majorTicks.Count + minorTicks.Count);
                    for (int n = 0; n < minorTicks.Count; n++)
                    {
                        FormatMinorTick(ticks[n], minorTicks[n], unitNormal);
                    }
                    for (int n = 0; n < majorTicks.Count; n++)
                    {
                        FormatMajorTick(ticks[minorTicks.Count + n], majorTicks[n], unitNormal);
                    }

                    _baseLine.Visible = true;
                }
                else
                {
                    AllocateTicks(0);
                    _baseLine.Visible = false;
                }

                _isDirty = false;
            }
            finally
            {
                base.ResetCoordinateSystem();
            }
        }
Esempio n. 2
0
		/// <summary>
		/// Recomputes and reformats the graphics that comprise the scale.
		/// </summary>
		protected virtual void UpdateScale()
		{
			// no point recomputing the scale if client code has made us invisible or we aren't on screen
			if (!this.Visible || (base.ParentPresentationImage != null && base.ParentPresentationImage.ClientRectangle.IsEmpty))
			{
				_isDirty = true;
				return;
			}

			base.CoordinateSystem = CoordinateSystem.Destination;
			try
			{
				PointF pt0 = this.Point1;
				PointF pt1 = this.Point2;

				// draw base line
				FormatBaseLine(_baseLine, pt0, pt1);

				// compute normal to the base line
				TickOffset unitNormal = new TickOffset(pt0.Y - pt1.Y, pt1.X - pt0.X).GetUnitOffset();

				// compute tick marks
				IList<PointF> majorTicks;
				IList<PointF> minorTicks;
				ComputeTickMarks(out majorTicks, out minorTicks, pt0, pt1, false);

				if (majorTicks == null || minorTicks == null)
				{
					_baseLine.Visible = false;
					return;
				}

				// draw tick marks
				if (majorTicks.Count + minorTicks.Count > 1) // must be at least 2 ticks for this to be useful
				{
					IList<LinePrimitive> ticks = AllocateTicks(majorTicks.Count + minorTicks.Count);
					for (int n = 0; n < minorTicks.Count; n++)
					{
						FormatMinorTick(ticks[n], minorTicks[n], unitNormal);
					}
					for (int n = 0; n < majorTicks.Count; n++)
					{
						FormatMajorTick(ticks[minorTicks.Count + n], majorTicks[n], unitNormal);
					}

					_baseLine.Visible = true;
				}
				else
				{
					AllocateTicks(0);
					_baseLine.Visible = false;
				}

				_isDirty = false;
			}
			finally
			{
				base.ResetCoordinateSystem();
			}
		}
Esempio n. 3
0
        /// <summary>
        /// Computes positions of major and minor tick marks along the specified line segment.
        /// </summary>
        /// <remarks>
        /// <para>
        /// For performance reasons the arguments are <b>not</b> validated. In particular, the line segment specified by the two points
        /// must be valid and non-trivial - specifying the same point (or close to the same point) for both end points produces indeterminate
        /// results.
        /// </para>
        /// <para>
        /// If the image is not calibrated and has no pixel spacing information, both
        /// <paramref name="majorTicks"/> and <paramref name="minorTicks"/> return null.
        /// </para>
        /// </remarks>
        /// <param name="majorTicks">Output variable to receive a list of major tick positions.</param>
        /// <param name="minorTicks">Output variable to receive a list of minor tick positions.</param>
        /// <param name="linePoint1">One endpoint of the line segment along which to compute tick positions.</param>
        /// <param name="linePoint2">The other endpoint of the line segment along which to compute tick positions.</param>
        /// <param name="allowOverlap">Specifies if minor ticks coincident with an existing major tick should be included in the results.</param>
        protected void ComputeTickMarks(out IList <PointF> majorTicks, out IList <PointF> minorTicks, PointF linePoint1, PointF linePoint2, bool allowOverlap)
        {
            PointF p0 = base.SpatialTransform.ConvertToSource(linePoint1);
            PointF p1 = base.SpatialTransform.ConvertToSource(linePoint2);
            PointF pM = Vector.Midpoint(p0, p1);

            bool   xyW;
            double len;
            double pxR, pxS;
            double pxW, pxH;
            bool   isCalibrated = TryGetPixelDimensions(out pxW, out pxH);

            if (!isCalibrated)
            {
                majorTicks = null;
                minorTicks = null;
                return;
            }

            if (!FloatComparer.AreEqual(p0.X, p1.X, 0.001f))
            {
                pxR = Math.Abs((p0.Y - p1.Y) / (p0.X - p1.X));
                pxS = 1 / Math.Sqrt(pxW * pxW + pxH * pxH * pxR * pxR);
                xyW = false;
                len = Math.Abs(p0.X - p1.X) / pxS;
            }
            else
            {
                pxR = 0f;
                pxS = 1 / Math.Sqrt(pxH * pxH + pxW * pxW * pxR * pxR);
                xyW = true;
                len = Math.Abs(p0.Y - p1.Y) * pxH;
            }

            // compute the square of the effective on-screen tick spacing (in screen pixels)
            // if the effective spacing is less than 3 pixels, the ticks will start being too silly to render distinctly
            const int effectiveScreenTickSpacingThreshold = 9;
            var       screenTickSpacing          = base.SpatialTransform.ConvertToDestination(TickOffset.CreateTickOffset(MinorTick * pxS, pxR, xyW));
            var       effectiveScreenTickSpacing = screenTickSpacing.Width * screenTickSpacing.Width + screenTickSpacing.Height * screenTickSpacing.Height;

            List <PointF> listMajorTicks = new List <PointF>();
            List <PointF> listMinorTicks = new List <PointF>();

            if (this.MinorTick < len && effectiveScreenTickSpacing > effectiveScreenTickSpacingThreshold)
            {
                Dictionary <string, object> map = new Dictionary <string, object>();
                PointF ptPos, ptNeg;

                // compute major tick positions and index their positions
                if (this.MajorTick < len)
                {
                    TickOffset majorOffset = TickOffset.CreateTickOffset(this.MajorTick * pxS, pxR, xyW);
                    ptPos = ptNeg = pM;
                    while (Math.Abs(Vector.SubtendedAngle(p0, ptPos, p1)) > 90)
                    {
                        listMajorTicks.Add(base.SpatialTransform.ConvertToDestination(ptPos));
                        map.Add(string.Format("{0:f2},{1:f2}", ptPos.X, ptPos.Y), null);

                        if (!ptPos.Equals(ptNeg))
                        {
                            listMajorTicks.Insert(0, base.SpatialTransform.ConvertToDestination(ptNeg));
                            map.Add(string.Format("{0:f2},{1:f2}", ptNeg.X, ptNeg.Y), null);
                        }

                        ptPos = ptPos + majorOffset;
                        ptNeg = ptNeg - majorOffset;
                    }
                }

                // compute minor tick positions, checking the index for existence of a major tick at the same position
                TickOffset minorOffset = TickOffset.CreateTickOffset(this.MinorTick * pxS, pxR, xyW);
                ptPos = ptNeg = pM;
                while (Math.Abs(Vector.SubtendedAngle(p0, ptPos, p1)) > 90)
                {
                    if (allowOverlap || !map.ContainsKey(string.Format("{0:f2},{1:f2}", ptPos.X, ptPos.Y)))
                    {
                        listMinorTicks.Add(base.SpatialTransform.ConvertToDestination(ptPos));
                    }

                    if (!ptPos.Equals(ptNeg) && (allowOverlap || !map.ContainsKey(string.Format("{0:f2},{1:f2}", ptNeg.X, ptNeg.Y))))
                    {
                        listMinorTicks.Insert(0, base.SpatialTransform.ConvertToDestination(ptNeg));
                    }

                    ptPos = ptPos + minorOffset;
                    ptNeg = ptNeg - minorOffset;
                }

                // if we don't have room for 2 ticks, try recomputing from one end instead of the middle
                if (listMajorTicks.Count + listMinorTicks.Count < 2)
                {
                    listMajorTicks.Clear();
                    listMinorTicks.Clear();

                    ptPos = p0 + minorOffset;
                    ptNeg = p0 - minorOffset;

                    if (Math.Abs(Vector.SubtendedAngle(p0, ptPos, p1)) > 90)
                    {
                        listMinorTicks.Add(linePoint1);
                        listMinorTicks.Add(base.SpatialTransform.ConvertToDestination(ptPos));
                    }
                    else if (Math.Abs(Vector.SubtendedAngle(p0, ptNeg, p1)) > 90)
                    {
                        listMinorTicks.Add(linePoint1);
                        listMinorTicks.Add(base.SpatialTransform.ConvertToDestination(ptNeg));
                    }
                }
            }

            majorTicks = listMajorTicks.AsReadOnly();
            minorTicks = listMinorTicks.AsReadOnly();
        }