/// <summary>
        /// Applies the specified old data rect.
        /// </summary>
        /// <param name="oldDataRect">The old data rect.</param>
        /// <param name="newDataRect">The new data rect.</param>
        /// <param name="viewport">The viewport.</param>
        /// <returns></returns>
        public override DataRect Apply(DataRect oldDataRect, DataRect newDataRect, Viewport2D viewport)
        {
            DataRect res = domain;
            if (domain.IsEmpty)
            {
                res = newDataRect;
            }
            else if (newDataRect.IntersectsWith(domain))
            {
                res = newDataRect;
                if (newDataRect.Size == oldDataRect.Size)
                {
                    if (res.XMin < domain.XMin) res.XMin = domain.XMin;
                    if (res.YMin < domain.YMin) res.YMin = domain.YMin;
                    if (res.XMax > domain.XMax) res.XMin += domain.XMax - res.XMax;
                    if (res.YMax > domain.YMax) res.YMin += domain.YMax - res.YMax;
                }
                else
                {
                    res = DataRect.Intersect(newDataRect, domain);
                }
            }

            return res;
        }
예제 #2
0
		public static DataRect RectZoomY(DataRect rect, Point zoomCenter, double ratio)
		{
			DataRect res = rect;
			res.YMin = zoomCenter.Y - (zoomCenter.Y - rect.YMin) * ratio;
			res.Height = rect.Height * ratio;
			return res;
		}
예제 #3
0
		public static DataRect RectZoomX(DataRect rect, Point zoomCenter, double ratio)
		{
			DataRect res = rect;
			res.XMin = zoomCenter.X - (zoomCenter.X - rect.XMin) * ratio;
			res.Width = rect.Width * ratio;
			return res;
		}
예제 #4
0
		internal RenderState(DataRect renderVisible, DataRect visible, Rect output, RenderTo renderingType)
		{
			this.renderVisible = renderVisible;
			this.visible = visible;
			this.output = output;
			this.renderingType = renderingType;
		}
예제 #5
0
		public static DataRect RectZoom(DataRect rect, Point zoomCenter, double horizontalRatio, double verticalRatio)
		{
			DataRect res = new DataRect();
			res.XMin = zoomCenter.X - (zoomCenter.X - rect.XMin) * horizontalRatio;
			res.YMin = zoomCenter.Y - (zoomCenter.Y - rect.YMin) * verticalRatio;
			res.Width = rect.Width * horizontalRatio;
			res.Height = rect.Height * verticalRatio;
			return res;
		}
		public PhysicalRectAnimation(Viewport2D viewport, Point initialMousePos)
		{
			this.from = viewport.Visible;
			this.viewport = viewport;
			this.initialMousePos = initialMousePos;

			initialTransform = viewport.Transform;

			position = from.Location.ToVector();
		}
		protected override DataRect CoerceVisible(DataRect newVisible)
		{
			if (viewport == null)
				return new DataRect(0, 0, 1, 1);

			if (viewport.PanningState == Viewport2DPanningState.Panning)
				return prevVisible;

			return base.CoerceVisible(newVisible);
		}
		/// <summary>
		/// Determines whether one DataRect is close to another DataRect.
		/// </summary>
		/// <param name="rect1">The rect1.</param>
		/// <param name="rect2">The rect2.</param>
		/// <param name="difference">The difference.</param>
		/// <returns>
		/// 	<c>true</c> if [is close to] [the specified rect1]; otherwise, <c>false</c>.
		/// </returns>
		public static bool IsCloseTo(this DataRect rect1, DataRect rect2, double difference)
		{
			DataRect intersection = DataRect.Intersect(rect1, rect2);
			double square1 = rect1.GetSquare();
			double square2 = rect2.GetSquare();
			double intersectionSquare = intersection.GetSquare();

			bool areClose = MathHelper.AreClose(square1, intersectionSquare, difference) &&
				MathHelper.AreClose(square2, intersectionSquare, difference);
			return areClose;
		}
		public override DataRect GetTileBounds(TileIndex tile)
		{
			if (tile.Level == 0)
				return rect;

			double width = GetTileWidth(tile.Level);
			double height = GetTileHeight(tile.Level);
			double x = 0 + tile.X * width;
			double y = /*minY*/0 + tile.Y * height;

			DataRect bounds = new DataRect(x, y, width, height);
			return bounds;
		}
		private CoordinateTransform(DataRect visibleRect, Rect screenRect)
		{
			this.visibleRect = visibleRect;
			this.screenRect = screenRect;

			rxToScreen = screenRect.Width / visibleRect.Width;
			ryToScreen = screenRect.Height / visibleRect.Height;
			cxToScreen = visibleRect.XMin * rxToScreen - screenRect.Left;
			cyToScreen = screenRect.Height + screenRect.Top + visibleRect.YMin * ryToScreen;

			rxToData = visibleRect.Width / screenRect.Width;
			ryToData = visibleRect.Height / screenRect.Height;
			cxToData = screenRect.Left * rxToData - visibleRect.XMin;
			cyToData = visibleRect.Height + visibleRect.YMin + screenRect.Top * ryToData;
		}
예제 #11
0
        public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
        {
            if (value == null)
            {
                throw base.GetConvertFromException(value);
            }

            string source = value as string;

            if (source != null)
            {
                return(DataRect.Parse(source));
            }

            return(base.ConvertFrom(context, culture, value));
        }
		private void viewport_PanningStateChanged(object sender, ValueChangedEventArgs<Viewport2DPanningState> e)
		{
			if (e.CurrentValue == Viewport2DPanningState.Panning && e.PreviousValue == Viewport2DPanningState.NotPanning)
			{
				prevVisible = Visible;
			}
			else if (e.CurrentValue == Viewport2DPanningState.NotPanning && e.PreviousValue == Viewport2DPanningState.Panning)
			{
				notMineEvent = true;
				try
				{
					Visible = viewport.Visible;
				}
				finally { notMineEvent = false; }
			}
		}
예제 #13
0
        public DataRect Intersect(DataRect rect)
        {
            if (!IntersectsWith(rect))
            {
                return(DataRect.Empty);
            }

            DataRect res = new DataRect();

            double x = Math.Max(this.XMin, rect.XMin);
            double y = Math.Max(this.YMin, rect.YMin);

            res.width  = Math.Max((double)(Math.Min(this.XMax, rect.XMax) - x), 0.0);
            res.height = Math.Max((double)(Math.Min(this.YMax, rect.YMax) - y), 0.0);
            res.xMin   = x;
            res.yMin   = y;

            return(res);
        }
		/// <summary>
		/// Annotates the specified isoline collection.
		/// </summary>
		/// <param name="collection">The collection.</param>
		/// <param name="visible">The visible rectangle.</param>
		/// <returns></returns>
		public Collection<IsolineTextLabel> Annotate(IsolineCollection collection, DataRect visible)
		{
			Collection<IsolineTextLabel> res = new Collection<IsolineTextLabel>();

			foreach (var line in collection.Lines)
			{
				double way = 0;

				var forwardSegments = line.GetSegments();
				var forwardEnumerator = forwardSegments.GetEnumerator();
				forwardEnumerator.MoveNext();

				foreach (var segment in line.GetSegments())
				{
					bool hasForwardSegment = forwardEnumerator.MoveNext();

					double length = segment.GetLength();
					way += length;
					if (way > wayBeforeText)
					{
						way = 0;

						var rotation = (segment.Max - segment.Min).ToAngle();
						if (hasForwardSegment)
						{
							var forwardSegment = forwardEnumerator.Current;
							rotation = (rotation + (forwardSegment.Max - forwardSegment.Min).ToAngle()) / 2;
						}

						res.Add(new IsolineTextLabel
						{
							Value = line.RealValue,
							Position = segment.Max,
							Rotation = rotation
						});
					}
				}
			}

			return res;
		}
예제 #15
0
		protected override DataRect CoerceVisible(DataRect newVisible, DataRect baseVisible)
		{
			DataRect result = newVisible;

			if (Plotter == null)
				return baseVisible;

			DataRect outerVisible = Plotter.Viewport.Visible;

			double xMin = outerVisible.XMin * xScale + xShift;
			double xMax = outerVisible.XMax * xScale + xShift;
			double yMin = outerVisible.YMin * yScale + yShift;
			double yMax = outerVisible.YMax * yScale + yShift;

			outerVisible = DataRect.Create(xMin, yMin, xMax, yMax);

			switch (ConjunctionMode)
			{
				case ViewportConjunctionMode.None:
					result = baseVisible;
					break;
				case ViewportConjunctionMode.X:
					result = new DataRect(outerVisible.XMin, baseVisible.YMin, outerVisible.Width, baseVisible.Height);
					break;
				case ViewportConjunctionMode.Y:
					result = new DataRect(baseVisible.XMin, outerVisible.YMin, baseVisible.Width, outerVisible.Height);
					break;
				case ViewportConjunctionMode.XY:
					result = outerVisible;
					break;
				default:
					break;
			}

			return result;
		}
		public override IEnumerable<TileIndex> GetTilesForRegion(DataRect region, double level)
		{
			region.Intersect(rect);
			//region.Intersect(new Rect(region.XMin, minY, region.Width, maxY - minY));
			if (region.IsEmpty)
				yield break;

			checked
			{
				double tileWidth = TileWidth;
				double tileHeight = TileHeight;

				int minIx = (int)Math.Floor(region.XMin / tileWidth);
				int maxIx = (int)Math.Ceiling(region.XMax / tileWidth);

				int minIy = (int)Math.Floor(region.YMin / tileHeight);
				int maxIy = (int)Math.Ceiling(region.YMax / tileHeight);

				var maxSideCount = GetSideTilesCount(Level);

				int maxIndex = maxSideCount / 2;
				if (maxIx > maxIndex)
					maxIx = maxIndex;
				if (maxIy > maxIndex)
					maxIy = maxIndex;
				if (minIx < -maxIndex)
					minIx = -maxIndex;
				if (minIy < -maxIndex)
					minIy = -maxIndex;

				if (level != 0)
				{
					maxIx--;
					maxIy--;
				}


				for (int ix = minIx; ix <= maxIx; ix++)
				{
					for (int iy = minIy; iy <= maxIy; iy++)
					{
						yield return new TileIndex(ix, iy, level);
					}
				}
			}
		}
예제 #17
0
		protected virtual Rect GetElementScreenBoundsCore(CoordinateTransform transform, UIElement child)
		{
			Rect bounds = new Rect(0, 0, 1, 1);

			DataRect ownViewportBounds = GetViewportBounds(child);
			if (!ownViewportBounds.IsEmpty)
			{
				bounds = ownViewportBounds.ViewportToScreen(transform);
			}
			else
			{
				double viewportX = GetX(child);
				double viewportY = GetY(child);

				if (viewportX.IsNaN() || viewportY.IsNaN())
				{
					//Debug.WriteLine("ViewportRectPanel: Position is not set!");

					return bounds;
				}

				double viewportWidth = GetViewportWidth(child);
				if (viewportWidth < 0) viewportWidth = 0;
				double viewportHeight = GetViewportHeight(child);
				if (viewportHeight < 0) viewportHeight = 0;

				bool hasViewportWidth = viewportWidth.IsNotNaN();
				bool hasViewportHeight = viewportHeight.IsNotNaN();

				DataRect r = new DataRect(new Size(hasViewportWidth ? viewportWidth : child.DesiredSize.Width,
										   hasViewportHeight ? viewportHeight : child.DesiredSize.Height));
				r = r.ViewportToScreen(transform);

				double screenWidth = hasViewportWidth ? r.Width : child.DesiredSize.Width;
				double screenHeight = hasViewportHeight ? r.Height : child.DesiredSize.Height;

				double minScreenWidth = GetMinScreenWidth(child);
				bool hasMinScreemWidth = minScreenWidth.IsNotNaN();

				if (hasViewportWidth && screenWidth < minScreenWidth)
					screenWidth = minScreenWidth;

				Point location = new Point(viewportX, viewportY).ViewportToScreen(transform);

				double screenX = location.X;
				double screenY = location.Y;

				HorizontalAlignment horizAlignment = GetViewportHorizontalAlignment(child);
				switch (horizAlignment)
				{
					case HorizontalAlignment.Stretch:
					case HorizontalAlignment.Center:
						screenX -= screenWidth / 2;
						break;
					case HorizontalAlignment.Left:
						break;
					case HorizontalAlignment.Right:
						screenX -= screenWidth;
						break;
				}

				VerticalAlignment vertAlignment = GetViewportVerticalAlignment(child);
				switch (vertAlignment)
				{
					case VerticalAlignment.Bottom:
						screenY -= screenHeight;
						break;
					case VerticalAlignment.Center:
					case VerticalAlignment.Stretch:
						screenY -= screenHeight / 2;
						break;
					case VerticalAlignment.Top:
						break;
					default:
						break;
				}

				bounds = new Rect(screenX, screenY, screenWidth, screenHeight);
			}

			// applying screen offset
			double screenOffsetX = GetScreenOffsetX(child);
			if (screenOffsetX.IsNaN()) screenOffsetX = 0;
			double screenOffsetY = GetScreenOffsetY(child);
			if (screenOffsetY.IsNaN()) screenOffsetY = 0;

			Vector screenOffset = new Vector(screenOffsetX, screenOffsetY);
			bounds.Offset(screenOffset);

			return bounds;
		}
예제 #18
0
		protected virtual Size GetElementSize(FrameworkElement child, Size availableSize, CoordinateTransform transform)
		{
			Size result = availableSize;

			DataRect ownViewportBounds = GetViewportBounds(child);
			if (!ownViewportBounds.IsEmpty)
			{
				result = ownViewportBounds.ViewportToScreen(transform).Size;
			}
			else
			{
				double viewportWidth = GetViewportWidth(child);
				double viewportHeight = GetViewportHeight(child);

				bool hasViewportWidth = viewportWidth.IsNotNaN();
				bool hasViewportHeight = viewportHeight.IsNotNaN();

				double minScreenWidth = GetMinScreenWidth(child);
				bool hasMinScreenWidth = minScreenWidth.IsNotNaN();

				double selfWidth = child.Width.IsNotNaN() ? child.Width : availableSize.Width;
				double width = hasViewportWidth ? viewportWidth : selfWidth;

				double selfHeight = child.Height.IsNotNaN() ? child.Height : availableSize.Height;
				double height = hasViewportHeight ? viewportHeight : selfHeight;

				if (width < 0) width = 0;
				if (height < 0) height = 0;

				DataRect bounds = new DataRect(new Size(width, height));
				Rect screenBounds = bounds.ViewportToScreen(transform);

				result = new Size(hasViewportWidth ? screenBounds.Width : selfWidth,
					hasViewportHeight ? screenBounds.Height : selfHeight);

				if (hasMinScreenWidth && result.Width < minScreenWidth)
				{
					result.Width = minScreenWidth;
				}
			}

			if (result.Width.IsNaN()) result.Width = 0;
			if (result.Height.IsNaN()) result.Height = 0;

			return result;
		}
 /// <summary>
 /// Initializes a new instance of the <see cref="DomainRestriction"/> class with given domain property.
 /// </summary>
 /// <param name="domain">The domain.</param>
 public DomainRestriction(DataRect domain)
 {
     this.Domain = domain;
 }
예제 #20
0
		protected override Size ArrangeOverride(Size finalSize)
		{
			if (plotter == null)
				return finalSize;

			var transform = plotter.Viewport.Transform;

			overallViewportBounds = DataRect.Empty;
			foreach (UIElement child in InternalChildren)
			{
				if (child != null)
				{
					if (child.Visibility != Visibility.Visible)
						continue;

					Rect bounds = GetElementScreenBounds(transform, child);
					child.Arrange(bounds);

					UniteWithBounds(transform, bounds);
				}
			}

			if (!InBatchAdd)
			{
				Viewport2D.SetContentBounds(this, overallViewportBounds);
				ContentBoundsChanged.Raise(this);
			}

			return finalSize;
		}
예제 #21
0
		private bool OccupyCells(Point position, Point next, DataRect bounds)
		{
			double xCoeff = bounds.Width / occupiedTableWidth;
			double yCoeff = bounds.Height / occupiedTableHeight;

			int startIx = (int)((position.X - bounds.XMin) / xCoeff);
			int startIy = (int)((position.Y - bounds.YMin) / yCoeff);

			int endIx = (int)((next.X - bounds.XMin) / xCoeff);
			int endIy = (int)((next.Y - bounds.YMin) / yCoeff);

			Vector direction = next - position;
			direction.Normalize();
			Point start = new Point(startIx + 0.5, startIy + 0.5);
			Point end = new Point(endIx + 0.5, endIy + 0.5);

			Vector up = new Vector(0, 1);
			Vector down = new Vector(0, -1);
			Vector left = new Vector(-1, 0);
			Vector right = new Vector(1, 0);

			int ix = startIx;
			int iy = startIy;

			if (ix < 0 || ix >= occupiedTableWidth ||
				iy < 0 || iy >= occupiedTableHeight)
				return false;
			do
			{
				occupiedTable[ix, iy] += 1;

				Point nextPoint = start + direction;

				List<PointDescription> neighbours = new List<PointDescription>();
				AddIfInside(new PointDescription { Point = start + up, DeltaX = 0, DeltaY = 1 }, neighbours);
				AddIfInside(new PointDescription { Point = start + down, DeltaX = 0, DeltaY = -1 }, neighbours);
				AddIfInside(new PointDescription { Point = start + left, DeltaX = -1, DeltaY = 0 }, neighbours);
				AddIfInside(new PointDescription { Point = start + right, DeltaX = 1, DeltaY = 0 }, neighbours);

				foreach (var pt in neighbours)
				{
					var distance = DistanceFromSegmentToPoint(start, end, pt.Point);
					if (distance < 1)
					{
						ix += pt.DeltaX;
						iy += pt.DeltaY;

						if (ix < 0 || ix >= occupiedTableWidth ||
							iy < 0 || iy >= occupiedTableHeight)
							return false;
							

						if (occupiedTable[ix, iy] > 1) return false;

						occupiedTable[ix, iy] += 1;
						break;
					}
				}

			} while (ix != endIx && iy != endIy);

			return true;
		}
        private void CreateRenderTask(DataRect visible, Rect output)
        {
            lock (this)
            {
                bitmapInvalidated = true;

                if (activeRequest != null)
                    activeRequest.Cancel();
                pendingRequest = new RenderRequest(nextRequestId++, visible, output);
                renderRequested.Set();
            }
            if (renderThread == null)
            {
                renderThread = new Thread(RenderThreadFunc);
                renderThread.IsBackground = true;
                renderThread.SetApartmentState(ApartmentState.STA);
                renderThread.Start();
            }
        }
 protected override void OnVisibleChanged(DataRect newRect, DataRect oldRect)
 {
     base.OnVisibleChanged(newRect, oldRect);
     CreateRenderTask(newRect, Viewport.Output);
     InvalidateVisual();
 }
		public static DataRect GetTileBoundsGeneric(TileIndex tile)
		{
			double width = 360.0 / Math.Pow(2, tile.Level);
			double height = 174.0 / Math.Pow(2, tile.Level);
			double x = /*minX*/0 + tile.X * width;
			double y = /*minY*/0 + tile.Y * height;

			DataRect bounds = new DataRect(x, y, width, height);
			return bounds;
		}
 protected virtual UIElement GetTooltipForPoint(Point point, DataRect visible, Rect output)
 {
     return null;
 }
예제 #26
0
		void IPlotterElement.OnPlotterDetaching(Plotter plotter)
		{
			OnPlotterDetaching(plotter);

			var debugMenu = plotter.Children.OfType<DebugMenu>().FirstOrDefault();
			if (debugMenu != null)
			{
				debugMenu.Menu.Items.Remove(mapsMenu);
			}

			visibleBounds = new Rect();

			this.plotter.CentralGrid.Children.Remove(this);
			this.plotter.Viewport.PropertyChanged -= Viewport_PropertyChanged;

			this.plotter.Viewport.Constraints.Remove(proportionsConstraint);
			this.plotter.Viewport.Constraints.Remove(maxSizeConstraint);

			this.plotter.Children.CollectionChanged -= PlotterChildren_CollectionChanged;

			RevertTextFormat();

			this.plotter = null;
		}
 protected abstract BitmapSource RenderFrame(DataRect visible, Rect output);
예제 #28
0
		protected override void RebuildUI()
		{
			// removing all triangles
			foreach (var triangle in triangles)
			{
				trianglesPool.Put(triangle);
				viewport3D.Children.Remove(triangle);
			}

			var dataSource = DataSource;
			if (dataSource == null)
				return;

			var palette = Palette;
			if (palette == null)
				return;

			width = dataSource.Width;
			height = dataSource.Height;

			minMaxLength = dataSource.GetMinMaxLength();
			bounds = dataSource.GetGridBounds();
			vectorLength = Math.Sqrt(bounds.Width * bounds.Width / (width * width) + bounds.Height * bounds.Height / (height * height));

			for (int i = 0; i < width; i++)
			{
				for (int j = 0; j < height; j++)
				{
					var direction = dataSource.Data[i, j];
					var position = dataSource.Grid[i, j];

					var triangle = CreateTriangle(position, direction);
					triangles.Add(triangle);

					viewport3D.Children.Add(triangle);
				}
			}
		}
 public RenderRequest(int requestId, DataRect visible, Rect output)
 {
     this.requestId = requestId;
     this.visible = visible;
     this.output = output;
 }
예제 #30
0
		protected override void InvalidatePosition(FrameworkElement child)
		{
			invalidatePositionCalls++;

			if (viewport == null) return;
			if (child.Visibility != Visibility.Visible)
				return;

			var transform = viewport.Transform;

			Size elementSize = GetElementSize(child, AvailableSize, transform);
			child.Measure(elementSize);

			Rect bounds = GetElementScreenBounds(transform, child);
			child.Arrange(bounds);

			var viewportBounds = Viewport2D.GetContentBounds(this);
			if (!viewportBounds.IsEmpty)
				overallViewportBounds = viewportBounds;

			UniteWithBounds(transform, bounds);

			if (!InBatchAdd)
			{
				Viewport2D.SetContentBounds(this, overallViewportBounds);
				ContentBoundsChanged.Raise(this);
			}
		}
예제 #31
0
		private void RebuildUI()
		{
			if (DataSource == null)
			{
				//todo: clear
				return;
			}

			panel.Children.Clear();

			int width = DataSource.Width;
			int height = DataSource.Height;
			bounds = DataSource.Grid.GetGridBounds();
			fieldWrapper = new UniformFieldWrapper(DataSource.Data, width, height);

			List<Point[]> tracks = new List<Point[]>(pointsNum);
			for (int i = 0; i < pointsNum; i++)
			{
				var track = new List<Point>();

				var start = rnd.NextPoint(bounds.XMin, bounds.XMax, bounds.YMin, bounds.YMax);
				track.Add(start);

				int maxLength = Math.Max(width, height);
				var position = start;
				double length = 0;
				do
				{
					var K1 = fieldWrapper.GetVector(position);
					K1.Normalize();
					//var shift = K1;
					var K2 = fieldWrapper.GetVector(position + (K1 / 2).DecreaseLength(width, height));
					K2.Normalize();
					var K3 = fieldWrapper.GetVector(position + (K2 / 2).DecreaseLength(width, height));
					K3.Normalize();
					var K4 = fieldWrapper.GetVector(position + K3.DecreaseLength(width, height));
					K4.Normalize();

					var shift = ((K1 + 2 * K2 + 2 * K3 + K4) / 6);
					//shift.Normalize();
					if (shift.X.IsNaN() || shift.Y.IsNaN())
						break;

					var next = position + shift;
					track.Add(next);

					if (!OccupyCells(position, next, bounds))
						break;

					position = next;
					length += shift.Length;
				} while (length < maxLength);

				Polyline line = new Polyline
				{
					Stroke = Brushes.Orange,
					StrokeThickness = 1,
					Stretch = Stretch.Fill,
					Points = new PointCollection(track),
					Effect = new DropShadowEffect { Color = Colors.Black, Direction = 245, BlurRadius = 3 }
				};
				ViewportPanel.SetViewportBounds(line, track.GetBounds());
				panel.Children.Add(line);
			}
		}
예제 #32
0
		private void UpdateContentBounds(bool recalculate)
		{
			if (recalculate)
			{
				var transform = plotter.Viewport.Transform;
				overallViewportBounds = DataRect.Empty;
				foreach (FrameworkElement child in Children)
				{
					if (child != null)
					{
						if (child.Visibility != Visibility.Visible)
							continue;

						Rect bounds = GetElementScreenBounds(transform, child);
						UniteWithBounds(transform, bounds);
					}
				}
			}

			Viewport2D.SetContentBounds(this, overallViewportBounds);
			ContentBoundsChanged.Raise(this);
		}