Drawing annotation shapes without graph scaling - jfreechart

I'm creating graphs using JFreeChart:
The problem should be fairly clear. My circles which I'm drawing on the graph are showing up as ovals, since my graph is being scaled down to fit within my dimensions.
Here's how I'm drawing the circle annotations:
chart.getXYPlot().addAnnotation(
new XYShapeAnnotation(
new Ellipse2D.Float(pointX - 15, pointY - 15, 30, 30),
new BasicStroke(0.5), Color.BLACK, Color.GREEN
)
);
How can I draw an annotation without it being scaled down? Is there a way to draw on top of the graph, translating global/real X/Y points into local/scaled X/Y points?

As an alternative, try one of the scale-invariant annotations such as XYImageAnnotation or XYPointerAnnotation. For example,
chart.getXYPlot().addAnnotation(
new XYPointerAnnotation("Bam!", pointX, pointY, 0));

I suggest using a second series with only one single value in it. For this second series you need to enable the drawing of shapes using the setSeriesShapesVisible() method of the plot renderer of the chart. All you need to do is adding one value to this second series in the point you want the shape to appear.
You can use squares, circles, rounded rectangle and some more. In fact any java.awt.Shape object is valid.

Related

MeshGeometry3D mesh to a Solid Surface or 3D Model? Using WPF and Helix toolkit

I am using WPF and Helix toolkit to generate a Mesh.
What I do in my code:
First of all, I have a file that contains different profiles of a real object and the data are represented as X,Y,Z coordinates. So I start reading the data from the file:
MeshGeometry3D mesh;
for-loop
{
--- File read function which returns X,Y,Z values ---
// for each point add it to the mesh
mesh.Positions.Add(new Point3D(temp_point.dX, temp_point.dY, temp_point.Z));
mesh.TriangleIndices.Add(indices++); // indices is just a counter from 0 to number of total points
}
modelGroup.Children.Add(new GeometryModel3D { Geometry = mesh, Material = material });
Model = modelGroup;
OnPropertyChanged(nameof(Model));
Then I get the points coordinates and add them to the mesh.
After the execution the result is the following:
Issue:
If I start rotating the Model, the mesh sometimes is barely visible, and I know that is due to the triangles and the angle view.
Is there anyway to transform this mesh to a 3D model? or something that is more solid?
Can I use mesh.Positions or Mesh.TriangleIndices somehow to make the model solid?
Thanks in advance.
You need to generate triangle indices based on your data, so the mesh can be rendered properly. Currently you use vertex index as indices, which is not correct.
Have a look at the MeshBuilder class. It has several methods yielding a valid MeshGeometry3D from 2-dimensional point arrays, without having to worry about triangle indexes.
The SurfacePlot example is a nice starting point for that,
https://helix-toolkit.github.io/demos/wpf/surfaceplot

Draw curves to make arrows in the Codename One GlassPane

In a CodenameOne App, I need to draw curved arrows in the GlassPane. The use of the GlassPane is not mandatory, however I've already used some layers in the ContentPane and some layers in the LayeredPane, so I suppose that the GlassPane is the best option to be sure that the arrows are "over" the app.
The arrows should be like the following ones:
I suppose that I can create an algorithm that decides the absolute X and Y coordinates of the "Start" and "End" points, more other few points (P0, P1, P2, etc.), that describes the curves. For example:
My problem is that I don't know how to do it. Usually I don't need low-level drawing in a Codename One app like in this case. Could you please show me a correct and complete code to do this drawing (assuming to know the coordinates of Start, End, P0, P1, etc.)? Thank you.
This is a bit hard to do by hand. I would suggest using SVG to draw an arrow like this by using a tool such as Sketch or a similar vector graphics tool. Then using flamingo to convert it to an image: https://www.codenameone.com/blog/flamingo-svg-transcoder.html
Alternatively you can handcode it with a GeneralPath e.g.:
GeneralPath gp = new GeneralPath();
// move to start of path
gp.move(x, y);
// draw the curve of the arrow, we use a control point around which
// the curve is drawn and curve to the destination of the line
gp.curveTo(contolX, controlY, destX, destY);
// Stroke defines how the shape is drawn it accepts the line width
// cap style, join style and miter limit
Stroke st = new Stroke(2, Stroke.CAP_SQUARE, Stroke.JOIN_MITER, 1);
// red
graphics.setColor(0xff00000);
// now we can draw the shape
graphics.drawShape(gp, st);

OpenGL total beginner and 2D animation project?

I have installed GLUT and Visual Studio 2010 and found some tutorials on OpenGL basics (www.opengl-tutorial.org) and 2D graphics programming. I have advanced knowledge in C but no expirience with graphics programming...
For project (astronomy - time scales) , i must create one object in center of window and make other 5 objects (circles,dots...) to rotate around centered object with respect to some equations (i can implement them and solve). Equations is for calculating coordinates of that 5 objects and all of equations have parameter t (as time). For creating animation i will vary parameter t from 0 to 2pi with some step and get coordinates in different moments. If task was to print new coordinates of objects it would be easy to me but problem is how to make animation of graphics. Can i use some functions of OpenGL for rotation/translation ? How to make an object to move to desired location with coordinates determined by equation? Or i can redraw object in new coordinates every millisecond? First thing i thought was to draw all objects, calculate new coordinates, clear screen and draw all objects in new coordinates and repeat that infinitely..(it would be primitive but will work?)
Here is screen shot of that objects - http://i.snag.gy/ht7tG.jpg . My question is how to make animation by calculating new coordinates of objects each step and moving them to new location. Can i do that with basics in OpenGL and good knowledge of C and geometry? Any ideas from what to start? Thanks
Or i can redraw object in new coordinates every millisecond? First
thing i thought was to draw all objects, calculate new coordinates,
clear screen and draw all objects in new coordinates and repeat that
infinitely..
This is indeed the way to go. I would further suggest that you don't bother with shaders and vertex buffers as is the OpenGL 3/4 way. What would be easiest is called "immediate mode", deprecated by OpenGL 3/4 but available in 1/2/3. It's easy:
glPushMatrix(); //save modelview matrix
glTranslatef(obj->x, obj->y, obj->z); //move origin to object center
glBegin(GL_TRIANGLES); //start drawing triangles
glColor3f(1.0f, 0.0f, 0.0f); //a nice red one
glVertex3f(0.0, +0.6f, 0.0f);
glVertex3f(-0.4f, 0.0f, 0.0f);
glVertex3f(+0.4f, 0.0f, 0.0f); //almost equilateral
glEnd();
glPopMatrix(); //restore modelview matrix/origin
Do look into helper libraries glu (useful for setting up the camera / the projection matrix) and glut (should make it very easy to set up a window and basic controls and drawing).
It would probably take you longer to set it up (display a rotating triangle) than to figure out how to use it. In fact, here's some code to help you get started. Your first challenge could be to set up a 2D orthogonal projection matrix that projects along the Z-axis, so you can use the 2D functions (glVertex2).
First thing i thought was to draw all objects, calculate new coordinates, clear screen and draw all objects in new coordinates and repeat that infinitely..(it would be primitive but will work?)
That's exactly how it works. With GLUT, you set a display function that gets called when GLUT thinks it's time to draw a new frame. In this function, clear the screen, draw the objects and flush it to the screen. Then just instruct GLUT to draw another frame, and you're animating!
Might want to keep track of the time inbetween frames so you can animate things smoothly, but I'm sure you can figure that part out.
OpenGL is really just a drawing library. It doesn't do animation, that's up to you to implement. Clear/draw/flush is the commonly used approach for it though.
Note: with 'flush' I mean glFlush(), although GLUT in multi-buffer mode requires glutSwapBuffers()
The red book explains the proper way to draw models that can first be translated, rotated, scaled and so on: http://www.glprogramming.com/red/chapter03.html
Basically, you load the identity, perform transforms/rotations/scales (which one you want first matters - again the book explains it), draw the model as though it was at the origin at normal scale and it'll be placed in its new position. Then you can load identity and proceed with the next one. Every frame of an animation, you glClear() and recalculate/redraw everything. (It sounds expensive, but there's usually not much you can cache between draws).

How to change shape of square to dot in XYSplineRenderer Graph

In JFreeChart XYSplineRenderer Graph I need to display small dots instead of small squares to display XY coordinates. How can I change the shape of these dots?
To center a symmetric Shape over a given data point, you'll want to offset the top-left corner by the radius (half the diameter). For smaller dots,
setSeriesShape(0, new Ellipse2D.Double(-3, -3, 6, 6));
See also this related example using ShapeUtilities.
Use the setBaseShape method inherited from AbstractRenderer. Or you can use setSeriesShape
setBaseShape(new Ellipse2D.Float(100.0f, 100.0f, 100.0f, 100.0f));

How can I create beveled corners on a border in WPF?

I'm trying to do simple drawing in a subclass of a decorator, similar to what they're doing here...
How can I draw a border with squared corners in wpf?
...except with a single-pixel border thickness instead of the two they're using there. However, no matter what I do, WPF decides it needs to do its 'smoothing' (e.g. instead of rendering a single-pixel line, it renders a two-pixel line with each 'half' about 50% of the opacity.) In other words, it's trying to anti-alias the drawing. I do not want anti-aliased drawing. I want to say if I draw a line from 0,0 to 10,0 that I get a single-pixel-wide line that's exactly 10 pixels long without smoothing.
Now I know WPF does that, but I thought that's specifically why they introduced SnapsToDevicePixels and UseLayoutRounding, both of which I've set to 'True' in the XAML. I'm also making sure that the numbers I'm using are actual integers and not fractional numbers, but still I'm not getting the nice, crisp, one-pixel-wide lines I'm hoping for.
Help!!!
Mark
Aaaaah.... got it! WPF considers a line from 0,0 to 10,0 to literally be on that logical line, not the row of pixels as it is in GDI. To better explain, think of the coordinates in WPF being representative of the lines drawn on a piece of graph paper whereas the pixels are the squares those lines make up (assuming 96 DPI that is. You'd need to adjust accordingly if they are different.)
So... to get the drawing to refer to the pixel locations, we need to shift the drawing from the lines themselves to be the center of the pixels (squares on graph paper) so we shift all drawing by 0.5, 0.5 (again, assuming a DPI of 96)
So if it is a 96 DPI setting, simply adding this in the OnRender method worked like a charm...
drawingContext.PushTransform(new TranslateTransform(.5, .5));
Hope this helps others!
M
Have a look at this article: Draw lines exactly on physical device pixels
UPD
Some valuable quotes from the link:
The reason why the lines appear blurry, is that our points are center
points of the lines not edges. With a pen width of 1 the edges are
drawn excactly between two pixels.
A first approach is to round each point to an integer value (snap to a
logical pixel) an give it an offset of half the pen width. This
ensures, that the edges of the line align with logical pixels.
Fortunately the developers of the milcore (MIL stands for media
integration layer, that's WPFs rendering engine) give us a way to
guide the rendering engine to align a logical coordinate excatly on a
physical device pixels. To achieve this, we need to create a
GuidelineSet
protected override void OnRender(DrawingContext drawingContext)
{
Pen pen = new Pen(Brushes.Black, 1);
Rect rect = new Rect(20,20, 50, 60);
double halfPenWidth = pen.Thickness / 2;
// Create a guidelines set
GuidelineSet guidelines = new GuidelineSet();
guidelines.GuidelinesX.Add(rect.Left + halfPenWidth);
guidelines.GuidelinesX.Add(rect.Right + halfPenWidth);
guidelines.GuidelinesY.Add(rect.Top + halfPenWidth);
guidelines.GuidelinesY.Add(rect.Bottom + halfPenWidth);
drawingContext.PushGuidelineSet(guidelines);
drawingContext.DrawRectangle(null, pen, rect);
drawingContext.Pop();
}

Resources