Dividing a range up evenly, allowing for spaces and margins - java

I have a point array and a panel. getWidth() is based off the panel. Imagine cards in your hand, so HAND_CARD_WIDTH is pretty self explanatory. The purpose of this loop is to set the points evenly across the panel, which it does. However, it allow the cards to go out of the panel, which makes it look very bad. What I want to do is give a small empty margin on both sides of the panel no matter how many cards you have in your hand.
Here's the code
int iteration = 1;
int limiter = getWidth();
int slice = (limiter/(handsize+1));
while (points.size() < handsize) {
int x = slice*(iteration++);
x -= HAND_CARD_WIDTH/2;
points.add(new Point(x, y));
}
Basically I want the leftmost x to be at least 20 and the rightmost to be at most getWidth() - 20 - HAND_CARD_WIDTH. I also want the cards to be evenly spaced... I just can't think of the right equation (getting to this point was sadly a feat..).
Thanks, based on the responses (all 2 of them) heres what I went with:
if((int)points.get(0).getX() < margin){
int boost = Math.abs(margin - (int)points.get(0).getX());
slice = (boost*2)/handsize;
for(Point p : points){
p.x += boost;
boost -= slice;
}
}

Not sure if I understand your layout, but I think it is something like this:
|margin|space|card|space|card|space|margin|
or
|margin|space|card|space|margin|
So, the number of spaces is one more than number of cards and the total width is component width minus margins. componentWidth = numCards x cardWidth + (numCards + 1) x spaceWidth Now it is easy to calculate the space needed which is (componentWidth - numCards x cardWidth) / (numCards + 1) so the left position of a card is leftMargin + spaceWidth x cardNum + cardWidth x (cardNum - 1)
Care must be taken when the space is negative, then you instead must calculate how much the cards must overlap.

Try this:
final int MARGIN = 20;
int availableWidth = getWidth() - 2 * MARGIN - HAND_CARD_WIDTH;
int cardSpaceWidth = availableWidth / handsize;
for (int i = 0; i < handsize; i++) {
int x = MARGIN + ((i + 0.5) * cardSpaceWidth) - HAND_CARD_WIDTH / 2;
points.add(new Point(x, y));
}
So:
calculate the available width by subtracting the margins from total panel width
calculate the space for each card by dividing remaining space by number of cards
for each card, we count its leftmost point by taking the middle of card space and subtracting half the width of the card.
Mind you, with this solution cards still can overlap margins, if HAND_CARD_WIDTH is greater than available space for card.

Related

Java Program to calculate how many bounces it will take a ball to drop in 5% decrements. User will initially input the heigh

So I have to write a short Java program which will input of the height a ball is dropped from. Assuming that on each bounce the height reached reduces by 5%, output the number of bounces that occur before
the ball stops bouncing.
I understand the logic of how to work this out but I cannot grasp how to put this into code.
I have some unfinished code, but just hit a brick wall. Any suggestions would be greatly appreciated.
package doWhileLoops;
import java.util.Scanner;
public class Ex3 {
public static void main(String[] args) {
Scanner key = new Scanner(System.in);
int height = 0, noBounces = 0, fivePer = 0;
fivePer = height /100 * 5;
System.out.print("\n\tEnter the height in feet that the ball will be dropped from: ");
height = key.nextInt();
do {
System.out.print("\n\tIt took " + (height - fivePer));
fivePer--;
} while (height > 0);
}
}
To get a feel of the algorithm, I mocked the following in Javascript. The important parts of the algorithm are:
height reduction of 5% is implemented as h = h * 95 / 100
there needs to be a terminating condition, i.e. threshold
When you run the algorithm you see that counter reaches 77. Why is it so high? Well, this is attributed to the fact that (1) a height reduction of 5% is unrealistic, in practice, a figure of 50% is more realistic, (2) in practical physics, there is a drag that causes it to diminish faster and eventually rest. With zero resistance, theoretically, something could bounce forever - hence, it is important that the question is improved with a terminating condition.
To demonstrate the algorithm, I did write it in Javascript not Java, so that you can run it in the browser.
let h = 50; // initial height, say 50cm
let threshold = 1; // threshold height, say <= 1cm
let count = 0; // counter for bounces
while (h > threshold) {
h = h * 95 / 100; // 5% height reduction
count++;
console.log(count, h);
}
Instead of calculating the five percent of the height and subtracting at the end, you can just decrease the height by 5% everytime until it reaches 0.
What about
float height = key.nextInt();
int nBounces = 0;
while(height > 0){
height *= 95 / 100; //decrease the height by 5%
nBounces++; //add a bounce
}
System.out.print("\n\tIt took " + nBounces);
Hope that helps!

Making an Image Concave in Java

I had a quick question, and wondered if anyone had any ideas or libraries I could use for this. I am making a java game, and need to make 2d images concave. The problem is, 1: I don't know how to make an image concave. 2: I need the concave effect to be somewhat of a post process, think Oculus Rift. Everything is normal, but the camera of the player distorts the normal 2d images to look 3d. I am a Sophmore, so I don't know very complex math to accomplish this.
Thanks,
-Blue
If you're not using any 3D libraries or anything like that, just implement it as a simple 2D distortion. It doesn't have to be 100% mathematically correct as long as it looks OK. You can create a couple of arrays to store the distorted texture co-ordinates for your bitmap, which means you can pre-calculate the distortion once (which will be slow but only happens once) and then render multiple times using the pre-calculated values (which will be faster).
Here's a simple function using a power formula to generate a distortion field. There's nothing 3D about it, it just sucks in the center of the image to give a concave look:
int distortionU[][];
int distortionV[][];
public void computeDistortion(int width, int height)
{
// this will be really slow but you only have to call it once:
int halfWidth = width / 2;
int halfHeight = height / 2;
// work out the distance from the center in the corners:
double maxDistance = Math.sqrt((double)((halfWidth * halfWidth) + (halfHeight * halfHeight)));
// allocate arrays to store the distorted co-ordinates:
distortionU = new int[width][height];
distortionV = new int[width][height];
for(int y = 0; y < height; y++)
{
for(int x = 0; x < width; x++)
{
// work out the distortion at this pixel:
// find distance from the center:
int xDiff = x - halfWidth;
int yDiff = y - halfHeight;
double distance = Math.sqrt((double)((xDiff * xDiff) + (yDiff * yDiff)));
// distort the distance using a power function
double invDistance = 1.0 - (distance / maxDistance);
double distortedDistance = (1.0 - Math.pow(invDistance, 1.7)) * maxDistance;
distortedDistance *= 0.7; // zoom in a little bit to avoid gaps at the edges
// work out how much to multiply xDiff and yDiff by:
double distortionFactor = distortedDistance / distance;
xDiff = (int)((double)xDiff * distortionFactor);
yDiff = (int)((double)yDiff * distortionFactor);
// save the distorted co-ordinates
distortionU[x][y] = halfWidth + xDiff;
distortionV[x][y] = halfHeight + yDiff;
// clamp
if(distortionU[x][y] < 0)
distortionU[x][y] = 0;
if(distortionU[x][y] >= width)
distortionU[x][y] = width - 1;
if(distortionV[x][y] < 0)
distortionV[x][y] = 0;
if(distortionV[x][y] >= height)
distortionV[x][y] = height - 1;
}
}
}
Call it once passing the size of the bitmap that you want to distort. You can play around with the values or use a totally different formula to get the effect you want. Using an exponent less than one for the pow() function should give the image a convex look.
Then when you render your bitmap, or copy it to another bitmap, use the values in distortionU and distortionV to distort your bitmap, e.g.:
for(int y = 0; y < height; y++)
{
for(int x = 0; x < width; x++)
{
// int pixelColor = bitmap.getPixel(x, y); // gets undistorted value
int pixelColor = bitmap.getPixel(distortionU[x][y], distortionV[x][y]); // gets distorted value
canvas.drawPixel(x + offsetX, y + offsetY, pixelColor);
}
}
I don't know what your actual function for drawing a pixel to the canvas is called, the above is just pseudo-code.

Check if point is in circular sector

I found this question that deals with the same issue. The provided answers work, but I need to change it slightly for my case. Below is the answer I went with:
double theta = Math.atan2(pointerY - height / 2, pointerX - width / 2);
if(theta<0)
theta = Math.PI - theta;
int whichSlice = 0;
double sliceSize = Math.PI*2 / 4;
double sliceStart;
for(int i=1; i<=4; i++) {
sliceStart = i*sliceSize;
if(theta < sliceStart) {
whichSlice = i;
break;
}
}
In my case, I need to rotate the quadrants by 45 degrees. Below is an example; red is what this code does, while green is what I want:
I've tried various code alterations, but still can't figure it out.
EDIT:
First off, create your circle in it's own desperate JComponent, and add it's own listeners - basically create a class for this circle, make the circle itself receive mouse events, and MAKE SURE THAT THE CIRCLE OCCUPIES THE ENTIRE RECTANGLE OF THE JCOMPONENT - it must be touching all edges (I will be using this.getHeight() and this must return the height of the bounding box of the circle)!!!
Fixed code below to support such a case, in addition to support y axis which increases downwards:
Step 1:
Check if we are inside the circle.
Step 2:
Check if we are above/below the diagonal lines (note: equations for diagonal lines are y = x, and y = -x)
Point pointWeAreChecking;
Point centerOfCircle;
double radius;
if(Math.pow(Math.pow(pointWeAreChecking.x-centerOfCircle.x , 2) + Math.pow(pointWeAreChecking.y-centerOfCircle.y , 2), 0.5) <= radius)
{
//Means we are in circle.
if(pointWeAreChecking.y>pointWeAreChecking.x)
{
//Means it is either in 2 or 3 (it is below y = -x line)
if(pointWeAreChecking.y>-pointWeAreChecking.x + this.getHeight()){
//We are in 2.
}else
{
//We are in 3.
}
}else
{
if(pointWeAreChecking.y>-pointWeAreChecking.x + this.getHeight())
{
//We are in 4.
}else
{
//We are in 2.
}
}
}

drawing shapes on a grid

I need to draw random shapes on a grid such as lines squares etc. This part I'm able to do. My problem is the start and end point of the lines I'm drawing falls anywhere in a grid cell. I would like them to be only at intersection points. One cell in the grid is a 10x10 pixel grid. Do i have to write an algorithm to assign the pixel to its nearest intersection point on the grid or is there a easier way. I'm using a buffered image to draw the grid. Please Help. this is what i have so far
for (int i = 0; i < 61; i++) {
g2d.drawLine((imgDim.width + 2) / 40 * i, 0,
(imgDim.width + 2) / 40 * i, imgDim.height - 1);
g2d.drawLine(0, (imgDim.height + 2) / 60 * i,
imgDim.width - 1, (imgDim.height + 2) / 60 * i);
}
Thank you
How are you coming up with the random points? Making an adjustment there might be the easiest way. That is, just drop a 0 in the process you are using to come up with the points in the first place. Then when you are ready to draw it, add a 0 back.
Seriously? In order to make a random point (pixelX, pixelY) snap to the closest point of a grid.
int gridSize = 10;
int x = (pixelX + gridSize / 2) / gridSize * gridSize;
int y = (pixelY + gridSize / 2) / gridSize * gridSize;

Draw different shape of polygon randomly

My program draw 10 polygon triangles in random sizes (width and height). The coordinate (points) of the polygon were generated using Random generator = new Random(). Since the points of the triangle and the width and height were randomly generated, how can I control the number of sizes drawn? e.g. there are 10 polygon in total, but I wanted to limit the number of different sizes e.g. only 2 or 4 different sizes.
for(int i = 0; i < 10; i++) {
double xWidth = generator.nextDouble() * 50.0 + 20.0; // range width of triangle
double yHeight = generator.nextDouble() * 50.0 + 20.0; // range height of triangle
xCoord[0] = generator.nextInt(300);
yCoord[0] = generator.nextInt(300);
xCoord[1] = (int) (xCoord[0] - xWidth);
xCoord[2] = (int) (xCoord[1] + (xWidth/2));
yCoord[1] = yCoord[0];
yCoord[2] = (int) (yCoord[1] - yHeight);
triangles.add( new Polygon(xCoord,yCoord, 3));
}
Why not just randomly generate 4 shapes and then run a different loop to pick randomly from those four shapes.
This code only generates the tringles, there has to be a .draw() somewhere - you just wrap that in some sort of code that picks one to four triangles - which again will need some sort of randomizer if you want those selected randomly.
int limit = generator.nextInt(4)+1; // [1,4]
for(int i = 0; i < limit; i++) {
//...
}

Categories

Resources