Displaying fan blades in Java - java

I do not understand the significance of multiplying by 0.4 in this line:
int radius = (int)(Math.min(getWidth(), getHeight()) * 0.4)
in the code below. how are they calculating the radius beneath
//Displaying fan blades in Java
package graphics;
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.Color;
import java.awt.Graphics;
#SuppressWarnings("serial")
class DrawFan extends JFrame {
public DrawFan() {
setTitle("The Four Fan Blades");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
add(new BladesPanel());
}
class BladesPanel extends JPanel {
protected void paintComponent(Graphics g){
super.paintComponent(g);
int xCenter = getWidth() / 2;
int yCenter = getHeight() / 2;
int radius = (int)(Math.min(getWidth(), getHeight()) * 0.4);
int x = xCenter - radius;
int y = yCenter - radius;
g.fillArc(x, y, 2 * radius, 2 * radius, 0, 30);
g.fillArc(x, y, 2 * radius, 2 * radius, 90, 30);
g.fillArc(x, y, 2 * radius, 2 * radius, 180, 30);
g.fillArc(x, y, 2 * radius, 2 * radius, 270, 30);
}
}
public static void main(String[] args) {
DrawArcs2 fanBlades = new DrawArcs2();
fanBlades.setSize(300,300);
fanBlades.setVisible(true);
}
}

In this line:
int radius = (int)(Math.min(getWidth(), getHeight()) * 0.4);
They first get what number is bigger in your JPanel: the width or the height with this part (Math.min(getWidth(), getHeight())
Imagine height is 400 and width 300. 400 is going to be selected. Now, you want to paint a circle inside this 400-wide rectangle. To fit your circle you need to make it at least 1/2 400 points. That's the same as 400*0.5. To fit better the circle inside, they choose to multiply by 0.4 (or 40% the size of the taller width/height)

Related

Start angle and extent values using Java's Arc2D give unexpected results

I am trying to understand the use of Java's Arc2D. Don't know how to calculate the start angle and extent when creating an arc out of an ellipse (not a circle). I want an arc of an ellipse with ry = 2 * rx where the start angle is at 45 deg and the extent is 90 deg. But instead I have to send a start angle of ~26 deg and an extent of ~127 deg to get what I expect. The included code generates an image with 3 arcs: green is a circle arc which behaves as expected, red is an ellipse arc with the expected parameters but unexpected results and blue is an arc with unexpected parameters but the expected result. Am I misinterpreting something here? In addition, at start angle of 0 deg and extent 90 deg the results are as expected??? Thx.
package example;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.geom.Arc2D;
import java.awt.image.BufferedImage;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
public class ExampleArc2D {
public static void main(String[] args) {
try {
int width = 800;
int height = 800;
BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
Graphics2D gfx2D = bi.createGraphics();
gfx2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
gfx2D.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
gfx2D.setFont(new Font(Font.MONOSPACED, Font.BOLD, 16));
FontMetrics fm = gfx2D.getFontMetrics();
gfx2D.setColor(Color.BLACK);
gfx2D.fillRect(0, 0, bi.getWidth(), bi.getHeight());
gfx2D.setStroke(new BasicStroke(2f));
int x = 5;
int y = 0;
int centerX = width / 2;
int centerY = height / 2 + 200;
int circleRadius = 200;
int ellipseRadiusX = circleRadius;
int ellipseRadiusY = 2 * circleRadius;
// gfx2D.setColor(new Color(255, 255, 255, 50));
// gfx2D.draw(new Ellipse2D.Double(centerX - circleRadius, centerY - circleRadius, 2 * circleRadius, 2 * circleRadius));
// gfx2D.draw(new Ellipse2D.Double(centerX - ellipseRadiusY, centerY - ellipseRadiusY, 2 * ellipseRadiusY, 2 * ellipseRadiusY));
// gfx2D.draw(new Ellipse2D.Double(centerX - ellipseRadiusX, centerY - ellipseRadiusY, 2 * ellipseRadiusX, 2 * ellipseRadiusY));
double startAngle = 45.0;
double extent = 90.0;
Arc2D circle = new Arc2D.Double(centerX - circleRadius, centerY - circleRadius, 2 * circleRadius, 2 * circleRadius, startAngle, extent, Arc2D.PIE);
gfx2D.setColor(Color.GREEN);
gfx2D.draw(circle);
y += fm.getAscent();
gfx2D.drawString("ARC FROM CIRCLE WITH EXPECTED PARMS AND RESULT:", x, y);
y += fm.getAscent();
gfx2D.drawString(String.format("start angle %.1f° and extent %.1f°", startAngle, extent), x, y);
startAngle = 45.0;
extent = 90.0;
Arc2D unexpectedEllipse = new Arc2D.Double(centerX - ellipseRadiusX, centerY - ellipseRadiusY, 2 * ellipseRadiusX, 2 * ellipseRadiusY, startAngle, extent, Arc2D.PIE);
gfx2D.setColor(Color.RED);
gfx2D.draw(unexpectedEllipse);
y += fm.getAscent();
gfx2D.drawString("UNEXPECTED ARC FROM ELLIPSE WITH EXPECTED PARMS AND UNEXPECTED RESULT:", x, y);
y += fm.getAscent();
gfx2D.drawString(String.format("start angle %.1f° and extent %.1f°", startAngle, extent), x, y);
startAngle = 26.4;
extent = 127.2;
Arc2D expectedEllipse = new Arc2D.Double(centerX - ellipseRadiusX, centerY - ellipseRadiusY, 2 * ellipseRadiusX, 2 * ellipseRadiusY, startAngle, extent, Arc2D.PIE);
gfx2D.setColor(Color.BLUE);
gfx2D.draw(expectedEllipse);
y += fm.getAscent();
gfx2D.drawString("EXPECTED ARC FROM ELLIPSE WITH UNEXPECTED PARMS AND EXPECTED RESULT:", x, y);
y += fm.getAscent();
gfx2D.drawString(String.format("start angle %.1f° and extent %.1f°", startAngle, extent), x, y);
y += fm.getAscent();
gfx2D.drawString("even though it is clear that the start angle is at 45° and the extent is 90°???", x, y);
gfx2D.setColor(Color.YELLOW);
gfx2D.drawRect(centerX - ellipseRadiusX, centerY - ellipseRadiusY, ellipseRadiusX * 2, ellipseRadiusY * 2);
gfx2D.setColor(Color.ORANGE);
gfx2D.drawLine(centerX, centerY, centerX + ellipseRadiusX, centerY - ellipseRadiusY);
x = centerX + ellipseRadiusX + 5;
y = centerY - ellipseRadiusY;
gfx2D.drawString("this is 45° as far", x, y);
y += fm.getAscent();
gfx2D.drawString("as the ellipse is", x, y);
y += fm.getAscent();
gfx2D.drawString("concerned!", x, y);
gfx2D.dispose();
JOptionPane.showMessageDialog(null, new JLabel(new ImageIcon(bi)));
// ImageIO.write(bi, "png", new File("examplearc2d.png"));
}
catch(Throwable t) {
t.printStackTrace();
}
}
}
UPDATE: Found a way to get the angles but it was too clunky so took another approach. I used a clipping area to solve the problem. I solved my problem but didn't really answer the question. Won't pursue it any further. So basically I draw the ellipse but apply a clipping area so only the arc is drawn.
package example;
import java.awt.BasicStroke;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.geom.AffineTransform;
import java.awt.geom.Arc2D;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Line2D;
import javax.swing.BorderFactory;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.SwingUtilities;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
public class ExampleArc2D3
extends JFrame {
private Canvas canvas;
private JSlider ryrxSld;
private JSlider startAngleSld;
private JSlider extentSld;
private JSlider angleSld;
public ExampleArc2D3() {
super("Example Arc2D");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container cp = getContentPane();
cp.add(canvas = new Canvas(), BorderLayout.CENTER);
JPanel southPanel = new JPanel(new BorderLayout());
southPanel.setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3));
cp.add(southPanel, BorderLayout.SOUTH);
JPanel labelsPanel = new JPanel(new GridLayout(0, 1, 0, 0));
southPanel.add(labelsPanel, BorderLayout.WEST);
JPanel fieldsPanel = new JPanel(new GridLayout(0, 1, 0, 0));
southPanel.add(fieldsPanel, BorderLayout.CENTER);
labelsPanel.add(new JLabel("ry/rx: "));
fieldsPanel.add(ryrxSld = new JSlider(10, 25, 20));
labelsPanel.add(new JLabel("Start Angle: "));
fieldsPanel.add(startAngleSld = new JSlider(0, 3600, 0));
labelsPanel.add(new JLabel("Extent: "));
fieldsPanel.add(extentSld = new JSlider(0, 3600, 300));
labelsPanel.add(new JLabel("Protractor: "));
fieldsPanel.add(angleSld = new JSlider(0, 3600, 0));
ChangeHandler ch = new ChangeHandler();
ryrxSld.addChangeListener(ch);
startAngleSld.addChangeListener(ch);
extentSld.addChangeListener(ch);
angleSld.addChangeListener(ch);
setSize(1000, 1020);
setVisible(true);
}
private class Canvas
extends JComponent {
public void refresh() {
invalidate();
repaint();
}
#Override
public void paintComponent(Graphics gfx) {
super.paintComponent(gfx);
Graphics2D gfx2D = (Graphics2D) gfx;
Dimension size = getSize();
try {
int width = size.width;
int height = size.height;
gfx2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
gfx2D.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
gfx2D.setFont(new Font(Font.MONOSPACED, Font.BOLD, 16));
FontMetrics fm = gfx2D.getFontMetrics();
gfx2D.setColor(Color.BLACK);
gfx2D.fillRect(0, 0, width, height);
double startAngle = startAngleSld.getValue() / 10.0;
double extent = extentSld.getValue() / 10.0;
int x = 5;
int y = 0;
gfx2D.setColor(Color.WHITE);
y += fm.getAscent();
gfx2D.drawString(String.format("ry/rx: %.1f", ryrxSld.getValue() / 10.0), x, y);
y += fm.getAscent();
gfx2D.drawString(String.format("start angle %.1f° and extent %.1f°", startAngle, extent), x, y);
int centerX = width / 2;
int centerY = 460;
double ellipseRadiusX = 200;
double ellipseRadiusY = ryrxSld.getValue() * ellipseRadiusX / 10.0;
gfx2D.setColor(new Color(255, 255, 255, 60));
gfx2D.setStroke(new BasicStroke(1f));
gfx2D.draw(new Ellipse2D.Double(centerX - ellipseRadiusX, centerY - ellipseRadiusX, 2 * ellipseRadiusX, 2 * ellipseRadiusX));
gfx2D.draw(new Ellipse2D.Double(centerX - ellipseRadiusY, centerY - ellipseRadiusY, 2 * ellipseRadiusY, 2 * ellipseRadiusY));
gfx2D.draw(new Ellipse2D.Double(centerX - ellipseRadiusX, centerY - ellipseRadiusY, 2 * ellipseRadiusX, 2 * ellipseRadiusY));
gfx2D.setStroke(new BasicStroke(2f));
gfx2D.setStroke(new BasicStroke(1f));
gfx2D.setFont(new Font(Font.MONOSPACED, Font.PLAIN, 10));
fm = gfx2D.getFontMetrics();
// clip area
Shape clipArea = buildClipArea(centerX, centerY, ellipseRadiusX, ellipseRadiusY, startAngle, extent);
gfx2D.setColor(new Color(255, 0, 0, 120));
gfx2D.draw(clipArea);
Shape oldClip = gfx2D.getClip();
gfx2D.setClip(clipArea);
gfx2D.setColor(Color.BLUE);
gfx2D.setStroke(new BasicStroke(2f));
gfx2D.draw(new Ellipse2D.Double(centerX - ellipseRadiusX, centerY - ellipseRadiusY, 2 * ellipseRadiusX, 2 * ellipseRadiusY));
gfx2D.setClip(oldClip);
double angle = angleSld.getValue() / 10.0;
gfx2D.setColor(Color.CYAN);
double len = 800.0;
gfx2D.draw(new Line2D.Double(centerX, centerY, centerX + len * Math.cos(Math.toRadians(angle)), centerY - len * Math.sin(Math.toRadians(angle))));
gfx2D.drawString(String.format("%.1f°", angle), centerX + 5, centerY + fm.getAscent());
}
catch(Throwable t) {
t.printStackTrace();
}
}
private Shape buildClipArea(double centerX,
double centerY,
double ellipseRadiusX,
double ellipseRadiusY,
double startAngle,
double extent) {
double radius = Math.max(ellipseRadiusX, ellipseRadiusY);
Arc2D arc = new Arc2D.Double(centerX - radius, centerY - radius, 2 * radius, 2 * radius, 0, extent, Arc2D.PIE);
AffineTransform at = new AffineTransform();
at.rotate(Math.toRadians(-startAngle), centerX, centerY);
return at.createTransformedShape(arc);
}
}
private class ChangeHandler
implements ChangeListener {
#Override
public void stateChanged(ChangeEvent e) {
canvas.refresh();
}
}
public static void main(String[] args) {
Runnable runner = new Runnable() {
#Override
public void run() {
new ExampleArc2D3();
}
};
SwingUtilities.invokeLater(runner);
}
}
The API for the Arc2D class states:
The angles are specified relative to the non-square framing rectangle such that 45 degrees always falls on the line from the center of the ellipse to the upper right corner of the framing rectangle
Not really sure what that means or how that provides insight on how to calculate the appropriate angles to use to achieve your desired result
However, it can be demonstrated by adding the following code at the bottom of your class:
gfx2D.setColor( Color.YELLOW );
gfx2D.drawRect(centerX - ellipseRadiusX, centerY - ellipseRadiusY, ellipseRadiusX * 2, ellipseRadiusY * 2);
gfx2D.setColor( Color.ORANGE );
gfx2D.drawLine(centerX, centerY, centerX + ellipseRadiusX, centerY - ellipseRadiusY);

Rotating a triangle around its axis

I have got a circle and a triangle inside. I need this figure to rotate around its axis and each time it rotates on a certain angle, it should be painted, overall to get something kind of 'ornament'(on the screen below). I've been trying with Graphics2D, but it went bad. How can I do that?
Code:
import org.omg.CORBA.TIMEOUT;
import javax.swing.*;
import java.awt.*;
import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
public class Main extends JPanel {
public static void main(String[] args) {
JFrame frame = new JFrame("Laboratorna 1");
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.add(new Main());
frame.setSize(1200, 800);
frame.setVisible(true);
}
public void paintComponent(Graphics g){
int num_2 = 8;
int bigOval_h = 300, bigOval_w = 300;
g.setColor(Color.BLUE);
g.drawOval(0+500, 0, bigOval_h, bigOval_w);
g.drawLine(150+500, 0, 20+500, 225);
g.drawLine(150+500, 0, 280+500, 225);
g.drawLine(20+500, 225,280+500, 225);
g.setColor(Color.RED);
}
}
The trick is to perform an affine transform for each angle. In addition you have to define the pivot point for each transform which equals the center of the circle. The following modifications of the paintComponent-method should possibly do the job.
public void paintComponent(Graphics g){
int num_2 = 8;
int bigOval_h = 300, bigOval_w = 300;
g.setColor(Color.BLUE);
g.drawOval(0 + 500, 0, bigOval_h, bigOval_w);
// REMOVE -------------------------------------------
// g.drawLine(150+500, 0, 20+500, 225);
// g.drawLine(150+500, 0, 280+500, 225);
// g.drawLine(20+500, 225,280+500, 225);
// REMOVE -------------------------------------------
g.setColor(Color.RED);
// ADD -------------------------------------------------------------------
// Create, transform and draw the lines
Line2D lin1 = new Line2D.Float(150f + 500f, 0f, 20f + 500f, 225f);
Line2D lin2 = new Line2D.Float(150f + 500f, 0f, 280f + 500f, 225f);
Line2D lin3 = new Line2D.Float(20f + 500f, 225f, 280f + 500f, 225f);
double pivotX = 500.0 + bigOval_w / 2.0; // center of the circle (x)
double pivotY = 0.0 + bigOval_h / 2.0; // center of the circle (y)
for (int i = 0; i < num_2; i++) {
AffineTransform affineTransform = AffineTransform.getRotateInstance(Math.toRadians(360.0 / num_2 * i), pivotX, pivotY);
((Graphics2D)g).draw(affineTransform.createTransformedShape(lin1));
((Graphics2D)g).draw(affineTransform.createTransformedShape(lin2));
((Graphics2D)g).draw(affineTransform.createTransformedShape(lin3));
}
// ADD -------------------------------------------------------------------
}
The output is:
One way to define a polygon is radius, rotation, and number of sides. A triangle is a 3 sided polygon. So a triangle class can simply save radius and rotation and then compute the three vertices of the polygon for drawing around a center point.
public class Triangle {
private final int radius;
private final double rotation;
public Triangle(int radius, double rotation) {
this.radius = radius;
this.rotation = rotation;
}
public void paintComponent(Graphics2D g, Point center) {
int[] xVertices = new int[3];
int[] yVertices = new int[3];
xVertices[0] = (int) (center.getX() - (Math.cos(rotation) * radius));
yVertices[0] = (int) (center.getY() - (Math.sin(rotation) * radius));
xVertices[1] = (int) (center.getX() - (Math.cos(Math.PI * 0.66667 + rotation) * radius));
yVertices[1] = (int) (center.getY() - (Math.sin(Math.PI * 0.66667 + rotation) * radius));
xVertices[2] = (int) (center.getX() - (Math.cos(Math.PI * 1.33333 + rotation) * radius));
yVertices[2] = (int) (center.getY() - (Math.sin(Math.PI * 1.33333 + rotation) * radius));
Polygon polygon = new Polygon(xVertices, yVertices, 3);
g.setColor(Color.RED);
g.drawPolygon(polygon);
}
}
This would give two triangles rotated PI radians.
Triangle t = new Triangle(100, 0.0);
t.paintComponent((Graphics2D)g, new Point(250,250));
Triangle t2 = new Triangle(100, Math.PI);
t2.paintComponent((Graphics2D)g, new Point(250,250));

Loops with graphics - bug in generating the graphics

I'm trying to make my code draw 10 rectangles, each one with a random position and size.
The problem is that, for some reason, it only draws one rectangle and never draws the other 9.
I'm using Math.random.
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Line2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Punto1
extends JPanel {
public static void main(String[] args) {
System.out.println("Estoy en el main");
JFrame frame = new JFrame("Soy una ventana :D");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(1280, 720);
frame.setVisible(true);
frame.setLocation(400, 200);
frame.setLocationRelativeTo(null);
frame.add(new Punto1());
}
public Punto1() {
}
public void paintComponent(Graphics g) {
g.setColor(Color.BLUE);
/*if(x1 != 0 && y1 != 0 && x2 != 0 && y2 !=0){
g.drawLine(x1,y1,x2,y2);
*/
rectangulo(g);
}
public void rectangulo(Graphics g) {
for (int i = 0; i < 10; i++) {
int x = (int) Math.random() * 1120 + 75;
int y = (int) Math.random() * 680 + 75;
int width = (int) Math.random() * 960 + 50;
int height = (int) Math.random() * 960 + 50;
g.setColor(Color.BLUE);
g.drawRect(x, y, width, height);
}
}
}
(int)Math.random() is truncating the value to an int, okay, but, random returns a value between 0 & 1, meaning that, any value less then 1 will be, 0, 0 x 1120 is 0 plus 75, which is 75, so you your code is drawing 10 rectangles in the same location
Two, possible solutions:
One...
Cast the result of the calculation to int after it's performed:
int x = (int)(Math.random() * 1120 + 75)
This will ensure that the calculation is done against a double base value and the truncated to int after the result is calculated
Two
Make use of the Graphics 2D API and use a Rectangle2D which supports double values...
double x = Math.random() * 1120 + 75;
double y = Math.random() * 680 + 75;
double width = Math.random() * 960 + 50;
double height = Math.random() * 960 + 50;
Rectangle2D rect = new Rectangle2D.Double(x, y, width, height);
((Graphics2D)g).draw(rect);
Side note...
Also, unless you have a specific reason to do otherwise, you should call setVisible last - it will cause less issues
JFrame frame = new JFrame("Soy una ventana :D");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(1280,720);
frame.add(new Punto1());
frame.setLocationRelativeTo(null);
frame.setVisible(true);
And finally (no, really ;))
Because of the way windows work an various operating systems, the panel is unlikely to be the same size as the window, in fact, in most cases, it's smaller.
In this case you should avoid relying on magic numbers and use known values
double x = Math.random() * getWidth() + 75;
double y = Math.random() * getHeight() + 75;
double width = Math.random() * (getWidth() / 2.0) + 50;
double height = Math.random() * (getHeight() / 2.0) + 50;
Rectangle2D rect = new Rectangle2D.Double(x, y, width, height);
((Graphics2D)g).draw(rect);

Translate, Scale, Rotate Yin Yang Symbol

I need help with Translating, Rotating, and Scaling a Yin-Yang Symbol in Java. Can anyone provide suggestions I'll post the code below. I'm trying to use affine transformation does anyone have a way to make sure every part follows suit when I decide to move rotate, translate, scale?
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.geom.AffineTransform;
import java.awt.geom.Area;
import java.awt.geom.Ellipse2D;
import javax.swing.JFrame;
public class ScaleTranslationRotation extends JFrame
{
public void paint(Graphics g){
super.paint(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
int xLeft,yUpper,width, height;
xLeft = this.getInsets().left;
yUpper = this.getInsets().top;
width = this.getWidth()-xLeft-this.getInsets().right;
height = this.getHeight()-this.getInsets().top-this.getInsets().bottom;
int xCenter = getWidth() / 2;
int yCenter = getHeight() / 2;
int radius = (int)(Math.min(getWidth(), getHeight()) * 0.2);
int x = xCenter - radius;
int y = yCenter - radius;
AffineTransform yUp = new AffineTransform();
g.setColor(Color.blue);
g.fillOval(x, y, 2 * radius, 2 * radius);
g.setColor(Color.cyan);
g.drawOval(x, y, 2 * radius, 2 * radius);
g.setColor(Color.cyan);
g.fillArc(x, y, 2 * radius, 2 * radius, 270, 180);
g.setColor(Color.blue);
g.fillOval(x + (radius / 2), y, radius, radius);
g.setColor(Color.cyan);
g.fillOval(x + (radius / 2), y + radius, radius, radius);
g.setColor(Color.cyan);
g.fillOval(x + radius - (radius / 4), y + radius / 4, radius / 2, radius / 2);
g.setColor(Color.blue);
g.fillOval(x + radius - (radius / 4), y + radius + radius / 4, radius / 2, radius / 2);
g2d.setStroke(new BasicStroke(1.0f));
g.setColor(Color.red);
drawSimpleCoordinateSystem(width,height, g2d);
grid(width, height, g2d);
}
public static void drawSimpleCoordinateSystem(int x, int y, Graphics2D g2d){
int xOffset = 30;
int yOffset = 50;
int step = 20;
String s;
//Remember the actual font.
Font fo = g2d.getFont();
//Use a small font.
g2d.setFont(new Font("sansserif",Font.PLAIN,9));
//x-axis.
g2d.drawLine(xOffset,yOffset,x,yOffset);
//Marks and labels for the x-axis.
for (int i=xOffset+step; i<=x; i=i+step)
{
g2d.drawLine(i,yOffset-2,i,yOffset+2);
g2d.drawString(String.valueOf(i),i-7,yOffset-7);
}
//y-axis.
g2d.drawLine(xOffset,yOffset,xOffset,y);
//Marks and labels for the y-axis.
s=" "; //for indention of numbers < 100
for (int i=yOffset+step; i<=y; i=i+step){
g2d.drawLine(xOffset-2,i,xOffset+2,i);
if (i>99){s="";}
g2d.drawString(s+String.valueOf(i),xOffset-25,i+5);
}
//Reset to the original font.
g2d.setFont(fo);
}
public void grid(int x, int y, Graphics2D g2d){
int xOffset = 30;
int yOffset = 50;
int step = 20;
g2d.drawLine(xOffset, yOffset, x, yOffset);
for(int i = xOffset+step; i<= x; i = i+step){
g2d.drawLine(i, yOffset, i, y);
}
g2d.drawLine(xOffset, yOffset, xOffset, y);
for(int i = yOffset+step; i<=y; i = i+step){
g2d.drawLine(xOffset, i, x, i);
}
}
public static void main(String[] args)
{
ScaleTranslationRotation f = new ScaleTranslationRotation();
f.setTitle("STR");
f.setSize(1920,1020);
f.setVisible(true);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
Just put your code yin-yang symbol code in a method
private void drawSymbol(int x, int y, int radius, Graphics g) {
g.setColor(Color.blue);
g.fillOval(x, y, 2 * radius, 2 * radius);
g.setColor(Color.cyan);
g.drawOval(x, y, 2 * radius, 2 * radius);
g.setColor(Color.cyan);
g.fillArc(x, y, 2 * radius, 2 * radius, 270, 180);
g.setColor(Color.blue);
g.fillOval(x + (radius / 2), y, radius, radius);
g.setColor(Color.cyan);
g.fillOval(x + (radius / 2), y + radius, radius, radius);
g.setColor(Color.cyan);
g.fillOval(x + radius - (radius / 4), y + radius / 4, radius / 2, radius / 2);
g.setColor(Color.blue);
g.fillOval(x + radius - (radius / 4), y + radius + radius / 4, radius / 2, radius / 2);
}
And then use an Affine transformation before calling the method to perform the requested transformation.
In the following I draw the symbol three times with different transformation
Remember to restore the original affine transformation to the initial value:
drawSymbol(x,y,radius,g);
//save original transformation
AffineTransform oldt=((Graphics2D) g).getTransform();
//create new transformation and apply it
AffineTransform yUp = new AffineTransform();
yUp.translate(0,-100);
((Graphics2D) g).setTransform(yUp);
drawSymbol(x,y,radius,g);
//create anothernew transformation and apply it
yUp = new AffineTransform();
yUp.translate(-100,0);
((Graphics2D) g).setTransform(yUp);
drawSymbol(x,y,radius,g);
//restore old transforamtion
((Graphics2D) g).setTransform(oldt);
g2d.setStroke(new BasicStroke(1.0f));
g.setColor(Color.red);
drawSimpleCoordinateSystem(width,height, g2d);
grid(width, height, g2d);

Draw a circle with fan blades inside, Java

I have to display four "fans" or arcs that are outlined by a circle, i have the fanblades/arcs set and looking the way i would like but i cannot figure out how to get them outlined by a circle, any ideas? Thanks in advance.
package chap15;
import java.awt.Graphics;
import javax.swing.JPanel;
public class Fans extends JPanel {
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
int xCenter = getWidth() / 2;
int yCenter = getHeight() / 2;
int radius = (int)(Math.min(getWidth(), getHeight()) * 0.4);
int x = xCenter - radius;
int y = yCenter - radius;
g.fillArc(x, y, 2 * radius, 2 * radius, 0, 30);
g.fillArc(x, y, 2 * radius, 2 * radius, 90, 30);
g.fillArc(x, y, 2 * radius, 2 * radius, 180, 30);
g.fillArc(x, y, 2 * radius, 2 * radius, 270, 30);
}
}
drawArc?

Categories