protected void DrawHsvDial(DrawingContext drawingContext) { float cx = (float)(Bounds.Width) / 2.0f; float cy = (float)(Bounds.Height) / 2.0f; float outer_radius = (float)Math.Min(cx, cy); ActualOuterRadius = outer_radius; int bmp_width = (int)Bounds.Width; int bmp_height = (int)Bounds.Height; if (bmp_width <= 0 || bmp_height <= 0) { return; } var stopwatch = new Stopwatch(); stopwatch.Start(); //This probably wants to move somewhere else.... if (border == null) { border = new Ellipse(); border.Fill = new SolidColorBrush(Colors.Transparent); border.Stroke = new SolidColorBrush(Colors.Black); border.StrokeThickness = 3; border.IsHitTestVisible = false; border.Opacity = 50; this.Children.Add(border); border.HorizontalAlignment = HA.Center; border.VerticalAlignment = VA.Center; } border.Width = Math.Min(bmp_width, bmp_height) + (border.StrokeThickness / 2); border.Height = Math.Min(bmp_width, bmp_height) + (border.StrokeThickness / 2); var writeableBitmap = new WriteableBitmap(new PixelSize(bmp_width, bmp_height), new Vector(96, 96), PixelFormat.Bgra8888); using (var lockedFrameBuffer = writeableBitmap.Lock()) { unsafe { IntPtr bufferPtr = new IntPtr(lockedFrameBuffer.Address.ToInt64()); for (int y = 0; y < bmp_height; y++) { for (int x = 0; x < bmp_width; x++) { int color_data = 0; // Convert xy to normalized polar co-ordinates double dx = x - cx; double dy = y - cy; double pr = Math.Sqrt(dx * dx + dy * dy); // Only draw stuff within the circle if (pr <= outer_radius) { // Compute the color for the given pixel using polar co-ordinates double pa = Math.Atan2(dx, dy); RGBStruct c = ColorFunction(pr / outer_radius, ((pa + Math.PI) * 180.0 / Math.PI)); // Anti-aliasing // This works by adjusting the alpha to the alias error between the outer radius (which is integer) // and the computed radius, pr (which is float). double aadelta = pr - (outer_radius - 1.0); if (aadelta >= 0.0) { c.a = (byte)(255 - aadelta * 255); } color_data = c.ToARGB32(); } *((int *)bufferPtr) = color_data; bufferPtr += 4; } } } } drawingContext.DrawImage(writeableBitmap, Bounds); stopwatch.Stop(); Debug.WriteLine($"YO! This puppy took {stopwatch.ElapsedMilliseconds} MS to complete"); }
protected void DrawHsvDial(DrawingContext drawingContext) { float cx = (float)this.ActualWidth / 2.0f; float cy = (float)this.ActualHeight / 2.0f; float outer_radius = (float)Math.Min(cx, cy); ActualOuterRadius = outer_radius; //double outer_circumference = 2.0 * Math.PI * outer_radius; int bmp_width = (int)this.ActualWidth; int bmp_height = (int)this.ActualHeight; if (bmp_width <= 0 || bmp_height <= 0) { return; } bitmap = new WriteableBitmap(bmp_width, bmp_height, 96.0, 96.0, PixelFormats.Bgra32, null); bitmap.Lock(); unsafe { int pBackBuffer = (int)bitmap.BackBuffer; for (int y = 0; y < bmp_height; y++) { for (int x = 0; x < bmp_width; x++) { int color_data = 0; //double inner_radius = radius * InnerRadius; // Convert xy to normalized polar co-ordinates double dx = x - cx; double dy = y - cy; double pr = Math.Sqrt(dx * dx + dy * dy); // Only draw stuff within the circle if (pr <= outer_radius) { // Compute the colour for the given pixel using polar co-ordinates double pa = Math.Atan2(dx, dy); RGBStruct c = ColourFunction(pr / outer_radius, ((pa + Math.PI) * 180.0 / Math.PI)); // Anti-aliasing // This works by adjusting the alpha to the alias error between the outer radius (which is integer) // and the computed radius, pr (which is float). double aadelta = pr - (outer_radius - 1.0); if (aadelta >= 0.0) { c.a = (byte)(255 - aadelta * 255); } color_data = c.ToARGB32(); } *((int *)pBackBuffer) = color_data; pBackBuffer += 4; } } } bitmap.AddDirtyRect(new Int32Rect(0, 0, bmp_width, bmp_height)); // I like to get dirty bitmap.Unlock(); drawingContext.DrawImage(bitmap, new Rect(this.RenderSize)); }