[2 days left] What’s wrong with your cloud strategy? Learn why multicloud solutions matter with Nimble Storage.Register Now

x
?
Solved

GDI+ Graphics Path - How to fill a path with ARGB ?

Posted on 2011-02-11
13
Medium Priority
?
1,956 Views
Last Modified: 2012-05-11
Hi,

I'm using Visual Studio 2008 with GDI+ to develop a simple app.
(Code in VB.NET)

I'm using this simple code to fill a path created with points.

Dim caneta As New Pen(Color.FromArgb(127, 0, 100, 10), 40)
path.FillMode = Drawing2D.FillMode.Winding
e.Graphics.DrawPath(caneta, path)

Open in new window


I want that when the path intersect itself it becomes darker.
In order to do this, I used ARGB but GDI+ consider that the path is a unique object, so the overlap never happens.

Someone have any idea in how to solve this problem ?

I want to create an effect like the attached picture:

overlap Example
0
Comment
Question by:giovaniluigi
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 5
  • 4
  • 2
  • +1
13 Comments
 
LVL 18

Assisted Solution

by:Jose Parrot
Jose Parrot earned 668 total points
ID: 34873256
GDI doesn't care about overlap, this is our human perception. GDI knows to fill areas with some path or color, so we should define such areas and ask GDI to fill them.

The first setp is to fill all the areas, identified as areas 1, 2, 3 and 4 with one color, as in Fig. 1.Fig. 1 - SubareasIf the subareas are filled in the desired colors, we have a problem, due the border color. If we use black borders, the result will be different of the given example. If border color is transparent (by using the alpha channel, the "A" in the "ARGB" format), the result is the one shown in detail in (d) of Fig. 1.

Then, as in Fig. 2, we fill the entire polygon with the desired color to subarea 1.
 Filling the areasIn (a) we see with black borders and in (b) with both border and interior with the same color. We do as in (b). Finally, we draw a new rectangle for the "overlap" area (the subarea 2) with another color and, again, by making both border and interior with the same color, thus allowing a result as in the example you have provided.

Please remember that GDI border is defined as a Pen and the filling color in the interior is a Brush color.

Jose
0
 

Author Comment

by:giovaniluigi
ID: 34875580
Thank you for your sugestion.

I just didn't understood how to implement in my code.

Take a look on MS Paint: (Windows 7)

giovaniluigi-408673.flv

GDI+ doesn't offer a simple way to do this ? If no, there is another library to facilitate this type of 2D drawing on .NET Visual Studio ?
0
 
LVL 18

Expert Comment

by:Jose Parrot
ID: 34915006
Paint does exactly what I have described as unpracticable to implement in GDI+, say, by picking each pixel color value and by computating the new color and by poking suck new color in the pixel. Paint has it implemented in low level (Assembly) programming, with good performance.
By the other hand, GDI is very slow for pixel operations, so we shouldn't adopt this approach in an  application. This is why I have suggested to draw polygons, which are supported by GDI with acceptable performance.

Let me understand your application. Is is an interactive one, say, an user draws in the same way as he uses Paint? Or your application draws areas programmaticatly (no human intervention)? In other words, does your application calculate where to draw or is it determined by an user?

In the first case (interactive application) we must call pixel functions, in the second case (automatic application) we can chose to call pixel or area painting. Anyway, pixel operations (GetPixel, SetPixel) will be V E R Y  S L O W, so you can try tLockBit functions.

My first suggestion is to see at http://www.bobpowell.net/lockingbits.htm if the directions there are applicable to your needs. Probably yes.

Jose
0
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 
LVL 96

Expert Comment

by:Bob Learned
ID: 34921733
Are you looking to define the path, or have you done that already?  I can see a way to simulate, with a series of arcs and rectangles, but that is only a thought experiment for now...
0
 

Author Comment

by:giovaniluigi
ID: 34922993
The path is drawn by coordinates received from a GPS in real time.
It's a kind of track logging.
When the GPS moves, the program draw the path, where you passed by.
Due the GPS coordinates, the image have a huge size.
The picture goes from -500.000.000 to +500.000.000 in x and y axis.

I used polygons to draw the path.
Having a line of points, I can draw polygons following the line, to simulate the Path width.
But with simple polygons the image becomes with poor quality.
When I have a curve for example the deformation appears.
With some math I reduced the deformation but the performance downs.
The quantity of polygons and the math used turns the performance very low for a real time program.
For example I will need to redraw about 10.000 polygons every time I need to rotate the image that will be needed for my application.
Depending of the time that the user active the GPS, the number os polygons can increase to 50.000 or more.

So I need to figure out how to use a unique Path to get a better performance and a smooth result specially in curves.

The only problem is that with Path I can't show to the user the overlapped area.

Take a look on the result using polygons to generate the Path:

 giovaniluigi-410980.flv
0
 
LVL 12

Expert Comment

by:satsumo
ID: 34930427
To clarify the problem, your drawing a line along the path with a wide pen, is that correct?

For this to work you need to divide the path into sections, so that overlapping parts of the path are drawn with different calls to DrawPath.

Some questions that might help solve the problem -

What language are you using?
Are all 10,000 polygons actually visible to the user all the time?
How are you optimising the polygons?
0
 

Author Comment

by:giovaniluigi
ID: 34930664
I'm using VB.NET

The 10.000 polygons are visible most of the time, when user use "zoom in" the number reduces of course.

But the video that I attached was made with my app, drawing some polygons with the algorithm that I created to simulate the path with wide pen.
On the video I drew with mouse, so the count of polygons was low. But in the real application, each second the program add 5 new points, wich means 5 new polygons.

The app will run for 3 hours for example.
Having 5 new polygons each second, we will have 54.000 polygons after tree hours.
All this will be visible using transformation to scale the image to fit monitor.

That is why I need to use Path instead polygons.

To divide the path into sections I will need to define the size of a section.

If I understood your idea, it is something like that:

Sub sections
If this size is too high the overlap effect will not happen.
If the size of each section is too low, the performance will be low as the polygons solution.
0
 
LVL 12

Assisted Solution

by:satsumo
satsumo earned 1332 total points
ID: 34930927
Ok, thats quite a lot of ideas to work on.

The diagram shows the principle but not the implementation.  I would suggest dividing sections where the direction of the road has changed significantly from when the section started.  Perhaps a value of about 90 degrees.  To get the overlap between section 3 and section 6 in the diagram, the path turns through about 300 degrees.  Using this technique, sections 1, 2 and 3 would not be divided at all and the loop in section 1would be divided 3 times.

The data can be reduced as it arrives too.  If the tracked object travels in the same direction for 10 seconds, there will be 50 points, though only two are needed to describe the line it travelled.  This technique is very similar to dividing the data into sections by direction.  Remove any points that aren't significant changes of direction.

Another apparent speed up is data reduction over time.  Assuming the program runs for 3 hours, and gradually zooms out, detail in the line can be reduced as it become smaller on the screen.  Points can be removed which describe a change of direction over a small distance compared to the zoom.

This process is called Level Of Detail (LOD), there are very many techniques for doing LOD.
Level of Detail on Wikipedia
0
 
LVL 12

Expert Comment

by:satsumo
ID: 34931091
Did a diagram to help explain the dividing sections by directions idea.  Hopefully pictures are easier to understand.
expert.gif
0
 

Author Comment

by:giovaniluigi
ID: 34931152
Thank you satsumo

Your idea is very good about dividing when I have significative change of direction.

Another thing to do, is to simplify the data that describes the path.

For example I can have a straight line represented by 100 point when 2 points is enough because it's a straight line!

The question is, there is some kind of Math trick to do a simplification based on the behavior of the data ? I mean, there is something opposite to interpolation ?

In interpolation I have few points and I get a curve based on the behavior of these points.

I want to do the opposite. Having a lot of points, I want to extract the most important points.

The problem that I see here is how to analyse the behavior of data and decide when a point is relevant.
I thought in using derivative calculus but if there is a better way to go I prefer than using derivative.
0
 
LVL 12

Accepted Solution

by:
satsumo earned 1332 total points
ID: 34931222
I was going to suggest giving each point a weight, a combination of the change of direction and the distance to the next point.  So that sharp corners have a big weight and almost straight lines have near zero weight.  Sharp angles on very short lines should have a smaller weight than slight angles on very long lines.

Only draw the lines between points with a particular weight.  As the view zooms out, the weight gets bigger so that less lines are drawn and small details disappear.  Equally, if the view zooms in, it can show more detail but less of the path.
0
 
LVL 12

Expert Comment

by:satsumo
ID: 34931281
No need for calculus, the simple way to get the angle and weight is a little bit of trigonometry.  Lets say we have 3 points a, b and c, each has an x and y coordinate.  Distance from a to b is this -
d.x = b.x - a.x
d.y = b.y - a.y
distance = sqrt (d.x * d.x + d.y * d.y)
nab.x = d.x / distance;
nab.y = d.y / distance;

Open in new window


The last two lines calulate the normal from a to b (so I called it nab).  If the code has two normals, from a to b and from b to c, the sine and cosine of the angle between them is -
sine = (nab.y * nbc.x) + (-nab.x * nbc.y)
cosine =  (nab.x * nbc.x) + (nab.y * nbc.y)

Open in new window

The sine will be zero if a, b and c make a line.  It will be positive or negative if the path bends left or right.  The cosine will be negative if the path bends more than 90 degrees left or right.
0

Featured Post

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Article by: Nadia
Linear search (searching each index in an array one by one) works almost everywhere but it is not optimal in many cases. Let's assume, we have a book which has 42949672960 pages. We also have a table of contents. Now we want to read the content on p…
If you need to start windows update installation remotely or as a scheduled task you will find this very helpful.
I've attached the XLSM Excel spreadsheet I used in the video and also text files containing the macros used below. https://filedb.experts-exchange.com/incoming/2017/03_w12/1151775/Permutations.txt https://filedb.experts-exchange.com/incoming/201…
We’ve all felt that sense of false security before—locking down external access to a database or component and feeling like we’ve done all we need to do to secure company data. But that feeling is fleeting. Attacks these days can happen in many w…

656 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question