Jump to content

Affine Transforms, line corners, beziers etc


aphillips
 Share

Recommended Posts

One thing I always wanted in PDN was to be able to rotate shapes. GDI+ has such great support for affine transformations (rotate, scale etc) that it seemed it would be easy to do this and a shame not to. (I always though it pathetic that earlier versions of Windows could only draw ellipses, rectangles, text etc parallel to the X and Y axes.)

A couple of years ago I actually added the ability to apply affine transformations to shapes, before they were "finalised" in the bitmap (in PDN 2.1). This used the fairly standard mechanism of "handles" (also sometimes called "control points") to allow transformations:

1. Initially 4 handles on the sides of object bounding rectangle that allowed scaling in X or Y

2. Handles on corners that allowed proportional scaling in X and Y together

3. Center handle that allowed moving (translating) the object unchanged

4. Click anywhere else in the bounding box to go from "scaling" mode (above) to "rotating" mode

5. In rotate mode, handles on the 4 corners are provided to rotate the object to any angle

6. The center handle moves the center of rotation

7. Handles on the four sides for skew

8. Click anywhere else in the bounding box to go into "adjusting" mode

9. Handles for original clicked points to adjust the shape (eg the 2 corners for a rectangle)

10. Click any where else in the bounding box to go back to "scaling" mode

11. Click outside the bounding box to "finalise" the shape

This was fairly easy to do in PDN 2.1. The main problem was drawing the handles in XOR mode for which I had to go to the Windows API (since GDI+ does not support drawing in XOR mode for some reason).

PDN 3.10

---------

With the release the much improved (MDI!) PDN 3, I thought it was time to port the above changes. I was pleasantly surprised to find the "nub" system which I could easily extend and do away with my ugly "handles" and Windows API calls. I managed to port my changes to 3.10 in a few hours and they worked very well.

Encouraged by this I then implemented Polygon and Polyline tools. The polygon tool is much like the freeform shape tool but only adds points to the shape whenever the user clicks the mouse, joining them with straight lines. The polyline tool is similar but is not a closed shape and hence cannot be filled.

This took even less time so I then added a new toolbar corner type drop-down list which allowed control of the shape of line corners (ie how 2 line segments are joined together). This control gives the option of rounded, flat, or clipped (sharp corners which are clipped if the angle is too acute). [Currently in PDN 3.10 line corners are always sharp but revert to flat (not clipped) if they become too acute. The effect is not often seen with current shapes (but can be seen in the freeform shape or a very flat ellipse, ...?) but with the ability to have polygons, polylines and skewed rectangles control of line joins becomes important.]

Further encouraged by this I added full bezier support to polylines. This allows either sharp joins by left-clicking (which use the above-mentioned line corner control) or smooth joins by right-clicking. As in other programs adjusting the bezier handle at a smooth join moves the opposing bezier diametrically opposite in order to preserve the perfectly smooth join.

Also polylines also support the line styles (dash etc) as well as line caps (rounded, arrow etc) which was added for the line tool in 3.10.

I was amazed at how simple it was to make these improvements and how useful these features are. Not only can you rotate, scale, etc and adjust the shape of object (eg corners of the rectangle or polygon), you can also adjust any other of the shape drawing parameters (brush width, fills, line ends, anti-aliasing etc) before the shape is "finalised".

Try it

-----

If you want to try the changes you can download a zip file from Edit by Rick: download link removed, see last post and just copy the files over the corresponding files after installing Paint.Net 3.10. (Of course, you should keep a copy of the original files before overwriting them.) Then run PaintDotNet.exe as normal.

See below an actual screen capture highlighting these features. This was annotated with PainDoNet (of course) using the new arrow line caps feature:

Future

------

There are still a few more things I have thought of which I have not yet had time to do, but these would be easy judging by my above experience.

1. Bezier support to polygons (just like in polylines).

2. The ability to rotate text would be useful.

3. Control of rounding radius for rounded rectangles.

4. Constrain angles of polygon/line to make it easy to draw shapes like a right-angle triangle.

5. Better polyline bezier "nubs" that indicate which corner they are associated with

Thanks

-------

Thanks to Rick et al for making the source available and creating software that is so incredibly easy to modify.

73_769ca6c87007b7755123166a069322a8

Link to comment
Share on other sites

Simply amazing! Great job.

I really like the new handles. Its almost like the matte/shape plugin but built in and easier to work with :)

I was wondering when someone would take the source and do something productive :P :wink:

Again, thank you!

"Only two things are infinite, the universe and human stupidity, and I'm not sure about the former"

[ dA Paint.NET Chat :: Yata on dA ]

Link to comment
Share on other sites

Keep it up and I won't need InkScape half as much :)

You need to fix the tooltip for PolyLine...It says the same thing as Polygon:

wrongtooltip.png

EDIT:

Rick...any chance of pulling this into the next official minor release?

I'd have to rate it a 10/10 on the "drawing usefullness" scale.

drakaan sig jan 2020.png

Link to comment
Share on other sites

Whoops...

It crashed...

This text file was created because Paint.NET crashed.
Please e-mail this file to  so we can diagnose and fix the problem.

Application version: Paint.NET v3.10 (Final Release build 3.10.2813.41911)
Time of crash: 14/09/2007 16:48:49
Application uptime: 00:08:55.6406250
OS Version: 5.1.2600.131072 Service Pack 2 Workstation x86
.NET Framework version: 2.0.50727.832 x86
Processor: 2x "Intel(R) Pentium(R) D CPU 2.80GHz" @ ~2800MHz (SSE, SSE2)
Physical memory: 1022 MB
Tablet PC: no
Locale: pdnr.c: en-US, hklm: en-US, hkcu: n/a, cc: en-GB, cuic: en-US

Exception details:
System.ArgumentException: Parameter is not valid.
  at System.Drawing.Drawing2D.GraphicsPath.AddBeziers(PointF[] points)
  at PaintDotNet.PdnGraphicsPath.AddBeziers(PointF[] points)
  at PaintDotNet.Tools.PolylineTool.CreateShapePath(PointF[] points)
  at PaintDotNet.Tools.ShapeTool.CreateTransformedPath(PointF[] points)
  at PaintDotNet.Tools.ShapeTool.RenderShape()
  at PaintDotNet.Tools.ShapeTool.CommitShape()
  at PaintDotNet.Tools.ShapeTool.OnDeactivate()
  at PaintDotNet.Tools.PolylineTool.OnDeactivate()
  at PaintDotNet.Tool.Deactivate()
  at PaintDotNet.DocumentWorkspace.SetTool(Tool copyMe)
  at PaintDotNet.DocumentWorkspace.PushNullTool()
  at PaintDotNet.HistoryStack.StepBackwardImpl()
  at PaintDotNet.HistoryStack.StepBackward()
  at PaintDotNet.Tools.ShapeTool.OnKeyPress(KeyPressEventArgs e)
  at PaintDotNet.AppWorkspace.DocumentKeyPress(Object sender, KeyPressEventArgs e)
  at PaintDotNet.DocumentView.OnDocumentKeyPress(KeyPressEventArgs e)
  at PaintDotNet.DocumentView.Panel_KeyPress(Object sender, KeyPressEventArgs e)
  at System.Windows.Forms.Control.OnKeyPress(KeyPressEventArgs e)
  at System.Windows.Forms.Control.ProcessKeyEventArgs(Message& m)
  at System.Windows.Forms.Control.ProcessKeyMessage(Message& m)
  at System.Windows.Forms.Control.WmKeyChar(Message& m)
  at System.Windows.Forms.Control.WndProc(Message& m)
  at System.Windows.Forms.ScrollableControl.WndProc(Message& m)
  at PaintDotNet.SystemLayer.ScrollPanel.WndProc(Message& m)
  at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
  at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
  at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
------------------------------------------------------------------------------

Lorenz_84_signature_by_PhillipsJ2.png

"I am the anarchist, I am the antichrist, I am the walrus, G'JOO G'GOO G'JOOB!"

I dig a pygmy, by Charles Hawtree and the Deaf Aids. Phase One, in which Doris gets her oats.

~John Lennon

Link to comment
Share on other sites

When I click on the forum button.

Other then this. It's very cool :)

This text file was created because Paint.NET crashed.
Please e-mail this file to  so we can diagnose and fix the problem.

Application version: Paint.NET v3.10 (Final Release build 3.10.2813.41911)
Time of crash: 9/14/2007 9:00:32 AM
Application uptime: 00:00:04.1459616
OS Version: 5.1.2600.131072 Service Pack 2 Workstation x86
.NET Framework version: 2.0.50727.42 x86
Processor: 1x "Intel(R) Pentium(R) M processor 1.50GHz" @ ~1497MHz (SSE, SSE2)
Physical memory: 510 MB
Tablet PC: no
Locale: pdnr.c: en-US, hklm: en-US, hkcu: en-US, cc: en-US, cuic: en-US

Exception details:
System.UriFormatException: Invalid URI: The URI is empty.
  at System.Uri.CreateThis(String uri, Boolean dontEscape, UriKind uriKind)
  at System.Uri..ctor(String uriString)
  at PaintDotNet.PdnInfo.LaunchWebSite(IWin32Window owner, String page)
  at PaintDotNet.Menus.HelpMenu.MenuHelpForum_Click(Object sender, EventArgs e)
  at System.Windows.Forms.ToolStripItem.RaiseEvent(Object key, EventArgs e)
  at System.Windows.Forms.ToolStripMenuItem.OnClick(EventArgs e)
  at PaintDotNet.PdnMenuItem.OnClick(EventArgs e)
  at System.Windows.Forms.ToolStripItem.HandleClick(EventArgs e)
  at System.Windows.Forms.ToolStripItem.HandleMouseUp(MouseEventArgs e)
  at System.Windows.Forms.ToolStripItem.FireEventInteractive(EventArgs e, ToolStripItemEventType met)
  at System.Windows.Forms.ToolStripItem.FireEvent(EventArgs e, ToolStripItemEventType met)
  at System.Windows.Forms.ToolStrip.OnMouseUp(MouseEventArgs mea)
  at System.Windows.Forms.ToolStripDropDown.OnMouseUp(MouseEventArgs mea)
  at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
  at System.Windows.Forms.Control.WndProc(Message& m)
  at System.Windows.Forms.ScrollableControl.WndProc(Message& m)
  at System.Windows.Forms.ToolStrip.WndProc(Message& m)
  at System.Windows.Forms.ToolStripDropDown.WndProc(Message& m)
  at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
  at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
  at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
------------------------------------------------------------------------------

The_next_thousand_words_by_0_ASH_0.png

All creations Ash + Paint.NET [ Googlepage | deviantArt | Club PDN | PDN Fan ]

Link to comment
Share on other sites

Here's a UI issue. When I draw a constrained rectangle (Holding Shift), I have to continue holding it down while making scale/rotate/skew adjustments. The constrainedness of the object should be finalized once the initial dimensions of the object are set, IMO.

 

Take responsibility for your own intelligence. ;) -Rick Brewster

Link to comment
Share on other sites

Rick...any chance of pulling this into the next official minor release?

I'd have to rate it a 10/10 on the "drawing usefullness" scale.

It's doubtful, even if he releases his source code. The reason I say this is simply because of the design changes I'm eyeing for 4.0. Right now it's a lot of work and complexity to implement this type of stuff in 3.x. I have wanted for awhile to refactor the tool system to make more advanced stuff a lot easier and cleaner to implement. So I'd rather do that and then revamp the tools, instead of spending a lot of time now revamping, and a lot of time later (for 4.0) revamping. Not to mention the reduction in bug churn -- as you have no doubt seen from the flood of bug reports coming in for this mod ;)

The Paint.NET Blog: https://blog.getpaint.net/

Donations are always appreciated! https://www.getpaint.net/donate.html

forumSig_bmwE60.jpg

Link to comment
Share on other sites

Rick...any chance of pulling this into the next official minor release?

I'd have to rate it a 10/10 on the "drawing usefullness" scale.

It's doubtful, even if he releases his source code. The reason I say this is simply because of the design changes I'm eyeing for 4.0. Right now it's a lot of work and complexity to implement this type of stuff in 3.x. I have wanted for awhile to refactor the tool system to make more advanced stuff a lot easier and cleaner to implement. So I'd rather do that and then revamp the tools, instead of spending a lot of time now revamping, and a lot of time later (for 4.0) revamping. Not to mention the reduction in bug churn -- as you have no doubt seen from the flood of bug reports coming in for this mod ;)

s'okay...I've been using it with no crashes so far, and I can live with it as an unofficial patch. These are aphillips' bugs, anyway :)

That makes me thoughtful, though...how far along *are* you in designing 4.0? What percentage of the codebase ends up rewritten? (Guessing a pretty large number for a full version change).

Have you given any thought to doing an interview about Paint.NET and what's coming in 4.0? You're pretty good about responding to stuff on the forums and giving notice of changes on the blog, but a Q & A-type interview might make a lot of people happy (I know I'd appreciate the insight).

What do you think about that?

drakaan sig jan 2020.png

Link to comment
Share on other sites

I'm not worried about you, per se ... it's other random people coming on to the forum going, "Yay!" and installing it. Then it crashes and they send the crash log to me, or they install an update and ask "Where did the features go :(" forgetting that the features were neither official nor plugins.

Although, looking at the crash logs already posted, it looks like my e-mail is thankfully not placed in there (I decided to start "scrubbing" these out of the source code a few releases ago for exactly the reasons I just listed).

The Paint.NET Blog: https://blog.getpaint.net/

Donations are always appreciated! https://www.getpaint.net/donate.html

forumSig_bmwE60.jpg

Link to comment
Share on other sites

Sorry, I only just got back to read the replies. Just a few notes on my changes:

1. First this was just a demonstration of enhancements that I think should be added to PDN. (I actually suggested allowing affine transformations years ago in the forums.) I thought an actual demonstration would show its usefulness, rather than harping on about it.

These changes were never intended to be incorporated into PDN as is, and should not be. Rick can better decide how/if/when they should be done. For example, the polyline tool and the line tool are probably better combined somehow.

2. It has a few rough edges. The nub shapes I made are pretty ordinary. Also I was aware of the problem with constrained shapes that barkbark00 pointed out but forgot to mention it. It should be addressed.

3. Bugs. I originally modified the code to draw shapes using my preferred method of a click for each point. (Ie drawing the basic shapes requires 2 clicks instead of click-drag-release.) This is also more consistent with how polygons/polylines are drawn which require more than just 2 points.

However I took that change out just at the last moment to keep the changes compatible with what everyone is used to in the official release. Unfortunately, this caused bugs such as the problem with the line tool that Ash pointed out and the crash that Bobofthedead and other found.

4. As Rick mentioned I did not fill in the email, forum etc strings in the source code. I (perhaps stupidly) just took out the markers so it would build, leaving the strings empty. I think (haven't tried it) that this means it will just crash if you use facilities that send email, go to the forums etc.

5. I am more than happy to provide the source code. (I just didn't provide it as I read somewhere that unsolicited code is not accepted.)

6. This is a patch designed for PDN 3.10 only. I think I did disable the automatic updates code so it will not wipe out the patch unexpectedly.

If you want to use it, it's probably best to install 3.10, then patch it, then copy the whole directory elsewhere. Then uninstall, and re-install the official PDN 3.10 so you have the official version and can get updates.

Link to comment
Share on other sites

If you want to use it, it's probably best to install 3.10, then patch it, then copy the whole directory elsewhere. Then uninstall, and re-install the official PDN 3.10 so you have the official version and can get updates.

I was just think about that :)

The best of both worlds.

The_next_thousand_words_by_0_ASH_0.png

All creations Ash + Paint.NET [ Googlepage | deviantArt | Club PDN | PDN Fan ]

Link to comment
Share on other sites

If you want to use it, it's probably best to install 3.10, then patch it, then copy the whole directory elsewhere. Then uninstall, and re-install the official PDN 3.10 so you have the official version and can get updates.

Why not just copy your existing 3.10 installation directory, then patch it? That way you skip a whole uninstall/reinstall...

xZYt6wl.png

ambigram signature by Kemaru

[i write plugins and stuff]

If you like a post, upvote it!

Link to comment
Share on other sites

If you want to use it, it's probably best to install 3.10, then patch it, then copy the whole directory elsewhere. Then uninstall, and re-install the official PDN 3.10 so you have the official version and can get updates.

Why not just copy your existing 3.10 installation directory, then patch it? That way you skip a whole uninstall/reinstall...

I was just about to edit my post above :)

Thats what I just did lol.... :lol:

The_next_thousand_words_by_0_ASH_0.png

All creations Ash + Paint.NET [ Googlepage | deviantArt | Club PDN | PDN Fan ]

Link to comment
Share on other sites

Guest
This topic is now closed to further replies.
 Share

×
×
  • Create New...