Jump to content
How to Install Plugins ×

Drawing Triangles, Pentagons, Stars, etc. Plugin: 2007-02-09


BoltBait

Recommended Posts

Then you will see my secrets... But it's ok I'm a "sharer" !

The trick is to do the stuff in two pass.

1st loop I use a binary table as large as the image. It's where I "plot" the spots.

2nd loop I read as normaly the selection and read the binary table to decide what to draw on the 'dst'. I learnt it's better to set 'dst' line by line.

So the 'precalculation' in the table AND normal 'plotting' in the dst make the rendering going faster!

here is the source of the newer version

I leave the old one if you want to compare.

I'm still missing a good solution for anti-aliasing :(

Link to comment
Share on other sites

Hi, I am new here. I am also new to the .net programming, but I can read it.

What I want to suggest are: for staris parameter, it need only start from 1 to (int)((double)n/2 - 0.5), because staris = k and staris = n-k is same thing.

For the computation efficiency, I think using vector and rotation is a faster way than call cos and sin all the times. For example, center point o, first point A, then vector oA is the Radius*(cos(offset), sin(offset)) where offset is the rotation I think. Calculate the angle AoB by anglestep = 2*pi/n, then create the 2D rotation matrix. The oB can be calculated by applying rotation on oA, which only need 4 double multiplications and 4 double additions (2 for add the o cord). Cos and sin will no longer be called every loop.

Probably for today's computer there is no problem, however, I experience a significant slowing down when in one of my openGL projects transplanted to a pentium II computer. And I think this is not harmful.

Link to comment
Share on other sites

What a post for a first one!

1. using float instead double is already a speed gain.

2. I'm not sure that 4 double multiplications and 4 double addition are computed faster than float cos...

3. If I could imagine vector and rotation on paper, I don't see how to write it in the program. Could you do it?

4. BTW I think we could improove this but anyhow is .Net running on your pentium II ? Which operating system ?

Link to comment
Share on other sites

Hi, Madjik:

I must agree that the idea lies in the polygon plugin is great. It might need no change if there is no more PII. My computer is not not PII, it runs opengl with no problem, but paint.net seems starting slow on it. Now because nearly every program is written in a way that requires more system resources, I really need a new computer for the tendency.

To use the vector operation is just a suggestion. In most of 3D calculation, including optical ray tracing, vector operation is widely applied for the calculation efficiency.

For your listed answers.

1. using float instead double is already a speed gain.

2. I'm not sure that 4 double multiplications and 4 double addition are computed faster than float cos...

3. If I could imagine vector and rotation on paper, I don't see how to write it in the program. Could you do it?

4. BTW I think we could improove this but anyhow is .Net running on your pentium II ? Which operating system ?

1. cos and sin might return double, but vector operation can be limited to float.

2. As I remember (it was long ago),

cos x = 1 - x^2/2 + x^4/4! - x^6/6! + .......

sin x = x - x^3/3! + x^5/5! - .......

this might be how they are calculated, the math functions loop until the precision is reached. However, this is just my guess from the old knowledge and mathematics, things might change

3. Let me see if I can draw something and put it online, but it might easier to find a website or a book on the vectors and matrix.

In optical tracing, refraction and reflection are calculated by vector operation, not the Trigonometric function. In 3D graphics, rotation matrix is a widely used tech to avoid intensive calculation by cos and sin.

a 2D rotation matrix A is

[cos(a) sin(a)]

[-sin(a) cos(a)]

a is the angle couterclockwise, in rad

a vector means a directional line from one point (x,y) to another point (X,Y)

note that it is same for the line from (0,0) to (X-x, Y-y), this means vector can be movable

Rotation is implemented by matrix operation: *A

for now I can only write a code for the operation in C to show the algorithm, it is not compiled

render(x0, y0, n, k, R, offset)

// x0, y0 : center cords

// n number of vertex

// k staris

// offset rotation offset

// R raduis

{

double a = 2*pi/n*k;

float cosa = cos(a), sina = sin(a);

float cosb = cos(offset), sinb = sin(offset);

// now we calculate a side without offset.

// imagine without offset, the first point is (x0+R, y0)

// next point is (x0+R*cosa, y0+R*sina)

// the coord difference gives the vector

float vx1 = R*(cosa-1), vy1 = R*sina;

// now rotate it by offset suppose it is in rad

float vx2 = vx1*cosb - vy1*sinb, vy2 = vx1*sinb + vy1*cosb;

// this stands for all the parallel lines with same length as the first side

// we need to determine its starting point

float x1 = x0 + R*cosb, y1 = y0 + R*cosb;

// now we loop

for (int i=1; i

{

// the next point can be calculated

// two float/double addition here

float x2 = x1 + vx2, y2 = y1 + vx2;

// now draw the line

drawline((int)x1, (int)y1, (int)x2,(int)y2)

// update the starting point, rotate the side vector

x1 = x2; y1 = y2;

vx1 = vx2; vy1 =vy2;

// two addition here, four multiplication here

vx2 = vx1*cosb - vy1*sinb; vy2 = vx1*sinb + vy1*cosb;

}

}

4. My computer is PenIV. When I was in school and using opengl, the computer is PenII. The code transplanted from

my computer to the school computer gets slow, one reason was the intensive cos and sin call.

I'd like to write in C#, but as I said, I am new to it. I have the runtime v2 on this machine, but coding and debug will be slow.

If you can help me on it (how to test it and maybe correct some syntax error), I will be glad to work with you. Or you can search the internet for vector and matrix operation or just borrow a book. It is quite easy.

Other than use the vector for sides, we also use the vector starting from center and pointing to vertex

render(x0, y0, n, k, R, offset)

// x0, y0 : center cords

// n number of vertex

// k staris

// offset rotation offset

// R raduis

{

double a = 2*pi/n*k;

float cosa = cos(a), sina = sin(a);

float cosb = cos(offset), sinb = sin(offset);

// now we calculate the vector from center to first vertex

float vx1 = R*cosb, vy1 = R*sinb;

// the vertex is

float x1 = x0 + vx1, y1 = y0 + vy1;

float vx2, vy2, x2, y2;

// now we loop

for (int i=1; i

{

// rotate the vector -- two add, four multiplication here

vx2 = vx1*cosa - vy1*sina;

vy2 = vx1*sina + vy1*cosa;

//next vertex two more addition here

x2 = x0 + vx2, y2 = y0 + vx2;

// now draw the line

drawline((int)x1, (int)y1, (int)x2,(int)y2)

// update the starting point, rotate the side vector

x1 = x2; y1 = y2;

vx1 = vx2; vy1 =vy2;

}

}

I modified madjik's code, don't know how to upload here or how to test it. Need help!

Link to comment
Share on other sites

Now here is a link on the rotation matrix

http://mathworld.wolfram.com/RotationMatrix.html

I am glad I have nothing wrongly explained. They express vector as a column vector and use right multiplication (matrix on left), I use row vector and left multiply the rotation matrix. Therefore the -sinx location is different.

The idea lies in the fact that the new side can be acquired by rotating the last side.

Moreover, it might be reasonable to draw the last side by connecting back to the first point. Otherwise, we might have an open at the end.

One more idea to create the hollow star: use two circle with Radius R1 and Radius R2, n vertexes, offset by alpha. This can create a holly star.

void render(x0,y0,R1,R2,alpha,beta,n)

{

// alpha, internal offset angle

// beta, extenal offet angle

// n, vertexes

float aa = 2*pi/n;

float cosaa2 = cos(aa/2), sinaa = sin(aa/2);

float cosaaa = 1 - 2*sinaa2*sinaa2, sinaaa = 2*sinaa2*cosaa2;

float cosa = cos(alpha), sina2 = sin(alpha); //alpha in rad

float cosb = cos(beta), sinb = sin(beta);

// this time we calculate the vertexes by vector from center to the vertex

float vx1 = R1, vy1 = 0;

float vx2 = R2*cosa2, vy2 = R2*sina2; // note that alpha is applied

// apply the offset beta on both v1 and v2

float vxt = vx2, vyt = vy2;

vx2 = vxt*cosb - vyt*sinb;

vy2 = vxt*sinb + vyt*cosb;

vxt = vx1; vyt = vy1;

vx1 = vxt*cosb - vyt*sinb;

vy1 = vxt*sinb + vyt*cosb;

// temperory varible for illustration

float x1, y1, x2, y2;

x1 = x0 + vx1; y1 = x0 + vy1;

x2 = x0 + vx2; y2 = y0 + vy2;

// now we loop

for (i=1; i

{

drawline((int)x1, (int)y1, (int)x2, (int)y2);

// rotate vector v1

vxt = vx1; vyt = vy1;

vx1 = vxt*cosb - vyt*sinb;

vy1 = vxt*sinb + vyt*cosb;

// draw another line

x1 = x0 + vx1; y1 = x0 +vy1;

drawline(x2,y2,x1,y1)

// rotate vector v2

vxt = vx2; vyt = vy2;

vx2 = vxt*cosb - vyt*sinb;

vy2 = vxt*sinb + vyt*cosb;

x2 = x0 + vx2; y2 = x0 +vy2;

}

}

BTW, the idea to use the variable radius is good, the result is anstonishing. That might be something that vector can't be helpful.

Link to comment
Share on other sites

I quickly encounter errors with both plugins :(

for the polygon, I try to produce a pentagon and then rotate a small amount and it crashes every time.

Can't reproduce that error... Could you tell me the picture size you're working on ?

imo, antialiasing is essential.

also, the polygones aren't symmetrical all the time, the lines look as though they don't quite match up; the odd extra pixel where there shouldn't be any. perhaps this is due to rounding.

I agree for antialiasing, but I've not viable solution yet for that... :oops:

Rounding could create some "extra" pixels. I'll have a look at that.

Link to comment
Share on other sites

Hi, Madjik:

I modified madjik's code, don't know how to upload here or how to test it. Need help!

You could try to PM it to me...

EDIT: BTW for a pentagone or a 5 spines star, We calculate only 5 times sin/cos matter. The biggest part of computation is for drawing the straight lines. So I'm not sure we'll gain something in the end.

Link to comment
Share on other sites

Yes, only if we drawing a polygon with over 1000 vertex, the difference might be seen, but the polygon will became a circle anyway:)

OK, I figured out my Javascript is disabled for this site, but I still can't find out how to attach a file. Do I need a webspace?

Following code is wat you posted before. I am not sure it is latest but I think the looping part is a little overlapped with each other, as I noted down in the code. I am not quite sure what you are trying to do in the loop from left to right, from top to bottom.

using Polygones.Properties;
.....
using System.Windows.Forms;

// the revised version on madjik's polygon, by Ghost_Archer.
// replace the cos and sin with vector operation, no other changes
namespace Polygones
   {
...
       {
...
       public override void Render(...)
           {
...

//  I am not sure what the startIndex and length refers to, is that the counter for selections and masks?
////////////////////////////////////////////////////////////////////////////
//  yet it seems that there are too many loops here.
//  I guess there will be lots of overlapping pixels inside
//  i.e., some pixel will be treated more than once if there are overlap
///////////////////////////////////////////////////////////////////////////

           for (int i = startIndex; i < startIndex + length; ++i)
// all these are inside the loop
// including the draw polygon part.
               {
               Rectangle rect = rois[i];
               // Because I have to reset the destination every time 
               // this is reeeeeaaaaallllly slow 
               for (int y = rect.Top; y < rect.Bottom; y++)
                   {
                   for (int x = rect.Left; x < rect.Right; x++)
                       {
                       if (selectionRegion.IsVisible(x, y))
                           {
                           dstArgs.Surface[x, y] = srcArgs.Surface[x, y];
                           }
                       }
                   }
// including the drawline calls, polygon is drawn several times
........
           }

       public void DrawLine(int x1, int y1, int x2, int y2, Surface dst, ColorBgra LineColor, PdnRegion selectionRegion)
           {
...
           }
       public override EffectConfigDialog CreateConfigDialog()
           {
...
           }

       public Polygones()
           : base(Strings.Polygones_Name, Resources.Polygones, Keys.None, null, EffectDirectives.None, true)
           {
...
           }
       }
   }

Link to comment
Share on other sites

I quickly encounter errors with both plugins :(

for the polygon, I try to produce a pentagon and then rotate a small amount and it crashes every time.

Can't reproduce that error... Could you tell me the picture size you're working on ?

I noticed that your internal buffer is not clipping, so I was able to reproduce the error on the first try...

Here is a screenshot of the error:

polyerror.gif

Here is the crash log:

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

Application version: Paint.NET v3.0 (Final Release build 3.0.2580.31)
Time of crash: 1/30/2007 9:38:47 AM
Application uptime: 00:00:59.4977152
OS Version: 5.1.2600.131072 Service Pack 2 Workstation x86
.NET Framework version: 2.0.50727.42 x86
Processor: 2x Intel(R) Pentium(R) 4 CPU 3.20GHz
Physical memory: 1022 MB
Tablet PC: no
Locale: pdnr.c: en-US, hklm: en-US, hkcu: en-US, cc: en-US, cuic: en-US

Exception details:
PaintDotNet.WorkerThreadException: Worker thread threw an exception ---> System.IndexOutOfRangeException: Index was outside the bounds of the array.
  at Polygones.Polygones.Render(ThreeAmountsConfigToken token, Surface dst, Surface src, Rectangle rect)
  at Polygones.Polygones.Render(EffectConfigToken parameters, RenderArgs dstArgs, RenderArgs srcArgs, Rectangle[] rois, Int32 startIndex, Int32 length)
  at PaintDotNet.Effects.BackgroundEffectRenderer.RendererContext.RenderImpl()
  --- End of inner exception stack trace ---
  at PaintDotNet.Effects.BackgroundEffectRenderer.Join()
  at PaintDotNet.Effects.BackgroundEffectRenderer.Start()
  at PaintDotNet.Menus.EffectMenuBase.EffectConfigTokenChangedHandler(Object sender, EventArgs e)
  at PaintDotNet.Effects.EffectConfigDialog.OnEffectTokenChanged()
  at PaintDotNet.Effects.TwoAmountsConfigDialogBase.amount2Slider_ValueChanged(Object sender, EventArgs e)
  at System.Windows.Forms.TrackBar.OnValueChanged(EventArgs e)
  at System.Windows.Forms.TrackBar.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)
------------------------------------------------------------------------------

BTW for a pentagone or a 5 spines star, We calculate only 5 times sin/cos matter. The biggest part of computation is for drawing the straight lines. So I'm not sure we'll gain something in the end.

I totally agree. Don't waste time optimizing code that hardly ever runs.

Link to comment
Share on other sites

I noticed that your internal buffer is not clipping, so I was able to reproduce the error on the first try...

Ok I've got the error.

I've added 1 to the width/high of what you call the 'buffer' and it's ok now!

new.jpg

here is the Polygones.DLL

here is the Polygones sources

I've delete older version!

Link to comment
Share on other sites

I think my thread is getting jacked... Oh well. Time to "split" the thread into two parts. :)

On to important business!

I have updated the first post with a link to the Draw Shapes/Stars Plugin UI that I wrote.

And the speed of line drawing has been GREATLY increased!

Enjoy. :cool:

Source code coming soon... really...

Link to comment
Share on other sites

corners.png

Fixable?

Absolutely fixable.

Actually, when the user is drawing stars, I change the line ends to be more pointed. This looks really good for stars with lots of points, but apparantly, not so good for less points. :D

I just had to delete a couple of lines of code, recompile, upload...

Try updating your dll now.

Link to comment
Share on other sites

Really good job with this new version. I'ld like to have the source to learn from your technic. Thanks.

Since you asked, in the first post, I have added a link to the VS2005 souce code.

Please let me know if there are not enough files included to build the project.

Link to comment
Share on other sites

Absolutely fixable.

Actually, when the user is drawing stars, I change the line ends to be more pointed. This looks really good for stars with lots of points, but apparantly, not so good for less points. :D

I just had to delete a couple of lines of code, recompile, upload...

Try updating your dll now.

I liked it the other way better! I got some cool looking gear-like shapes.

Could you have a check box on the GUI or something so you can have both options?

Or, can you post the old dll as well? Then I will just run both depending on my need...

 

Take responsibility for your own intelligence. 😉 -Rick Brewster

Link to comment
Share on other sites

Please let me know if there are not enough files included to build the project.

Everything is fine : I've opened the project with VS C# (express version). I press F6, "built success"...

This source shows me how much I need to learn about C#. I have some technics but if I don't know the words...

Thanks a lot!

Link to comment
Share on other sites

Madjik, I think you can bookmark this:

http://www.siteduzero.com/tuto-3-1946-0 ... ertis.html

Don't be afraid by the header which said that you had to know C/C++, as far as I see, it's very well explained.

(worst english sentence ever written)

edit:typo.

No. Way. I've just seen Bob. And... *poof!*—just like that—he disappears into the mist again. ~Helio

Link to comment
Share on other sites

I liked it the other way better! I got some cool looking gear-like shapes.

Could you have a check box on the GUI or something so you can have both options?

Or, can you post the old dll as well? Then I will just run both depending on my need...

Well, I guess you can't please everybody. :(

Link to comment
Share on other sites

Its ok. I had the old verison on my laptop. I will just load both...

here is a radial blade I made with the old dll.

blade.png

 

Take responsibility for your own intelligence. 😉 -Rick Brewster

Link to comment
Share on other sites

Fixable?
Absolutely fixable.

Much appreciated.

BK_BloodSaw_sig.png

- DO NOT contact me asking for the .pdn of my avatar or the PDN logo. Thank you. Have a nice day.

Link to comment
Share on other sites

Please let me know if there are not enough files included to build the project.

Everything is fine : I've opened the project with VS C# (express version). I press F6, "built success"...

This source shows me how much I need to learn about C#. I have some technics but if I don't know the words...

Thanks a lot!

MadJik, as you look through the source code, read this thread: http://paintdotnet.12.forumer.com/viewt ... 4136#24136

Madjik, I think you can bookmark this:

http://www.siteduzero.com/tuto-3-1946-0 ... ertis.html

Don't be afraid by the header which said that you had to know C/C++, as far as I see, it's very well explained.

(worst english sentence ever written)

edit:typo.

Bob, I checked out that site, but I really couldn't get anything out of it. :?

Perhaps it is because I don't speak French? :idea:

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...