I have a homework assignment that I am ready to turn in, in the assignment I had to use recursion to draw nested circles 10 levels deep, after banging my head against this for a few hours I finally completed it. My only question is, is the image I am drawing 10 levels deep or actually 11?
This question comes from the fact that I have specifically state the recursion to end when it has gone through 10 levels, but I do tell the method to draw the original circles then it calls itself. this is making me think that it draws the first level then goes down 10 to make a total of 11 levels. the Image it creates goes down so far that I can not count the circles :/
any clarification would be appreciated, thanks!
// import statements
import java.awt.*;
import javax.swing.*;
public class RecursiveCircles
{
public static void main(String[] args)
{
// create a new canvas
RCanvas myCanvas = new RCanvas();
// create JFrame
JFrame myJframe = new JFrame();
myJframe.setTitle("Recursive Circles");
// set JFrame size, location and close operation
myJframe.setSize(1500, 500);
myJframe.setLocation(100, 100);
myJframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// and canvas to JFrame and make it visble
myJframe.getContentPane().add(myCanvas);
myJframe.setVisible(true);
} // end main
} // end class RecursiveCircles
/*
* this class will draw the main circle of the image and will have the recursive
* method that draws the two outer circles down 10 levels
*/
class RCanvas extends Canvas
{
// defualt constructor
public RCanvas ()
{}
public void paint (Graphics graphics)
{
// declare variables
String title = "Recursive Circles";
int n = 300; // diamerter of the circle
int xOrigin = 600; // x location of start of circle (makes circle around the origin I wanted
int yOrigin = 100; // y location of start of circle (makes circle around the origin i wanted
int radius = n/2; // radius of circle (half the diamerter
int level = 10;
// make canvas background color black
graphics.setColor(Color.black); // make the background color black
graphics.fillRect(0, 0, 1500, 500); // rectangle that fills the JFrame
// put title on canvas
graphics.setColor(Color.BLUE);
graphics.drawString(title, 725, 50);
// draw main circle
graphics.setColor(Color.WHITE);
graphics.drawOval(xOrigin, yOrigin, n, n);
drawRCircles(graphics,xOrigin,yOrigin,radius,level); // call recrusrive method
System.out.println(level);
} // end paint
/*
* This is the recursive method that will draw the two circles on the outer sides of the
* main circle. it will then call itself and repate the process till it is 10 levels deep
*/
public void drawRCircles(Graphics graphics,int xOrigin,int yOrigin, int radius, int level)
{
int newRadius = (radius/2); // radius of smaller circle
int newXOrigin = xOrigin - (newRadius); // xOrigin of circle on left of the main circle
int newYOrigin = yOrigin + (newRadius); // yOrigin of circle on the right of the main circle
int newXOrigin2 = xOrigin + (newRadius*3); // xOrigin of circle on the right of the main circle
int newYOrigin2 = yOrigin + (newRadius); // yOrigin of circle on the right of the main circle
if (level > 0) // counts down from 10 to make the recursive image 10 levels deep
{
graphics.drawOval(newXOrigin, newYOrigin, newRadius*2, newRadius*2); // draw recursive circle on the left of main circle
graphics.drawOval(newXOrigin2, newYOrigin2, newRadius*2, newRadius*2); // draw recursive circle on the right of main circle
drawRCircles(graphics, newXOrigin, newYOrigin , newRadius, (level-1)); // make recursion of left circle
drawRCircles(graphics, newXOrigin2, newYOrigin2,newRadius,(level-1)); // make recursion of right circle
}// end if
} // end drawRCircles
}// end class
Your code is drawing 11 circles but your call(s) to the drawRCircles itself is responsible for only 10 of them.
More specifically, these lines are drawing 1 circle.
// draw main circle
graphics.setColor(Color.WHITE);
graphics.drawOval(xOrigin, yOrigin, n, n);
This circle gets drawn regardless of whether or not you even have a drawRCircles function. (Try removing it and running your code to see what happens.)
Then, your code calls the drawRCircles function 11 times, but only draws 10 circles since the last call to it, with level = 0 fails the test if(level > 0).
the Image it creates goes down so far that I can not count the circles :/
A quick tip: since you want to know if, given max level of N, will it draw N or N+1 levels of circles, you could also just try changing your level variable to something more manageable (like 2) and checking it visually.
Going back to your code above, and ignoring the draw main circle portion (since it's independent of your recursive circle drawing) you have
drawRCircles(graphics,xOrigin,yOrigin,radius,level); // call recursive method
System.out.println(level);
and within your public void drawRCircles(…) function,
drawRCircles(…,level-1);
Let's check it with level = 2 instead of 10:
drawRCircles(…, 2)
--> Check if 1 > 0.
--> Yes, 1 > 0 so drawRCircles(…, 1)
--> Check if 0 > 0.
--> No, 0 = 0, so stop.
Number of levels = 2 = number of recursive circles drawn.
Related
I am trying to recreate the snake game, right now i am stuck on adding a new section to the snake everything it collides with an apple
I tried to tell the program to draw a new rectangle but with the x axis slightly shifted and this "shifting" would slowly increase every time my snake eats an apple. My snake starts off with 2 sections, and when i move the snake towards the green apple, it only moves the second section instead of drawing a new one, I know i didn't tell my draw method to draw a new rectangle every time my snake eats an apple since i have no clue on how to do that
public void draw(PApplet p) {
// clear area
p.fill(255, 0, 0);
// draw snake head
p.rect(x, y, length, width);
// draw snake body ?
if (upIsDown == true ) {
p.rect(x, y - section, length, width);
} else if(downIsDown == true) {
p.rect(x, y + section, length, width);
} else if(RightIsDown == true) {
p.rect(x - section, y, length, width);
} else if(LeftIsDown == true) {
RightIsDown = false;
p.rect(x + section, y, length, width);
}
}
the section variable increases by 10 in my checkCollision method
The snake gets longer, but my program only draws the head and the tail of the snake
I added comments to your code.
You code in draw clears the whole game area, then draws 2 rectangles. If you want to see 3 rectanges, you will need to call p.rect() 3 times in that method. If you want to see 10 rectanges, you will need to call it 10 times (so maybe a loop would be good). Else reconsider the call to p.fill() in the beginning.
For a loop, you would need to store the coordinates for each body segment in a structure like a LinkedList, with the coordinates for each segment, and in the draw method draw all segments.
So my ultimate goal is to draw 50 circles(with processing.core.PApplet) structured around a ring that transitions colors like a neon sign so that it would look like Psychadelics
The circles have to be random sizes and with a diameter of under 210 pixels the circles have to have 8 bars with each "shells" changing colors in order, and at the center, there must be an empty circle with the same color as the background.
Right now I am trying to break this problem into lots of small problems, and currently, I am struggling to make the spaces between the bars to be equally spaced.
Culprit:
(I found the problem to be the ratio between the bar size and the circle size, due to the undefined range random sizing it made seemingly empty circles)
Here is my next problem, The circles seem to be vibrating instead of remaining static, I want the 50 circles to be static while the colors on each shell change each frame.
Here is the part where I tell it to draw smaller and smaller circles
This is the "Drawing component"
public Donut(float x, float y , float d) { //constructor
this.x =x;
this.y =y;
diameter=d;
}
public void draw(PApplet p) {
p.circle(x, y, diameter);
float bar=(float)(Math.random()*(1-10)-1)+1;
for(int i =0; i<8; i++) {
bar+=10;
p.fill(REDS[i],GREENS[i],BLUES[i]);
p.circle(x, y, diameter-bar);
}
}
And here is the part where I tell it to have random sizes and positions(still haven't told it to be placed around a ring yet) //This is the Main Class
public class Psychadelics extends PApplet{
Donut [] DonutList = new Donut [50];
public static void main(String[] args) {
PApplet.main("test.Psychadelics");
}
public void settings() {
size(SCR_W, SCR_H);
}
public void setup() {
for(int i =0; i<DonutList.length;i++) {
float x = (float)(Math.random()*600);
float y = (float)(Math.random()*400);
float diameter = (float)(Math.random()*210);
DonutList [i]= new Donut(x,y,diameter);
}
I have another drawing method inside the main class to tell the Donut class to keep drawing and to keep updating it.
I expect each circle to remain static and to transition colors, each frame but my actual results were the circles each with different colors on each shell vibrating on their specified coordinates
The vibration is caused by float bar=(float)(Math.random()*(1-10)-1)+1;. Because bar is determined inside the draw function, the exact diameter will be slightly different on each frame. Instead, you should create an array of these random floats in the constructor and use random_diameter[i] in the draw loop, so the sizes of the inner circles are created random, but remain constant.
The color remaining constant is caused by p.fill(REDS[i],GREENS[i],BLUES[i]);. You assign specific colors, based on the index, to a circle that is also based on the index. This is where you should use random. For red, green and blue use int(Math.random(0,255));. That way, on each frame, a random color is generated for each circle. If you want more gradual color changes, you'll need to store the color for each circle and add/subtract a small random number. If you want to limit the number of colors, you can use the function you have now, but instead of i, use a random number with the size of the array.
I hope you see that, interestingly, the problems/solutions are each others inverse :)
just to preface, I am very new to java. So expect dumb mistakes.
I am trying to do a project with java's drawing panel, within BlueJ, and I cannot figure out how to make a program that has a moving object. This is a project, so the code is provided. We are having to modify it in whatever way we want. We are not able to add any other packages.
I know it has to do with some sort of loop, but I am making some type of mistake where it is just printing a ton of circles, instead of a new type every time I press refresh. Here is the code.
import java.awt.*;
import javax.swing.*;
public class DrawingPanel extends JPanel {
public void paintComponent(Graphics g)
{
// clear screen
g.setColor(Color.white);
g.clearRect(0,0,500,500);
{
System.out.printf("Spring Design Barker Spring 2018%n");
int x = 125;
int y = 125;
int w = 50;
int h =80;
int b = 50;
int rd = 255 ;
int gn = 255 ;
int bl = 0 ;
Circle c1,c2;
Rectangle r1,r2;
Triangle t1,t2;
Color clr1,c;
clr1 = new Color(rd,gn,bl);
r1 = new Rectangle(x,y,w,h,clr1);
clr1 = new Color(106,96,200);
t1=new Triangle(x,y,w,h,clr1);
clr1 = new Color(220,15,15);
c1=new Circle(x,25,25,clr1);
r1.draw(g); /*display the rectangle */
t1.draw(g); /*display the triangle */
c1.draw(g); /*display the circle */
t1.setH(-h); /*display the triangle */
t1.setColor(new Color(15,220,15)); /*display the triangle */
t1.draw(g); /*display the triangle */
x=200;
y=200;
for(int k=0;k<9;k++)
{
c=new Color(255-k*20,0+k*15,0+k*25); // vary color
c1=new Circle(200,10 * k,50,c);
c1.draw(g); /*display the new circle */
}
//c=new Color(0,255,0); // change paint in can to green
//c2=new Circle(300,50,10,c);
//c2.draw(g); /*display the new circle */
}
}
}
The mistake is that you are drawing the circle again and again. Every time the code in the loop runs a new circle is drawn. You have to understand that when you draw the circle you are not actually redrawing the same circle but drawing a new circle. What I understand you want to do is to make a circle moving. You can do that by running this whole method again and again. The way I prefer to do this is by using the Swing Timer. It is a way to run a loop calling the paintComponent() method in simple words.
I am actually working on something and I am using this library to display graphics. The only thing I don't like about that is that it uses a lot of CPU. Maybe there is better way to do this.
I'm porting a class that that was previously done in Swing to JavaFX 8. It displays a UI element that looks like an analog electric voltage meter with a half circle surrounded by a collection of "tic marks" at regular intervals. In the Swing version the class was an extension of JPanel and the tic marks were drawn in paintComponent(Graphics g) as follows:
private Line2D ticLine = new Line2D.Float(0, LINE_ROOT_Y, TIC_LENGTH, LINE_ROOT_Y);
public void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
// Draw tic marks
if (ticCount > 0)
{
g2.draw(ticLine); // First tic
AffineTransform ticTrans = new AffineTransform();
// Draw all additional tics rotated around half circle
for (int i = 1; i < ticCount; i++)
{
ticTrans.rotate(Math.toRadians(ticGap),
METER_MIDDLE, METER_BASE_Y);
g2.draw(ticTrans.createTransformedShape(ticLine));
}
}
}
This worked fine.
Now with JavaFX I'm using a class extending VBox. It contains 2 stacked Canvas objects. One of which will draw the static elements like the half circle and tic marks, and the other for the regularly moving meter line. On that first Canvas I was hoping to use a similar loop as I did in the Swing version to easily redraw the first tic mark in a ticCount # of additional positions around the half circle. So I tried the following which compiled and ran but only drew that first tic mark:
// Called from the constructor:
MeterGC = MeterCanvas.getGraphicsContext2D();
Line ticLine = new Line(0, LINE_ROOT_Y, TIC_LENGTH, LINE_ROOT_Y);
// Draw tic marks
if (ticCount > 1)
{
MeterGC.setStroke(Color.GRAY);
MeterGC.setLineWidth(BASIC_LINE_WIDTH);
MeterGC.strokeLine(ticLine.getStartX(), ticLine.getStartY(),
ticLine.getEndX(), ticLine.getEndY());
Rotate ticTrans = new Rotate(Math.toRadians(ticGap), METER_MIDDLE, METER_BASE_Y);
for (int i = 1; i < ticCount; i++)
{
ticLine.getTransforms().add(ticTrans);
MeterGC.strokeLine(ticLine.getStartX(), ticLine.getStartY(),
ticLine.getEndX(), ticLine.getEndY());
}
}
It may be that trying to Transform a Shape object like this only works when drawing to a scene and not on a Canvas. Or that I have to do something after the "ticLine.getTransforms().add(ticTrans)" line to get them to apply to the line. Am I at least close? Or is there a much better way to do what I'm trying here?
What you are doing wrong
In your sample code you are applying the transform to a Line object (which you never display).
How to fix it
You need to set the transform on the canvas GraphicsContext before you stroke the line on the canvas.
Sample code
For an example, see:
How to draw image rotated on JavaFX Canvas?
/**
* Sets the transform for the GraphicsContext to rotate around a pivot point.
*
* #param gc the graphics context the transform to applied to.
* #param angle the angle of rotation.
* #param px the x pivot co-ordinate for the rotation (in canvas co-ordinates).
* #param py the y pivot co-ordinate for the rotation (in canvas co-ordinates).
*/
private void rotate(GraphicsContext gc, double angle, double px, double py) {
Rotate r = new Rotate(angle, px, py);
gc.setTransform(r.getMxx(), r.getMyx(), r.getMxy(), r.getMyy(), r.getTx(), r.getTy());
}
This is my revised for-loop and it works perfectly. Noticing that converting the angle in Rotate to radians is no longer necessary in JavaFX was also key in getting it to work.
for (int i = 1; i < ticCount; i++)
{
Rotate ticTrans = new Rotate(ticGap * i, METER_MIDDLE, METER_BASE_Y);
MeterGC.setTransform(ticTrans.getMxx(), ticTrans.getMyx(), ticTrans.getMxy(),
ticTrans.getMyy(), ticTrans.getTx(), ticTrans.getTy());
MeterGC.strokeLine(ticLine.getStartX(), ticLine.getStartY(),
ticLine.getEndX(), ticLine.getEndY());
}
I'll be candid about this; it is a homework assignment, but can someone guide me in the right direction and explain to me how some parts of the code are supposed to work? The directions are below the code and the questions.
This is my code so far:
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Container;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Rainbow extends JPanel
{
// Declare skyColor:
private final Color skyColor = Color.CYAN;
public Rainbow()
{
setBackground(skyColor);
}
// Draws the rainbow.
public void paintComponent(Graphics g)
{
super.paintComponent(g);
int width = getWidth();
int height = getHeight();
// Declare and initialize local int variables xCenter, yCenter
// that represent the center of the rainbow rings:
int xCenter = width/2;
int yCenter = (height * 3) /4;
// Declare and initialize the radius of the large semicircle:
int largeRadius = width/4;
g.setColor(Color.RED);
// Draw the large semicircle:
g.fillArc(xCenter,yCenter,largeRadius,height,0,180);
// Declare and initialize the radii of the small and medium
// semicircles and draw them:
int smallRadius = height/4;
g.setColor(Color.MAGENTA);
g.fillArc(xCenter,yCenter,width,height,0,180);
int mediumRadius = (int) Math.sqrt(smallRadius * largeRadius);
g.setColor(Color.GREEN);
g.fillArc(xCenter,yCenter,width,height,0,180);
// Calculate the radius of the innermost (sky-color) semicircle
// so that the width of the middle (green) ring is the
// arithmetic mean of the widths of the red and magenta rings:
// Draw the sky-color semicircle:
g.fillArc(xCenter,yCenter,width,height,0,180);
}
public static void main(String[] args)
{
JFrame w = new JFrame("Rainbow");
w.setBounds(300, 300, 300, 200);
w.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container c = w.getContentPane();
c.add(new Rainbow());
w.setVisible(true);
}
}
My questions: How exactly does fillArc work; I understand what goes in the parameter, but what must one do so each arc differs from one another?
How does one set one color for each arc? I tried doing so, and I ended up with the color listed closest the end showing up and overriding the others.
I'll probably have more as a I continue to code.
These were the directions:
![enter image description here][1]
The “rainbow” is made of four overlapping semicircles. The outer ring is red (Color.RED), the middle one is green (Color.GREEN), and the inner ring has the magenta color (Color.MAGENTA). The innermost semicircle has the same color as the background.
Follow the instructions below and fill in the blanks in Rainbow.java.
Start the Rainbow project.
Add a complete comment header with your name before the class declaration at the top of the file.
Add to the Rainbow class a declaration of a private final field skyColor of the type Color, initialized to Color.CYAN (the color of the sky). In Rainbow’s constructor, set the window’s background to skyColor rather than Color.WHITE.
In the paint method, declare local integer variables xCenter and yCenter that represent the coordinates of the center of the rings. Initialize them to 1/2 width and 3/4 height (down) of the content pane, respectively. (Recall that the origin of graphics coordinates in Java is at the upper left corner of the content pane with the y-axis pointing down.) Do not plug in fixed numbers from the window’s dimensions.
Declare a local variable largeRadius that represents the radius of the largest (red) semicircle and initialize it to 1/4 of width.
A method call g.fillArc(x, y, size, size, from, degrees) (with all integer arguments) draws a sector of a circle. x and y are the coordinates of the upper left corner of the rectangle (in this case a square) into which the oval is (logically) inscribed; size is the side of the square (and the diameter of the circle); from is the starting point of the arc in degrees (with 0 at the easternmost point of the horizontal diameter), and degrees (a positive number) is the measure of the arc, going counterclockwise. Add a statement to the paint method to draw the largest (red) semicircle. Test your program.
Add statements to display the medium (green) and small (magenta) semicircles. The radius of the magenta semicircle should be 1/4 of height. The radius of the green one should be the geometric mean (the square root of the product) of the radius of the red semicircle and the radius of the magenta semicircle, rounded to the nearest integer. (A call to Math.sqrt(x) returns the value of square root of x, a double.) Retest your program.
Add statements to display the innermost semicircle of the background (“sky”) color to complete the rainbow. Use the skyColor constant for this semicircle’s color. Choose the radius of the sky-color semicircle in such a way that the width of the middle (green) ring is the arithmetic mean of the widths of the red and magenta rings.
Test your program.
Submit your completed program and run output. Your run output (the rainbow picture) can be included by capturing the screen output (Alt-PrintScrn), pasting it into a graphics program (such as MS Paint) and then saving the image to your Eclipse project directory.
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Container;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Rainbow extends JPanel
{
//Declare skyColor:
private final Color skyColor = Color.CYAN;
public Rainbow()
{
setBackground(skyColor);
}
// Draws the rainbow.
public void paintComponent(Graphics g)
{
super.paintComponent(g);
int width = getWidth();
int height = getHeight();
// Declare and initialize local int variables xCenter, yCenter
// that represent the center of the rainbow rings:
int xCenter = width/2;
int yCenter = (height * 3) /4;
// Declare and initialize the radius of the large semicircle:
int largeRadius = width/4;
g.setColor(Color.RED);
// Draw the large semicircle:
g.fillArc(xCenter - largeRadius,yCenter - largeRadius ,largeRadius,largeRadius,0,180);
// Declare and initialize the radii of the small and medium
//semicircles and draw them:
int smallRadius = height/4;
int mediumRadius = (int) Math.sqrt(smallRadius * largeRadius);
g.setColor(Color.GREEN);
g.fillArc(xCenter-(largeRadius+mediumRadius)/2,yCenter- (largeRadius+mediumRadius)/2,mediumRadius,mediumRadius,0,180);
g.setColor(Color.MAGENTA);
g.fillArc(xCenter-(largeRadius+smallRadius)/2,yCenter-(largeRadius+smallRadius)/2,smallRadius,smallRadius,0,180);
// Calculate the radius of the innermost (sky-color) semicircle
// so that the width of the middle (green) ring is the
// arithmetic mean of the widths of the red and magenta rings:
int skyRadius = (int)((2 * Math.sqrt(smallRadius * largeRadius)) - width/4);
// Draw the sky-color semicircle:
g.setColor(skyColor);
g.fillArc(xCenter-skyRadius,yCenter-skyRadius,skyRadius,skyRadius,0,180);
}
public static void main(String[] args)
{
JFrame w = new JFrame("Rainbow");
w.setBounds(300, 300, 300, 200);
w.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container c = w.getContentPane();
c.add(new Rainbow());
w.setVisible(true);
}
}
fillArc() fills in a section of the circle based upon the parameters you gave it. For example your first arc.
You're drawing the fill arc, which in this case is a semi-circle, of the color red.
//Set the arc color
g.setColor(Color.RED);
// Draw the large semicircle:
g.fillArc(xCenter,yCenter,largeRadius,height,0,180);
There's our fillArc. That doesn't look anything like a rainbow. In order to get the rainbow shape, we have to draw a smaller arc inside of it. In your case the next one is green. So we do fillArc again after setting the color to green. But we shrunk the radius a little bit so the green doesn't cover the entire red section.
Keep in mind when we draw, we're drawing on top, so if you drew the green on first it would be covered by the red one.
Then we draw another arc inside this once more, but make this one the color of the sky (white in this case). This creates the final rainbow shape. So we do fillArc again, but with a slightly smaller radius and the color white.
And there, we drew a rainbow.
To center this beautiful creation, we have to understand a few things about the fillArc function.
The parameters are:
public abstract void fillArc(int x,
int y,
int width,
int height,
int startAngle,
int arcAngle)
int x and int y represent the coordinates for the upper left hand corner of the arc that you are drawing. The reason your code isn't centering is because of how you're drawing the arc.
g.fillArc(xCenter - largeRadius,yCenter - largeRadius,largeRadius,largeRadius,0,180);
g.fillArc(xCenter-(largeRadius+mediumRadius)/2,yCenter-(largeRadius+mediumRadius)/2,mediumRadius,mediumRadius,0,180);
g.fillArc(xCenter-(largeRadius+smallRadius)/2,yCenter-(largeRadius+smallRadius)/2,smallRadius,smallRadius,0,180);
I took out a few of the excess stuff. You see how you're subtracting the (largeRadius+smallRadius)/2 and (largeRadius+mediumRadius)/2? This is shifting the rainbow to make it off center. What you should have is instead:
g.fillArc(xCenter - largeRadius/2,yCenter - largeRadius,largeRadius,largeRadius,0,180);
g.fillArc(xCenter-(mediumRadius)/2,yCenter-(largeRadius+mediumRadius)/2,mediumRadius,mediumRadius,0,180);
g.fillArc(xCenter-(smallRadius)/2,yCenter-(largeRadius+smallRadius)/2,smallRadius,smallRadius,0,180);
This will properly center the rainbow. Here's why.
That's the point where they will start the drawing the arc from. If you want to center the entire rainbow, you'd shift it over by half of it's entire width. So if you want to center the red arc, you'd do
xCenter - (largeRadius/2)
As this is setting the x start to the left by half. You wouldn't include largeRadius in the other arcs, as you're centering them around this point. Thus you'd want to shift them over by half of their individual widths, which is why their x positions are
xCenter-(mediumRadius)/2
xCenter-(smallRadius)/2
Centering on the Y-axis works differently. You have to consider that the height of the rainbow overall is 1/4 the largeRadius. Your code uses yCenter = 3/4 * height, so that changes it a bit.
This is my solution
g.fillArc(xCenter - largeRadius/2,yCenter - largeRadius/2 + largeRadius/4 -height/4,largeRadius,largeRadius,0,180);
g.fillArc(xCenter-(mediumRadius)/2,yCenter-(mediumRadius)/2 + largeRadius/4 -height/4,mediumRadius,mediumRadius,0,180);
g.fillArc(xCenter-(smallRadius)/2,yCenter-(smallRadius)/2 + largeRadius/4 -height/4,smallRadius,smallRadius,0,180);
Let's take a look. I subtracted the largeRadius/2 (and respective radiuses) for the same principle as in x. But then I added largeRadius/4 because we have to shift the entire rainbow down. This is because subtracting the respective radius/2 only centers the rainbow as if it were an entire circle, not semi-circles.
Adding largeRadius/4 shifts the rainbow down by overall half of it's height, centering it correctly for a semi-circle. Finally, subtracting height/4 makes changes the yCenter to height/2, since 3/4 * height is a requirement in your assignment.
Sorry about all the problems in the comments, hope this cleared it up.
I've modified part of your code so you could get an idea. Remember that your xCenter and yCenter represent the center of your circle, not the coordinates you need to use in the fillArc method. The instructions you provided explain it pretty well. You can get an idea from what I did here and figure the rest by yourself.
// First declare and initialize all radiuses
int largeRadius = width/4;
int smallRadius = height/4;
int mediumRadius = (int) Math.sqrt(smallRadius * largeRadius);
//Then draw each arc in descending order from the largest one
g.setColor(Color.RED);
g.fillArc(xCenter-largeRadius,yCenter-largeRadius,largeRadius,largeRadius,0,180);
g.setColor(Color.GREEN);
g.fillArc(xCenter-(largeRadius+mediumRadius)/2,yCenter-(largeRadius+mediumRadius)/2,mediumRadius,mediumRadius,0,180);
g.setColor(Color.MAGENTA);
g.fillArc(xCenter-(largeRadius+smallRadius)/2,yCenter-(largeRadius+smallRadius)/2,smallRadius,smallRadius,0,180);
// Calculate the radius of the innermost (sky-color) semicircle
For you skyRadius consider:
Red width = large radius - medium radius
green width = medium - small
magenta width = small radius - skyradius
if I did the math rightyou get: skyRadius = smallRadius - 2*(mediumRadius-smallRadius)+largeRadius-mediumRadius
int skRadius=smallRadius-2*(mediumRadius-smallRadius)+largeRadius-mediumRadius;
g.setColor(skyColor);
g.fillArc(xCenter-(largeRadius+skRadius)/2,yCenter-(largeRadius+skRadius)/2,skRadius,skRadius,0,180);
A much simpler equation for skyRadius is:
int skyRadius = largeRadius - 3 * mediumRadius + 3 * smallRadius;