I would like to draw a ring pie chart with its shading which color is start from BaseColor.WHITE to BaseColor.GREEN.
I used the pdfShading function. It fails when the X and Y axis' coordinate value are the same.
The pie chart isn't generated.
PdfShadingPattern pattern;
PdfShading axial;
axial = PdfShading.simpleAxial(canvas.getPdfWriter(), 0, 76, 0, 76,BaseColor.WHITE, BaseColor.GREEN);
pattern = new PdfShadingPattern(axial);
canvas.setShadingFill(pattern);
canvas.setShadingStroke(pattern);
canvas.fill();
To draw a circle you need to use simpleRadial instead of simpleAxial. Like:
axial = PdfShading.simpleRadial(canvas.getPdfWriter(), 0, 76, 5, 0, 76, 5,BaseColor.WHITE, BaseColor.GREEN);
Related
I studied this question, but I still don't get it. The shortest possible code below shows a Pyramid totally grey, whereas I try to give the 6 triangles making up the pyramid different colors. So ... why don't these colors show up?
Note that I borrowed the getTexCoords().addAll(..) statement from that question, but clearly I still am doing something wrong. Is it the uv mapping? What is that anyway? I have seen a topological explanation (sphere <-> map), but what has that got to do with textures/colors...?
Appreciate your help - Michael
public class ColoredPyramid extends Application {
public void start(Stage primaryStage) {
Group root = new Group();
Scene scene = new Scene(root, 200, 200, true);
primaryStage.setTitle("Colored Pyramid");
primaryStage.setScene(scene);
primaryStage.show();
TriangleMesh colouredPyramid = new TriangleMesh();
float height = 100;
float hypotenuse = 150;
colouredPyramid.getPoints().addAll(0, 0, 0); //0-index:: top
colouredPyramid.getPoints().addAll(0, height, -hypotenuse / 2); //1-index:: x=0, z=-hyp/2 ==> Closest to user
colouredPyramid.getPoints().addAll(-hypotenuse / 2, height, 0); //2-index:: x=hyp/2, z=0 ==> Leftest
colouredPyramid.getPoints().addAll(hypotenuse / 2, height, 0); //3-index:: x=hyp/2, z=0 ==> rightest
colouredPyramid.getPoints().addAll(0, height, hypotenuse / 2); ////4-index:: x=0, z=hyp/2 ==> Furthest from user
//Next statement copied from stackoverflow.com/questions/26831871/coloring-individual-triangles-in-a-triangle-mesh-on-javafx
colouredPyramid.getTexCoords().addAll(
0.1f, 0.5f, // 0 red
0.3f, 0.5f, // 1 green
0.5f, 0.5f, // 2 blue
0.7f, 0.5f, // 3 yellow
0.9f, 0.5f // 4 orange
);
colouredPyramid.getFaces().addAll(0, 0, 2, 0, 1, 0); //Left front face ---> RED
colouredPyramid.getFaces().addAll(0, 1, 1, 1, 3, 1); //Right front face ---> GREEN
colouredPyramid.getFaces().addAll(0, 2, 3, 2, 4, 2); //Right back face ---> BLUE
colouredPyramid.getFaces().addAll(0, 3, 4, 3, 2, 3); //Left back face ---> RED
colouredPyramid.getFaces().addAll(4, 4, 1, 4, 2, 4); //Base: left triangle face ---> YELLOW
colouredPyramid.getFaces().addAll(4, 0, 3, 0, 1, 0); //Base: right triangle face ---> ORANGE
MeshView meshView = new MeshView(colouredPyramid);
Group group = new Group(meshView);
group.setTranslateX(100);
group.setTranslateY(80);
root.getChildren().add(group);
}
public static void main(String[] args) {
launch(args);
}
}
To understand how JavaFX 3D defines the color of any given 3D shape, have a look at the PhongMaterial javadoc (bold is mine):
The PhongMaterial class provides definitions of properties that represent a Phong shaded material. It describes the interaction of light with the surface of the Mesh it is applied to. The PhongMaterial reflects light in terms of a diffuse and specular component together with an ambient and a self illumination term. The color of a point on a geometric surface is mathematical function of these four components.
That means that you need to supply a material in the first place, and then you need to specify any of those components, for instance the diffuse component.
If you copy the image from the cited question:
and create a material instance with it:
PhongMaterial material = new PhongMaterial();
material.setDiffuseMap(new Image(getClass().getResourceAsStream("bB2jV.png")));
meshView.setMaterial(material);
you can see that this image is used to apply colors to your pyramid:
If you modify the texture indices for the faces, you will get different colors, based on the texture coordinates.
To know more about this, you can have a look at the FXyz3D library, that provides a TexturedMesh class based in this concept. There you will find many different 3D shape "textured" primitives, that can use different texture "modes". Most of those modes don't even require an image, as this is created internally. This allows creating for instance color gradients based on mathematical functions.
This is an example of a TetrahedraMesh, that makes use a 3D function to define the density map:
TetrahedraMesh tetra = new TetrahedraMesh(10, 5, null);
tetra.setTextureModeVertices3D(1530, p -> p.magnitude());
I currently have an application that onClick will draw a green bounding rectangle around the battery and the blue strip of paper. I would also like to have the button onClick draw a line from the battery to the strip of paper(as shown in second picture below). Currently I am able to get the all the x and y values of the rectangles, thus knowing that I need to draw a line from 534,1261 to 788,1261 and have the line labeled with the x difference as shown in picture.
For drawing lines and text You can use code like that:
Point firstPoint = new Point(100, 200);
Point secondPoint = new Point(100, 400);
Point middlePoint = new Point(firstPoint.x,
firstPoint.y + 0.5 * (secondPoint.y - firstPoint.y));
Scalar lineColor = new Scalar(255, 0, 0, 255);
int lineWidth = 3;
Scalar textColor = new Scalar(255, 0, 0, 255);
Imgproc.line(sourceMat, firstPoint, secondPoint, lineColor, lineWidth);
Imgproc.putText(sourceMat, " Text" , middlePoint,
Core.FONT_HERSHEY_PLAIN, 1.5 , textColor);
Where sourceMat - Mat with image.
And for determining of line "height" in cm (approximately) You should use "height" of battery rectangle :
lineHeightCm = 4.46 / heightOfBatteryRectangleInPixels * lineHeightInPixels;
where 4.46 - "height" of AAA battery in cm.
I am trying to draw a gradient rectangle that goes from red to blue. I have the following code:
g2d.setPaint(new GradientPaint(0, 0, Color.RED, 1000, 1000, Color.BLUE));
g2d.fillRect(0, 0, 1000, 1000);
This is working. However, the direction of the gradient is diagonal, from the top left point of the rectangle to the bottom right point (another way to look at this is that the gradient follows the line of y=-x + windowHeight)
I would like my gradient to go from top to bottom. So the entire top of the rectangle is red, and the entire bottom is blue. In other words, the color should only change with the y coordinate, given any y=point line the color should be uniform across that line.
I have included the following images also to give a general idea of what I am trying to do:
How can I accomplish this?
It all has to do with the vector of your gradient. Here: (0, 0, Color.RED, 1000, 1000, Color.BLUE) you're vector is a diagonal vector that originates at [0, 0], and then ends or points at [1000, 1000] or on a 45 degree angle.
Change that to straight down: [0, 0] going to [0, 1000] should work well. e.g,
new GradientPaint(0, 0, Color.RED, 0, 1000, Color.BLUE)
Just using the coord system my rectangle for my touch bounding box never seems to align with the coordinated and placement of my textures.
What is the simplest way to draw bounding box rectangles so that I can line them up with my drawn textures?
Im using OPEN-GLES
EG..
playBounds = new Rectangle( 240, 400, 157, 177);
batcher.drawSprite(240, 400, 157, 177, Assets.mainMenu);
I found out that because the bounding rectangles are based on the lower left corner and texture coords are based on the center, the below seems to be the best solution.
playBounds = new Rectangle(240, 400, 157, 177);
batcher.drawSprite(
playBounds.lowerLeft.x + playBounds.width / 2,
playBounds.lowerLeft.y + playBounds.height / 2,
playBounds.width,
playBounds.height,
Assets.mainMenu
);
I working on a project in which I have to simulate a memory manager and show some memory snapshots. I have created a draw class via examples I have found here in which I override the paintComponet(). Everything draws fine.
I would like to be able to draw a rectangle to represent a memory partition and then overlay another rectangle over top to represent an incoming job (ie Job1 is in this partition3). What seems to occur is that I add the partition first (which will always be the case) and then when I add the job it will sit behind the partition block. Is there a way other than drawing the Job first to shift these after the job is created?
Here is the paint override
#Override public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D)g;
// set up rendering to allow anti-aliasing
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
// create the rectangle to represent the memory partition block
// x = address position h = amount of memory (y & w are predefined for the display block)
Rectangle2D rect = new Rectangle2D.Double(x, y, w, h); // create the rectangle
g2d.setPaint(partColor); // set it's color
g2d.fill(rect); // fill it in
// create the transparency for the text
Composite comp = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, .4f);
g2d.setComposite(comp);
// draw the text with color, type and size and center the text in the block created above
g2d.setPaint(Color.black);
g2d.setFont(new Font("Tahoma", Font.PLAIN, 12));
g2d.drawString(text, (int)((w / 2) - (text.length()/2)), (int)h/2);
}
The call to draw is in my window class (this will place the partition in front of the job) but I need to order to be reversed without changing the order of the calls.
// Draw both Text and Block with transparency
DrawPartition part1 = new DrawPartition(Color.blue, 0, 0, 110, 100, "part1");
part1.setBounds(5, 5, 110, 100);
snapPanel.add(part1);
DrawJob job1 = new DrawJob(Color.green, 0, 0, 110, 100, "Job 1");
job1.setBounds(5, 15, 110, 100);
snapPanel.add(job1);
Is there some reason you can't do this?
// Draw both Text and Block with transparency
DrawPartition part1 = new DrawPartition(Color.blue, 0, 0, 110, 100, "part1");
part1.setBounds(5, 5, 110, 100);
DrawJob job1 = new DrawJob(Color.green, 0, 0, 110, 100, "Job 1");
job1.setBounds(5, 15, 110, 100);
snapPanel.add(job1);
snapPanel.add(part1);
A more general answer would be to add a z component to each of your rectangles. Then you can loop through your rectangles in the paintComponent method, drawing them in z order.