public Size GetBestTextureDimension(int w, int h, int count) { const int MAX = 32; int k = 1; while (k < w) { k <<= 1; } w = k; k = 1; while (k < h) { k <<= 1; } h = k; int numSprites = w * h * count; Size bestDimension = new Size(MAX, MAX); for (int i = w; i <= MAX; i <<= 1) { for (int j = h; j <= MAX; j <<= 1) { Size candidateDimension = new Size(i, j); if (candidateDimension.Area() < numSprites) { continue; } if ((candidateDimension.Area() < bestDimension.Area()) || (candidateDimension.Area() == bestDimension.Area() && candidateDimension.Width() + candidateDimension.Height() < bestDimension.Width() + bestDimension.Height())) { bestDimension = candidateDimension; } } } return(bestDimension); }
/// <summary> /// Determines the size of the source image. /// This method is only used when re-projection applies. /// </summary> /// <param name="sourceBoundingBox">The source bounding box.</param> /// <param name="targetSize">Requested target size.</param> /// <returns>The computed source size.</returns> protected virtual Size DetermineSourceSize(IBoundingBox sourceBoundingBox, Size targetSize) { if (!ReprojectionServiceOptions.SourceSizeFactor.HasValue) { return(DetermineSourceSizeByAmountOfPixels(sourceBoundingBox, targetSize.Area())); } if (ReprojectionServiceOptions.SourceSizeFactor.Value < 0) { return(DetermineSourceSizeByAmountOfPixels(sourceBoundingBox, -ReprojectionServiceOptions.SourceSizeFactor.Value * targetSize.Area())); } var aspect = sourceBoundingBox.AspectRatio(); var sizes = new [] { new SizeD(targetSize.Height * aspect, targetSize.Height), new SizeD(targetSize.Width * aspect, targetSize.Width), new SizeD(targetSize.Width, targetSize.Width / aspect), new SizeD(targetSize.Height, targetSize.Height / aspect) }; var min = sizes.Select(s => s.Area()).Min(); var max = sizes.Select(s => s.Area()).Max(); return(DetermineSourceSizeByAmountOfPixels(sourceBoundingBox, min + (max - min) * ReprojectionServiceOptions.SourceSizeFactor.Value)); }
public static Image <TPixel> CreateImage <TPixel>(this Size size, TPixel[] data) where TPixel : struct, IPixel <TPixel> { if (size.Area() <= 0) { throw new ArgumentException(nameof(size)); } if (data == null) { throw new ArgumentNullException(nameof(data)); } if (data.Length < size.Area()) { throw new ArgumentException(nameof(data)); } return(Image.LoadPixelData(_DefaultConfiguration, data, size.Width, size.Height)); }
public static Image <TPixel> CreateImage <TPixel>(this Size size) where TPixel : struct, IPixel <TPixel> { if (size.Area() <= 0) { throw new ArgumentException(nameof(size)); } return(new Image <TPixel>(_DefaultConfiguration, size.Width, size.Height)); }
public void FitManySameSizesInto2TimesBiggerCircle() { var size = new Size(24, 120); var space = size.Area() * Thousand; var radius = Math.Sqrt(2 * space / Math.PI); var rects = Thousand.Times(() => layouter.PutNextRectangle(size)); rects.SelectMany(x => x.Points()) .Select(x => x.DistanceTo(center)) .All(x => x < radius) .Should().BeTrue(); }
public static void RenderSingleSpan(string edgeSpansPath, int spanIndex, int sideResolution) { var resolution = new Size(sideResolution, sideResolution); using var spans = EdgeSpanStream.Load(edgeSpansPath); using var timer = TimedOperation.Start("points", totalWork: resolution.Area()); var random = new Random(); var index = spanIndex >= 0 ? spanIndex : random.Next(0, spans.Count); var imageFilePath = Path.Combine( Path.GetDirectoryName(edgeSpansPath) ?? throw new Exception($"Could not get directory name: {edgeSpansPath}"), Path.GetFileNameWithoutExtension(edgeSpansPath) + $"_{index}_{sideResolution}x{sideResolution}.png"); Log.Info($"Using edge span index {index:N0}"); Log.Info($"Output file: {imageFilePath}"); var span = spans.ElementAt(index).ToConcreteDouble(spans.ViewPort); var spanLength = span.Length(); Log.Info($"Edge span: {span} (length: {spanLength})"); var image = new FastImage(resolution); var viewPort = new ViewPort(GetArea(span), resolution); Log.Info($"View port: {viewPort}"); var positionInSet = viewPort.GetPosition(span.InSet); var positionNotInSet = viewPort.GetPosition(span.NotInSet); var highlightPixelRadius = resolution.Width / 100; var borderPoint = span.FindBoundaryPoint(Constant.IterationRange.Max); Log.Info($"Border point: {borderPoint} (escape time: {ScalarDoubleKernel.FindEscapeTime(borderPoint)})"); var borderPointPosition = viewPort.GetPosition(borderPoint); // TODO: Why is the inner loop parallelized? for (int row = 0; row < resolution.Height; row++) { Parallel.For(0, resolution.Width, col => { var position = new Point(col, row); var c = viewPort.GetComplex(position); Color PickColor() { if (position.DistanceSquaredFrom(positionInSet) <= highlightPixelRadius) { return(Color.Red); } if (position.DistanceSquaredFrom(positionNotInSet) <= highlightPixelRadius) { return(Color.ForestGreen); } if (position.DistanceSquaredFrom(borderPointPosition) <= highlightPixelRadius) { return(Color.Fuchsia); } var isInSet = ScalarDoubleKernel.FindEscapeTime(c, Constant.IterationRange.Max).IsInfinite; return(isInSet ? Color.FromArgb(0x20, 0x20, 0x20) : Color.White); } image.SetPixel(position, PickColor()); }); timer.AddWorkDone(resolution.Width); } image.Save(imageFilePath); }