How to rotate an asterisk trapezoid in java? - java

In a school assignment we have to draw a trapezoid with asterisk in java. The constructor is like
Trapezoid(int tWidth, int bWidth, char signA, char signB, int margin)
tWidth: is the top width, bWidth: bottom width, signA: foreground sign, signB: background sign and margin: the margin (left and right) of the bWidth.
my main() class looks like this:
Trapezoid t = new Trapezoid(3, 9, '*', '-', 2);
t.printTrapezoid();
then it should look like this:
-----***-----
----*****----
---*******---
--*********--
the printTrapezoid() method looks like this:
int width = 2* margin + bWidth;
int length = (width - tWidth) / 2;
while (tWidth <= bWidth) {
printChar(signB, length);
printChar(signA, tWidth);
printChar(signB, length);
System.out.println();
tWidth++;
}
The printChar() method looks like:
printChar(char signB, int length) {
for (int i = 0; i < length; i++) {
System.out.print(signB);
}
}
So. This works fine for me. But i think there are some other and better solutions for that. The next exercise is to rotate this trapezoid just with t.rotate() in the main() class. So that it looks like:
--*********--
---*******---
----*****----
-----***-----
I have no idea how to do it. Can anybody give me a hint?
Please, I don't want the solution here. Just a hint how i can solve it. Maybe it is better to refactor the draw method? I don't know...

You haven't shown us the whole Trapezoid class, but I'm guessing that it has a field tWidth that you set in your constructor.
If that's the case, your printTrapezoid method shouldn't be changing it. That field, the "top width", is a property of the trapezoid that shouldn't change when you print it out. So in printTrapezoid, you should declare a local variable that's something like
int currentWidth = tWidth;
and then the method should modify this local variable, not the tWidth field.
Once you've done that, it should be very simple to see how to print the upside-down trapezoid, by making currentWidth become the same values in the reverse order.
EDIT: If rotate is supposed to change the properties of the trapezoid, rather than printing an upside-down trapezoid, then that should be easy too since you've fixed printTrapezoid not to change tWidth and bWidth, so now you can do what you need to do to change them (by swapping the values).

Related

Does Java Swing limit how many items it will draw?

I'm writing a recursive method in Java that creates essentially creates a circle tree. It draws a circle at the top and center and then the method gets called again and creates the circles one level lower on the y axis and half way to the left and right of the new circle. I was successful but only for a certain number of objects to be drawn This is what it looks like
public void test(Graphics g, int y, int num, double instance) {
if(num<50) {
int r = 20;
for(int i=1;i<=instance;i++) {
if(i%2==1) {
g.fillOval(getWidth() * i / num, y, r, r);
}
}
if(instance==1){
instance= 2* instance;
}
test(g, y + 20, num * 2, Math.pow(instance,2.0));
}
Everything works perfectly until I try to increase the number in "if(num<50)" to exactly "if(num<65)". When I change that the JFrame appears but now it is empty and it seems like the program is frozen. I want to increase that so that I can fill the Jframe with the circle tree. Why is it doing that? Looking forward to your response! Thank you!
I found the issue. I don't know why I choose to use Math power when I only had to use *2 and that fixed the whole program.

Trying to get multiple images out of a single image

I've been stuck at something recently.
What I want to do is to get multiple sub-images out of 1 big image.
So take this example. I have a frame of 128x128 pixels where all the images need to be in.
I'm putting all the bufferedImages inside a list and scaling all those images to 128x128.
The image you see on that link is showing that I need 4 sub-images from that image, so at the end, I have 4 images which are 128x128 but 4 times.
Or if you have an image with 128x384 it will give 3 sub-images going from top to bottom.
https://i.stack.imgur.com/RsCkf.png
I know there is a function called
BufferedImage.getSubimage(int x, int y, int w, int h);
But the problem is that I can't figure out what math I need to implement.
What I tried is if the height or width is higher than 200 then divide it by 2 but that never worked for me.
I'm not sure I fully understand what you are asking, but I think what you want is something like this:
First, loop over the image in both dimensions.
Then compute the size of the tile (the smaller value of 128 and (image dimension - start pos)). This is to make sure you don't try to fetch a tile out of bounds. If your images are always a multiple of 128 in any dimension, you could just skip this step and just use 128 (just make sure you validate that input images follow this assumption).
If you only want tiles of exactly 128x128, you could also just skip the remainder, if the tile is less than 128x128, I'm not sure what your requirement is here. Anyway, I'll leave that to you. :-)
Finally, get the subimage of that size and coordinates and store in the list.
Code:
BufferedImage image = ...;
int tileSize = 128;
List<BufferedImage> tiles = new ArrayList<>();
for (int y = 0; y < image.height(); y += tileSize) {
int h = Math.min(tileSize, image.height() - y);
for (int x = 0; x < image.width(); x += tileSize) {
int w = Math.min(tileSize, image.width() - x);
tiles .add(image.getSubimage(x, y, w, h));
}
}

Recursive methods Java

Recursion always has been something I have a hard time with. I have a test tomorrow and he said there will be some Recursion on the test so I want to be prepared.
The problem I am trying to do says this:
Given a class Rectangle with instance variables width and height, provide a recursive getArea() method. Construct a rectangle whose width is one less than the original and call its getArea method.
So I know that in recursion you end up calling the method inside itself with a simplified rendition. Like, I know somewhere in getArea(int n) I will have to call getArea(n - 1). I am just not sure what to do with width and height.
So I have this:
public int getArea()
{
if (width == 1) {
// Base case here. Not sure what to do for this.
return 1; // Maybe? I'm not sure.
} else {
Rectangle smallerRect = new Rectangle (width - 1);
int smallerArea = smallerRect.getArea();
return smallerArea + height + width;
}
}
Can anyone help me better understand recursion or maybe how to go about thinking through a recursive function? Thanks.
You've got the recursion itself right, with a base case and a recursive case, and a correct reduction of the parameter in the recursive call (except that, as the commenters have noted, you also need to specify the height of the new rectangle). It's only the geometry that needs fixing: height doesn't change during the recursion; what is the area of the base case rectangle, which has got width 1 and height height? And if you are told the area of the rectangle with width width - 1 and height height, how much extra area do you get by adding a strip of width 1 and height height?
For later use: while mathematically correct, this is a terrible way to compute the area of a rectangle, so please don't do this outside of exam/homework situations :-)
Something like this perhaps? It's basically just multiplying width by height with recursion...
public int getArea() {
return getArea(width);
}
private int getArea(int x) {
return x == 0 ? 0 : height + getArea(x-1);
}
public int getArea()
{
if (width == 1) {
// Base case
return height; // Area = width(1)*height
} else {
Rectangle smallerRect = new Rectangle (width - 1, height);
int smallerArea = smallerRect.getArea();
return smallerArea + height;
}
}

Trying to rotate a polygon using math

I have a school assignment where I'm supposed to (among other things) rotate a polygon. I can not use any premade rotate functions, so I have an array of points. The array is set up like this:
intArray[2][amount_of_points] where intArray[0] equals the points x coordinate, and intArray[1] holds the y coordinates.
//x=pivot point x coordinate, y = pivot point y coordinate.
public int[][] rotate(int[][]matrix,int x, int y, double degrees){
double s=Math.sin(degrees);
double c=Math.cos(degrees);
for (int i=0;i<matrix.length;i++){
//translate to origin
int px=matrix[0][i]-x;
int py=matrix[1][i]-y;
//rotate
double xnew = (px*c)-(py*s);
double ynew = (px*s)+(py*c);
//translate back
px=(int)((xnew+x)+0.5);
py=(int)((ynew+y)+0.5);
matrix[0][i]=px;
matrix[1][i]=py;
}
This is my code so far, and it is definitely not working out for me. I tried to trim the code as much as I could. Any help would mean a lot!
edit: I'm not getting any errors when I run the code, no exceptions etc. The only problem is that the polygon isn't rotating the way I intend it to.
I've made a test polygon:
polyArray = new int [2][3];
polyArray[0][0]=400;
polyArray[1][0]=200;
polyArray[0][1]=300;
polyArray[1][1]=500;
polyArray[0][2]=500;
polyArray[1][2]=500;
Which I draw in a JPanel, then I run this array through the rotation method like this:
polyArray=mm.rotate(polyArray, polyArray[0][0], polyArray[1][0], Math.PI);
Using the top point as pivotpoint. The whole polygon is then deformed.
Although still not very clear on question, I feel your problem is with the loop.
matrix.length is 2. So, the code never uses these :
polyArray[0][2]=500;
polyArray[1][2]=500;
If you change the condition as below, it should work :
for (int i=0;i<matrix[0].length;i++)

Check if rectangle contains another rectangle with specific distance between borders

I am trying to write small program to check if one rectangle contains second rectangle and distance betwwen their borders should be less than some specific number like 100 or 50.
When I use Rectangle.contains method it doesnt care about about distnce between borders of both rectangle.
Is there any way this can be achieved?
You could use the contains(Rectancle r) method twice: first to check if the inner rectangle is inside the outer rectangle at all, then temporarily enlarge the inner rectangle by half the threshold into every direction and make the same check again. This time it shouldn't be inside the outer rectangle anymore. So basically something like this:
//Rectangle outer; // Do some proper setup for these two
//Rectangle inner;
int limit = 50;
boolean containsWithinLimits = outer.contains(inner);
inner.setLocation(inner.getX()-limit/2, inner.getY()-limit/2);
inner.setSize(inner.getWidth()+limit, inner.getHeight()+limit);
boolean containsWithinLimits = containsWithinLimits && !outer.contains(inner);
// Now reset the bounds:
inner.setLocation(inner.getX()+limit/2, inner.getY()+limit/2);
inner.setSize(inner.getWidth()-limit, inner.getHeight()-limit);
example code etc?
Even so, you'll want to do the following:
unless im mistaken.
pseudo code:
rectA = outside, rectB = inside
if rectB.left - rectA.left < x then distance is ok else do something
if rectB.top - rectA.top < y then distance is ok else do something
etc etc
If the rectangles are orthogonal, and I assume that you have called contains(Rectangle rect). Then you only have to do extra comparisons:
inside.x - outside.x >= LEFT_BORDER &&
outside.x + outside.width - inside.x - inside.width >= RIGHT_BORDER &&
inside.y - outside.y >= TOP_BORDER &&
outside.y + outside.height - inside.y - inside.height >= BOTTOM_BORDER
LEFT_BORDER, RIGHT_BORDER, TOP_BORDER, BOTTOM_BORDER are for you to define.
In Rectangle2d ,we are having
boolean contains(double x, double y)
--- Tests if a specified coordinate is inside the boundary of this Rectangle2D.
boolean contains(double x, double y, double w, double h)
--- Tests if the interior of this Rectangle2D entirely contains the specified set of rectangular coordinates.
So it is not possible to check about the distance to my knowledge...

Categories

Resources