BoltBait Posted February 5 Posted February 5 I know @toe_head2001 has an excellent graph paper plugin, however, it doesn't include labels and shape drawing. So, I rolled my own. I won't publish this as his is better than mine. But, I thought someone might find it interesting as it is GPU accelerated. CodeLab source for BBGraphPaper.cs : Spoiler // Name: Graph Paper // Submenu: Render // Author: BoltBait // Title: BoltBait's Graph Paper v1.1 // Version: 1.1 // Desc: Render Graph Paper // Keywords: graph paper // URL: https://BoltBait.com/pdn // NSC #region UICode IntSliderControl cellSize = 20; // [10,50] Cell Size IntSliderControl offsetWidth = 0; // [-10,10] Center Offset X / Y IntSliderControl offsetHeight = 0; // [-10,10] MultiLineTextboxControl rawPoints = ""; // [32767] Points (one per line) x,y LabelComment comment = "You can close the shape by entering a comma alone on a line. You can start a new shape by entering a blank line."; // CheckboxControl labelPoints = false; // Label points #endregion protected override unsafe void OnDraw(IDeviceContext deviceContext) { deviceContext.AntialiasMode = AntialiasMode.PerPrimitive; deviceContext.TextAntialiasMode = TextAntialiasMode.Grayscale; deviceContext.UseTextRenderingMode(TextRenderingMode.Outline); IDirect2DFactory d2dFactory = this.Services.GetService<IDirect2DFactory>(); IDirectWriteFactory textFactory = this.Services.GetService<IDirectWriteFactory>(); IGdiFontMap fm = textFactory.GetGdiFontMap(); FontProperties fp = fm.TryGetFontProperties("Courier New"); ITextFormat textFormat = textFactory.CreateTextFormat(fp.FontFamilyName, null, fp.Weight, fp.Style, fp.Stretch, cellSize/2.5f); deviceContext.Clear(LinearColors.White); RectFloat sourceBounds = new RectFloat(Point2Float.Zero, Environment.Document.Size); float CenterX = sourceBounds.Center.X + (offsetWidth * cellSize); float CenterY = sourceBounds.Center.Y - (offsetHeight * cellSize); float FirstX = CenterX % cellSize; float FirstY = CenterY % cellSize; ISolidColorBrush grayBrush = deviceContext.CreateSolidColorBrush(LinearColors.Gray); ISolidColorBrush blackBrush = deviceContext.CreateSolidColorBrush(LinearColors.DarkGray); ISolidColorBrush blueBrush = deviceContext.CreateSolidColorBrush(LinearColors.SkyBlue); // draw vertical lines for (float x = FirstX; x < sourceBounds.Width; x += cellSize) { if (x == CenterX) { // Y axis deviceContext.DrawLine(new Point2Float(x,0),new Point2Float(x,sourceBounds.Bottom), blueBrush, 3); } else { if ((x-CenterX) % (cellSize * 5) == 0) { // make every 5 lines darker deviceContext.DrawLine(new Point2Float(x,0),new Point2Float(x,sourceBounds.Bottom), blackBrush, 2); } else { // normal line deviceContext.DrawLine(new Point2Float(x,0),new Point2Float(x,sourceBounds.Bottom), grayBrush, 1, d2dFactory.CreateStrokeStyle(new StrokeStyleProperties(CapStyle.Flat, CapStyle.Flat, CapStyle.Flat, LineJoin.Round, 10f, PaintDotNet.Direct2D1.DashStyle.Dash, 0f, StrokeTransformType.Normal))); } } // X labels RectFloat topTextOffset = RectFloat.Offset(sourceBounds, x+1, CenterY); deviceContext.DrawText(((x-CenterX) / (cellSize)).ToString(),textFormat,topTextOffset, blueBrush); } // draw horizontal lines for (float y = FirstY; y < sourceBounds.Height; y += cellSize) { if (y == CenterY) { // X axis deviceContext.DrawLine(new Point2Float(0,y),new Point2Float(sourceBounds.Right,y), blueBrush, 3); } else { if ((y-CenterY) % (cellSize * 5) == 0) { // make every 5 lines darker deviceContext.DrawLine(new Point2Float(0,y),new Point2Float(sourceBounds.Right,y), blackBrush, 2); } else { // normal line deviceContext.DrawLine(new Point2Float(0,y),new Point2Float(sourceBounds.Right,y), grayBrush, 1, d2dFactory.CreateStrokeStyle(new StrokeStyleProperties(CapStyle.Flat, CapStyle.Flat, CapStyle.Flat, LineJoin.Round, 10f, PaintDotNet.Direct2D1.DashStyle.Dash, 0f, StrokeTransformType.Normal))); } // Y labels RectFloat topTextOffset = RectFloat.Offset(sourceBounds, CenterX +1, y); deviceContext.DrawText(((CenterY-y) / (cellSize)).ToString(),textFormat,topTextOffset, blueBrush); } } // Draw shapes on the graph paper List<string> points = (rawPoints + "\n").Split('\n').ToList(); float previousX = 0, previousY = 0; bool prev = false; bool first = true; int brushIndex = 2; float firstX = 0, firstY = 0; char label = 'A'; List<Point2Float> currentShape = new List<Point2Float>(); FontProperties labelFP = fm.TryGetFontProperties("Arial"); // use your font properties to create a font ITextFormat labelTextFormat = textFactory.CreateTextFormat( labelFP.FontFamilyName, // font family name null, FontWeight.Bold, // font weight FontStyle.Normal, // font style labelFP.Stretch, // how to stretch the font 12); // size in points IReadOnlyList<ColorBgra> DefaultColors = Services.GetService<IPalettesService>().DefaultPalette; //IReadOnlyList<ColorBgra> DefaultColors = Services.GetService<IPalettesService>().CurrentPalette; foreach (string rawPoint in points) { string myPoint = rawPoint.Trim(); // process each line in the text box if (myPoint.Contains(",")) { float x,y; ISolidColorBrush shapeBrush = deviceContext.CreateSolidColorBrush(DefaultColors[brushIndex]); if (myPoint == ",") { x = firstX; y = firstY; } else { if (!float.TryParse(myPoint.Substring(0,myPoint.IndexOf(",")), out x)) { //x = 0; } if (!float.TryParse(myPoint.Substring(myPoint.IndexOf(",")+1), out y)) { //y = 0; } else { y = -y; } currentShape.Add(new Point2Float(x,y)); } if (first) { firstX = x; firstY = y; first = false; } // draw a dot at our specified x,y position deviceContext.DrawRoundedRectangle(new RoundedRect( CenterX+(cellSize * x)-1.5f, CenterY+(cellSize * y)-1.5f, 3, 3, 3 ), shapeBrush,3); // if we have a previous dot, draw a line between them if (prev) { deviceContext.DrawLine( new Point2Float(CenterX+(cellSize * x),CenterY+(cellSize * y)), new Point2Float(CenterX+(cellSize * previousX),CenterY+(cellSize * previousY)), shapeBrush, 2); } previousX = x; previousY = y; prev = true; } else { if (labelPoints) { // Determine the center of our shape float totalX = 0; float totalY = 0; foreach (Point2Float point in currentShape) { totalX += point.X; totalY += point.Y; } float shapeCenterX = totalX / currentShape.Count; float shapeCenterY = totalY / currentShape.Count; // Draw point labels foreach (Point2Float point in currentShape) { float differenceInX = shapeCenterX - point.X; float differenceInY = shapeCenterY - point.Y; float distance = (float)Math.Sqrt((shapeCenterX - point.X)*(shapeCenterX - point.X) + (shapeCenterY - point.Y)*(shapeCenterY - point.Y)); if (distance == 0) { differenceInX = 1; differenceInY = 1; distance = 1; } differenceInX /= distance; differenceInY /= distance; ISolidColorBrush shapeBrush = deviceContext.CreateSolidColorBrush(DefaultColors[brushIndex]); float myX = CenterX+(cellSize * (point.X - (differenceInX * 0.5f)))-4.5f; float myY = CenterY+(cellSize * (point.Y - (differenceInY * 0.5f)))-4.5f; deviceContext.DrawText(label.ToString(),labelTextFormat,new RectFloat(myX,myY,100,100),shapeBrush,DrawTextOptions.None); if (label == 'Z') { label = 'a'; } else if (label == 'z') { label = 'A'; } else { label++; } } } // start the next shape prev = false; first = true; brushIndex += 1; currentShape.Clear(); } } } I use this when helping my kids with their geometry homework. Since the script is just for my own use, it doesn't have a lot of error checking. And, I haven't bothered to go back and clean it up. // you've been warned! Each shape gets a different color. The first shape gets color index 2, red. Then, each shape after that gets the next color from the default color palette. EDIT: Download v2.1 below! 3 3 Quote Download: BoltBait's Plugin Pack | CodeLab | and a Free Computer Dominos Game
Ego Eram Reputo Posted February 6 Posted February 6 Nice! I wanted to have a play with this, but I'm unable to build the DLL from the source (using Codelab 6.11). Appears to Render fine from Codelab ...but has build errors. Edit: Is there a clever way to copy the Error List in Codelab? Quote ebook: Mastering Paint.NET | resources: Plugin Index | Stereogram Tut | proud supporter of Codelab plugins: EER's Plugin Pack | Planetoid | StickMan | WhichSymbol+ | Dr Scott's Markup Renderer | CSV Filetype | dwarf horde plugins: Plugin Browser | ShapeMaker
Ego Eram Reputo Posted February 6 Posted February 6 Quote ebook: Mastering Paint.NET | resources: Plugin Index | Stereogram Tut | proud supporter of Codelab plugins: EER's Plugin Pack | Planetoid | StickMan | WhichSymbol+ | Dr Scott's Markup Renderer | CSV Filetype | dwarf horde plugins: Plugin Browser | ShapeMaker
BoltBait Posted February 6 Author Posted February 6 @Ego Eram Reputo the critical line is here: Make sure you save this script to a file that ends in .cs and open it from there. Make sure the file name does not have a space in it. I call mine BBGraphPaper.cs 1 Quote Download: BoltBait's Plugin Pack | CodeLab | and a Free Computer Dominos Game
Ego Eram Reputo Posted February 6 Posted February 6 10 minutes ago, BoltBait said: Make sure the file name does not have a space in it. You'd think by now I'd have learned this ^. Solved Thank you @BoltBait Quote ebook: Mastering Paint.NET | resources: Plugin Index | Stereogram Tut | proud supporter of Codelab plugins: EER's Plugin Pack | Planetoid | StickMan | WhichSymbol+ | Dr Scott's Markup Renderer | CSV Filetype | dwarf horde plugins: Plugin Browser | ShapeMaker
BoltBait Posted February 6 Author Posted February 6 Published v1.1 with ability to label points. Basically, it calculates the center of each shape, follows a ray from the center of the object through a specific vertex to slightly beyond it and draws the label letter there. So, for regular shapes, the labels will always be outside the shape. For irregular shapes, ymmv. Quote Download: BoltBait's Plugin Pack | CodeLab | and a Free Computer Dominos Game
toe_head2001 Posted February 6 Posted February 6 (edited) 2 hours ago, BoltBait said: Make sure the file name does not have a space in it. I thought that issue was solved a very long time ago. Edit: Fixed in CodeLab. Must have been lost during the GPU refactoring. Edited February 6 by toe_head2001 Quote My Gallery | My Plugin Pack Layman's Guide to CodeLab
lynxster4 Posted February 6 Posted February 6 @BoltBait I followed the instructions throughout (using VS 2022) and I'm getting these error messages in Codelab 6.11: A lot has changed since I was messing with code. Can you guide me? Quote My Art Gallery | My Shape Packs | ShapeMaker Mini Tut | Air Bubble Stained Glass Chrome Text with Reflections | Porcelain Text w/ Variegated Coloring | Realistic Knit PatternOpalescent Stained Glass | Frosted Snowman Cookie | Leather Texture | Plastic Text | Silk Embroidery Visit my Personal Website "Never, ever lose your sense of humor - you'll live longer"
BoltBait Posted February 6 Author Posted February 6 On 2/6/2024 at 5:47 AM, lynxster4 said: Can you guide me? Before pasting the script into CodeLab, do this: Run CodeLab. File > New > GPU Drawing Effect: Only THEN should you select all and paste into the CodeLab editor. OR You could use your favorite text editor (Notepad++) to save the source code to a file BBGraphPaper.cs and then run CodeLab and open it from there. HISTORY: Way back in the day, there used to only be one type of CodeLab script. So, pasting a script into the editor just worked. Now, there are 4+ different types of CodeLab scripts (Classic, Bitmap, GPU Image, and GPU Drawing--not to mention FileTypes and Shapes). In order to compile your script, CodeLab needs to know which type of script it is. This detection happens when you open a new window (through File > New > ...) or when you open a file from disk. Once determined, the effect type can't be changed. In the future, CodeLab may get better at this, but for now, that's just the way it works. EDIT: CodeLab v6.12 no longer has this problem. It will detect what type of script you're trying to compile and adjust itself accordingly. 1 Quote Download: BoltBait's Plugin Pack | CodeLab | and a Free Computer Dominos Game
lynxster4 Posted February 6 Posted February 6 1 hour ago, BoltBait said: Run CodeLab. File > New > GPU Drawing Effect: Thank you, BB! Worked perfectly. This is a neat plugin being able to make geometric shapes. 🤩 Quote My Art Gallery | My Shape Packs | ShapeMaker Mini Tut | Air Bubble Stained Glass Chrome Text with Reflections | Porcelain Text w/ Variegated Coloring | Realistic Knit PatternOpalescent Stained Glass | Frosted Snowman Cookie | Leather Texture | Plastic Text | Silk Embroidery Visit my Personal Website "Never, ever lose your sense of humor - you'll live longer"
BoltBait Posted February 7 Author Posted February 7 Fixed a label bug in the script if there is a point right on the calculated center of the shape or if there was just a single point. Quote Download: BoltBait's Plugin Pack | CodeLab | and a Free Computer Dominos Game
BoltBait Posted February 8 Author Posted February 8 Version 2.0! By turning off "Draw lines connecting points", changing the "Label points" to numeric, I believe someone could use this to create dot-to-dot puzzles for kids. Leave the grid "on" while creating your dot-to-dot, then turn it off for the final render. If you notice in the upper left corner, I did add the Perimeter or Distance. I also found an algorithm for calculating Area... it can get confused if the shape's lines cross, but otherwise works pretty well. According to the site: Screenshots: Download: <Snip!> Download v2.1 in a post below... Source Code: Spoiler I had to switch from CodeLab script into a full project to add the tabs into the UI. I'll leave the CodeLab script for v1.1 in the first post, but it's too long now for posting. Sorry. Plans: I'm pretty much done tinkering with this. I probably won't add it into my plugin pack as it's pretty specialized. But, you can always download it here. Enjoy! 2 2 Quote Download: BoltBait's Plugin Pack | CodeLab | and a Free Computer Dominos Game
Rick Brewster Posted February 15 Posted February 15 On 2/7/2024 at 11:37 PM, BoltBait said: I also found an algorithm for calculating Area You can also use IGeometry::ComputeArea() Quote The Paint.NET Blog: https://blog.getpaint.net/ Donations are always appreciated! https://www.getpaint.net/donate.html
BoltBait Posted February 18 Author Posted February 18 Version 2.1! Just a little clean up of the UI... Added a few more controls to change colors and other options. My son really finds this helpful in his Geometry class. Often, problems will be something like, "You have a triangle with points A(-5,0) B(2,6) and C(6,-2)..." etc. This gives him a quick way to create his drawing for working the problem. This is why I wrote this plugin. Another use for this plugin is to make simple dot-to-dot puzzles for children. Here's one I made: Spoiler 0,0 -5,0 0.5,10 6,0 1,0 1,-2 7,-2 6,-4 -5,-4 -6,-2 0,-2 , Anyway, NOW I'm done tinkering with this! BBGraphPaper.zip Enjoy. 3 3 Quote Download: BoltBait's Plugin Pack | CodeLab | and a Free Computer Dominos Game
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.