-
-
Notifications
You must be signed in to change notification settings - Fork 102
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement option to use Porter-Duffman src operator #193
Comments
Do you have a small example code that reproduces this? |
Yes, here it is. This is the main loop overlaping layers ordered by the area (larger areas first, smaller atop)
This the function constructing lines:
And this is the palette from which I choose the "col" (color) variable:
Please notice the first element in the color array. I do know that I have contours with the values {0.07, 0.1} that should correspond to transparent pixels and I know that some of these contours should be atop as shown in the picture in the first message. However I instead see only contours with the color {220, 240, 255, 255} (that is first below). If I substitute the first element in the color array with {0x00, 0x00, 0x00, 0xff}, I see black spots atop. |
Just a quick idea, the rasterizer gives awkward results for open paths. Are
you sure the paths are closed? You can close a polyline by appending the
starting point at the end.
…On Fri, 9 Dec 2022, 07:59 dkononovGm, ***@***.***> wrote:
Yes, here it is.
This is the main loop overlaping layers ordered by the area (larger areas
first, smaller atop)
for _, rng := range contourPixelPoints {
col := rng.Color
ctx.SetFillColor(col)
ctx.SetStrokeColor(col)
ctx.SetStrokeWidth(0.0)
line := pixelsToLine(rng.Line)
//ctx.Style.FillRule = canvas.EvenOdd
ctx.DrawPath(0, 0, line...)
}
This the function constructing lines:
func pixelsToLine(pixelLine []LinePoint) []*canvas.Path {
var line []*canvas.Path
polyline := &canvas.Polyline{}
for _, l := range pixelLine {
polyline.Add(l.Px, l.Py)
}
line = append(line, polyline.Smoothen())
return line
}
And this is the palette from which I choose the "col" (color) variable:
precipitationPalette := PaletteRangeColor{
Ranges: [][]float64{{0.07, 0.1}, {0.1, 0.2}, {0.2, 0.3}, {0.3, 0.4}, {0.4, 0.5}, {0.5, 0.6}, {0.6, 0.7}, {0.7, 0.8}, {0.8, 0.9}, {0.9, 1}, {1, 2}, {2, 3}, {3, 4}, {4, 5}, {5, 6}, {6, 7}, {7, 9}, {9, 11}, {11, 13}, {13, 15}, {15, 20}, {20, 50}, {50, 70}, {70, 100}, {100, 120}, {120, 1000}}, // 1000 is an arbitrary high number
Colors: []color.RGBA{{0x00, 0x00, 0x00, 0x00}, {220, 240, 255, 255}, {174, 220, 255, 255}, {128, 200, 255, 255}, {110, 193, 255, 255}, {91, 186, 255, 255}, {73, 179, 255, 255}, {55, 171, 255, 255}, {37, 164, 255, 255}, {18, 157, 255, 255}, {0, 150, 255, 255}, {0, 144, 245, 255}, {0, 138, 235, 255}, {0, 132, 226, 255}, {0, 127, 217, 255}, {0, 122, 208, 255}, {0, 100, 255, 255}, {0, 50, 255, 255}, {0, 38, 223, 255}, {0, 13, 160, 255}, {0, 0, 128, 255}, {0, 0, 96, 255}, {0, 0, 64, 255}, {0, 0, 32, 255}, {0, 0, 0, 255}, {0, 0, 0, 0}, {0, 0, 0, 0}},
}
Please notice the first element in the color array. I do know that I have
contours with the values {0.07, 0.1} that should correspond to transparent
pixels and I know that some of these contours should be atop as shown in
the picture in the first message. However I instead see only contours with
the color {220, 240, 255, 255} (that is first below). If I substitute the
first element in the color array with {0x00, 0x00, 0x00, 0xff}, I see black
spots atop.
—
Reply to this email directly, view it on GitHub
<#193 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/ABKOGHR6XVY5JMFK224SHC3WMMGKLANCNFSM6AAAAAASWVCYO4>
.
You are receiving this because you commented.Message ID:
***@***.***>
|
I have looked at your "draw" function and have a question:
In the fist condition you exit from the function if !c.Style.HasFill(). As I understand, if the alpha = 0, HasFill = false and this contour won't be drawn, i.e. pixel values inside this contour won't be set to zero, but will retain the previous values (the values of the previous layer). Am I right? May it be the reason of the issue? |
Drawing a shape is always blended with previously drawn shapes below. That is, drawing transparent pixels is like doing nothing, which is why Would you be able to send me a small piece of working code that reproduces the issue? Then I can take a look at it. |
I unfortunately cannot send a small piece of the code, since it's distributed over a number of files and functions. But I can try explaining what I want to have as a result with a simple illustration: I want to draw something like in the picture with the non-filled annulus in the center. Is it possible with your package? |
I seem to have figured it out how to illustrate my question with a small piece of code. Let us imagine that I have three circular contours as above. I draw them in series:
I of course do something like this within a loop. But the main idea is like above. So the question is if this way of drawing contours one on one is appropriate for having the picture above within the paradigm of your package, or I need to invent a different method. |
In general, the way drawing happens in most libraries (imitating what happens when you literally paint something) is that you can't remove painted pixels below, you can only over-paint with a new color. The rasterizer actually allows the Porter-Duffman operators One way to fix this in your case though would be to paint a subpath in the contrary direction (clockwise/counter clockwise) within the outer path. This only works when you're sure that the higher layer path is contained in the lower layer path. E.g.: line0 := formCircularContour(...)
line1 := formCircularContour(...)
line2 := formCircularContour(...)
// bottom dark blue path
ctx.SetFillColor(color.Blue)
ctx.SetStrokeColor(color.Blue)
ctx.SetStrokeWidth(0.0)
ctx.DrawPath(0, 0, line0.Append(line1.Reverse()))
//middle cyan path (or light blue, I just do not remember how it is designated in the color list)
ctx.SetFillColor(color.Cyan)
ctx.SetStrokeColor(color.Cyan)
ctx.SetStrokeWidth(0.0)
ctx.DrawPath(0, 0, line1.Append(line2.Reverse()))
// NOT NEEDED
//upper path whose "color" I do not know. I want the pixels inside this path to be set default values {0,0,0,0} if it is possible
//ctx.SetFillColor(?)
//ctx.SetStrokeColor(?)
//ctx.SetStrokeWidth(0.0)
//ctx.DrawPath(0, 0, line2) I'm working on path boolean operations as we speak, which would allow |
Oh, I see. Am I right that by adding a subpath you in fact form a "complex path" that is, in fact, a ring? The problem is that I have both ascending and descending embedded contours. Will the idea you proposed for now work in the ascending order of layer values? Thanks for your help. I'll try to implement this way for now and wait for updates
|
Oh. And I have one more question. Do this operation |
Yes, it subtracts the inner path from the outer path. Appending literally appends the path and does no effort to join both paths, for that we have I'm not sure what the problem is with ascending/descending. From what I understand, you always need to draw from the bottom up, and from what I see is that each next layer is contained within the previous layer, right? That is, each layer is getting smaller and doesn't intersect with the layers below. |
Oh. Almost, but my task is a little more complicated. I can easily have several smaller area contours within one big area contour and those smaller may have both larger and smaller values (see the initial picture in my first message of this issue). Well. I'll try to refactor my code to account for contour embedding, since now I only arrange contours by areas.
|
Well, it depends on whichever value should be on top. I was assuming that darker blue should always be on top (higher value), but if this is not always the case the method above applies equally well. Just with the consideration that higher layers are contained within the lower ones (whether the value is higher/lower i.e. color more white or more blue doesn't matter). I hope that helps. Otherwise you could sort by value first? |
@dkononovGm Is this still an issue? |
Yes. I still hope that you'll be able to implement that P-D operator you mentioned. :) |
Hi! Probably this isn't issue, but browsing through your code I coudn't find any solution. The point is that I'm trying to draw a "map" where contours (or layers) have both humps and holes (see figs attached). And in some holes the bottom layer is zero (pixels must not be filled). But when I subsequently overlay the contours and add the zero contour to the top, I see not an empty hole but the last underlying contour with minimal, but non-zero value. Could you please give some advice, how I could solve this problem?
Thanks in advance,
Dmitry
The text was updated successfully, but these errors were encountered: