Curved Path2D becomes straight when increasing stroke size - path

I have this strange problem with Java2D. I have a Path2D.Double that I want to draw, but depending on the stroke size, all segments are drawn correctly (curved) but when the stroke size is greater or equal than 0.00005d the segments are drawn straight. As you can see, the only parameter I'm changing is the stroke size. What am I doing wrong?
BasicStroke basicStroke1 = new BasicStroke(.00004f, CAP_ROUND, JOIN_ROUND);
g2draw.setStroke(basicStroke1);
g2draw.draw(path);
BasicStroke basicStroke2 = new BasicStroke(.00006f, CAP_ROUND, JOIN_ROUND);
g2draw.setStroke(basicStroke2);
g2draw.draw(path);
And here a picture with the result of this code:

Turns out the error seems to be rounding errors when transforming user coordinates to screen coordinates, when the scale difference is big (or not so big...). It's an odd behaviour of Java2D. Switched to JavaFX and the problem disappeared.

Related

How to prevent values of x axis points from overlapping each other when Graph has more than one series.?

Couldn't show the value of point on the red line which is covered black circle.
Probably, near points are squishing each other. Is there a solution for fixing this ? Showing it in tooltip not a solution for my task.

Wrong result using function fillPoly in opencv for very large images

I have a hard time solving the issue with mask creation.My image is large,
40959px X 24575px and im trying to create a mask for it.
I noticed that i dont have a problem for images up to certain size(I tested about 33000px X 22000px), but for dimensions larger than that i get an error inside my mask(Error is that it gets black in the middle of the polygon and white region extends itself to the left edge.Result should be without black area inside polygon and no white area extending to the left edge of image).
So my code looks like this:
pixel_points_list = latLonToPixel(dataSet, lat_lon_pairs)
print pixel_points_list
# This is the list im getting
#[[213, 6259], [22301, 23608], [25363, 22223], [27477, 23608], [35058, 18433], [12168, 282], [213, 6259]]
image = cv2.imread(in_tmpImgFilePath,-1)
print image.shape
#Value of image.shape: (24575, 40959, 4)
mask = np.zeros(image.shape, dtype=np.uint8)
roi_corners = np.array([pixel_points_list], dtype=np.int32)
print roi_corners
#contents of roi_corners_array:
"""
[[[ 213 6259]
[22301 23608]
[25363 22223]
[27477 23608]
[35058 18433]
[12168 282]
[ 213 6259]]]
"""
channel_count = image.shape[2]
ignore_mask_color = (255,)*channel_count
cv2.fillPoly(mask, roi_corners, ignore_mask_color)
cv2.imwrite("mask.tif",mask)
And this is the mask im getting with those coordinates(minified mask):
You see that in the middle of the mask the mask is mirrored.I took those points from pixel_points_list and drawn them on coordinate system and im getting valid polygon, but when using fillPoly im getting wrong results.
Here is even simpler example where i have only 4(5) points:
roi_corners = array([[ 213 6259]
[22301 23608]
[35058 18433]
[12168 282]
[ 213 6259]])
And i get
Does anyone have a clue why does this happen?
Thanks!
The issue is in the function CollectPolyEdges, called by fillPoly (and drawContours, fillConvexPoly, etc...).
Internally, it's assumed that the point coordinates (of integer type int32) have meaningful values only in the 16 lowest bits. In practice, you can draw correctly only if your points have coordinates up to 32768 (which is exactly the maximum x coordinate you can draw in your image.)
This can't be considered as a bug, since your images are extremely large.
As a workaround, you can try to scale your mask and your points by a given factor, fill the poly on the smaller mask, and then re-scale the mask back to original size
As #DanMaĆĄek pointed out in the comments, this is in fact a bug, not fixed, yet.
In the bug discussion, there is another workaround mentioned. It consists on drawing using multiple ROIs with size less than 32768, correcting coordinates for each ROI using the offset parameter in fillPoly.

Direct2D Border Around Text

For better visual appearance want to draw a black border around my text.
Currently i am drawing the same text 5 times.
If i want to draw the text on x = 5, y = 10 i would draw the text one time on the actual position.
Then i would draw the same text in black color with slightly other positions.
x = 4, y = 10
x = 5, y = 9
...
I can only imagine that this is bad performance wise. Or is this the correct way?
I never did it the correct way myself, but it seems here they did it: http://www.codeproject.com/Articles/376597/Outline-Text-With-DirectWrite
I do that too. But I suddenly realise there might be a better way (have not tried it yet): first draw in black with a slightly bigger size, and draw again in white with preferred size. Worth a try? Let me know how that goes.

Indesign Bug? Choosing Fancy Corners Reverses Function of Align Stroke Inside/Outside

I think that this might be a bug in InDesign but I thought that it might be handy to know.
Here's how to recreate: Create a rectangle 200px x 200px, with a 4pt stroke. Set Align stroke to INSIDE. Set the top left xy pos of the rectangle to 100px,100px so that you can easily see changes, and leave the Reference Point in the top left. Now when you change stroke widths, everything is fine, and change corner types, everything is fine, EXCEPT the Fancy Corners. So if you choose Fancy Corners, the x/y becomes 96,96 and total width/height changes to 208 x 208 which is incorrect. Now change the Align Stroke to "OUTSIDE", and the x/y changes back to 100,100 and the rectangle size changes back to 200 x 200. Completely backwards, but just for the Fancy Corners.
Please comment if this is an expected response.

Non-scaling / absolute gradient for scatter plots in CorePlot?

I've added a gradient to my scatter plot in the usual manner:
CPTFill areaGradientFill = [CPTFill fillWithGradient:areaGradient1];
boundLinePlot.areaFill = areaGradientFill;
boundLinePlot.areaBaseValue = 0;
Setting the minimum for the gradient is easy to do with the areaBaseValue property. However, the gradient will always stretch such that the entire range of color defined by areaGradient1 appears below the line plot.
What I'd like to do is set an absolute y-axis range (e.g., 0 to 100) and have the gradient always be set to that range. So if my line is at y=50, only the bottom 50% of the gradient would be rendered below the line. I thought setting boundLinePlot.areaBaseValue2 = 100; would do this, but it doesn't have any effect.
Does CorePlot support this? If not, what's the 'right' way to go about implementing it?
(This is my first question so apologies if I'm not clear. Be gentle. :) )
While there's no direct way to make this happen you could use a trick. Make your horizontal global range wider than what you would show normally and do not make the graph horizontally scrollable. Add a value to the graph in the hidden area that is always your maximum value. This will be filled with the full gradient. Other parts however will only get a partial gradient, depending on their height.
I found this trick by accident while looking at one of my graphs. Look:
The overview at the top shows where the big graph is currently (the green limit band). Now compare this with another part:
You can clearly see that the tip of the large value has a different gradient value as the tip of the smaller one.
You can use a "background limit band" to draw a fill at a certain size behind the plots, but that won't be clipped to the plot line.

Resources