I can't get the calculations to work - java

I have a calculator that is suposed to figure the volume and the results come back as "0"
JButton btnCalculateVlmn = new JButton("Calculate Hot Tub Volume");
btnCalculateVlmn.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent arg0)
{
double width = 0, length = 0, depth = 0, volume = 0;
String lengthString, widthString, depthString;
lengthString = hotTubLengthText.getText();
widthString = hotTubWidthText.getText();
depthString = hotTubDepthText.getText();
try
{
if (rdbtnRoundTub.isSelected())
{
volume = Math.PI * Math.pow(length / 2.0, 2) * depth;
}
else
{
volume = Math.PI * Math.pow(length * width, 2)
* depth;
}
DecimalFormat formatter = new DecimalFormat("#,###,###.###");
hotTubVolumeText.setText("" + formatter.format(volume));
}
catch (NumberFormatException e)
{
labelTubStatus
.setText("Fill in all fields");
}
}
});
btnCalculateVlmn.setBounds(20, 200, 180, 20);
hotTubs.add(btnCalculateVlmn);
JButton Exit = new JButton("Exit");
Exit.setBounds(220, 200, 80, 20);
Exit.addActionListener(this);
hotTubs.add(Exit);
}

depth is declared as 0 and never overwritten... so the volume is always 0.
I guess you should do something like:
...
double width = 0, length = 0, depth = 0, volume = 0;
String lengthString, widthString, depthString;
lengthString = hotTubLengthText.getText();
widthString = hotTubWidthText.getText();
depthString = hotTubDepthText.getText();
depth = Double.valueOf(depthString);
length = Double.valueOf(lengthString);
width = Double.valueOf(widthString);
....

You forgot to convert the strings (lengthString, widthString and depthString) to doubles and assign them to your variables (length, width and depth).

you have depth = 0 and
anything * 0 = 0

you forgot to convert your strings from the input fields to double.
you get 0 as result because you set length and width to 0

In both branches of your main if condition your expressions ending * depth. However this depth variable seems to be set to 0 and not set to anything else. So volume will always be 0 since whatever you multiply by 0 will be 0.
Maybe you've wanted to use depthString. Something like this:
depth = Integer.parseInt(depthString);
if (rdbtnRoundTub.isSelected())
{
volume = Math.PI * Math.pow(length / 2.0, 2) * depth;
}
else
{
volume = Math.PI * Math.pow(length * width, 2) * depth;
}

Related

Why does the alpha argument to stroke() cause nothing to be drawn?

When I run the following code, my sketch draws as expected:
void draw() {
int[] nextColor = getNextColor();
stroke(nextColor[0], nextColor[1], nextColor[2]);
float[] nextPoint = getNextLocation();
point(nextPoint[0], nextPoint[1]);
}
However, if I add the fourth argument for the alpha transparency value to stroke(), nothing is drawn to the canvas at all:
float alpha = 0.8;
void draw() {
int[] nextColor = getNextColor();
stroke(nextColor[0], nextColor[1], nextColor[2], alpha);
float[] nextPoint = getNextLocation();
point(nextPoint[0], nextPoint[1]);
}
So far I have tried setting the alpha value to 1.0 directly in the argument (rather than using a variable) to be sure that I wasn't accidentally setting it to 0 somewhere. I have also double checked the documentation for stroke() and there is indeed an overridden version matching my arguments.
What am I doing incorrectly?
Here is all of my code in case there is something elsewhere that should be considered. Thank you.
import java.util.Random;
Random generator;
int meanX, stdevX, meanY, stdevY;
int meanR, meanG, meanB, stdevR, stdevG, stdevB;
float alpha = 0.8;
// returns two random numbers (for x, y, coordinates)
float[] getNextLocation() {
float[] retArr = new float[2];
retArr[0] = (float) (generator.nextGaussian() * stdevX + meanX);
retArr[1] = (float) (generator.nextGaussian() * stdevY + meanY);
return retArr;
}
int[] getNextColor() {
int[] retArr = new int[3];
retArr[0] = (int) (generator.nextGaussian() * stdevR + meanR);
retArr[1] = (int) (generator.nextGaussian() * stdevG + meanG);
retArr[2] = (int) (generator.nextGaussian() * stdevB + meanB);
return retArr;
}
void setup() {
background(255);
size(500, 500);
generator = new Random();
strokeWeight(10);
// play around with these
meanX = width/6;
stdevX = width/8;
meanY = height/2;
stdevY = height/30;
meanR = 224;
stdevR = 20;
meanG = 169;
stdevG = 60;
meanB = 20;
stdevB = 5;
}
void draw() {
int[] nextColor = getNextColor();
stroke(nextColor[0], nextColor[1], nextColor[2]);
float[] nextPoint = getNextLocation();
point(nextPoint[0], nextPoint[1]);
}
You are misunderstanding what the value of alpha is.
Alpha means transparency.
Alpha values range from 0 to 255, with 0 being completely transparent (i.e., 0% opaque) and 255 completely opaque (i.e., 100% opaque).
So in your case, when you set your alpha to 0.8, you don't see anything because it's very close to transparent. When you do not set the alpha, it is by default 100% opaque, so you see the drawing.
Take a look here if interested to know more.

How to make a condition of two fields?

Good afternoon, I need to add several conditions to validate two fields in the current code.
The Min field must not exceed the Max field. Min <Max / 5000
<4000 prohibited when entering.
The Max field must not be less than the Min field. Max <Min / 4000 <5000 prohibited when entering.
The Min field should not exceed the interval from the Max field, 500 units less can be entered.
For instance:
Min 4500 and Max 5000, 4400/5000, 4250/5000, 4501/5000 are prohibited to enter and above.
The Min and Max fields must not be equal. Min = Max is prohibited when entering.
code:
import controlP5.*;
ControlP5 cp5;
Textfield O;
Textfield OO;
void setup() {
size(700, 400);
PFont font = createFont("arial", 18);
cp5 = new ControlP5(this);
O = cp5.addTextfield("MIN")
.setPosition(20, 100)
.setSize(200, 40);
O.setInputFilter(ControlP5.INTEGER)
.setFont(font)
.setColor(color(255, 0, 0));
OO = cp5.addTextfield("MAX")
.setPosition(20, 170)
.setSize(200, 40);
OO.setInputFilter(ControlP5.INTEGER)
.setFont(font);
textFont(font);
}
void draw() {
if (keyPressed && OO.isFocus()) {
float n;
try {
n = Float.parseFloat(OO.getText().replace(',', '.'));
if (!(n >= 1 && n <= 12000)) {
throw new NumberFormatException(); // throw to catch below
}
}
catch (Exception e2) {
String t;
if (OO.getText().length() > 1) {
t = OO.getText().substring(0, OO.getText().length() - 1);
} else {
t = "";
}
OO.setText(t);
}
}
if (keyPressed && O.isFocus()) {
float n;
try {
n = Float.parseFloat(O.getText().replace(',', '.'));
if (!(n >= 1 && n <= 11500)) {
throw new NumberFormatException(); // throw to catch below
}
}
catch (Exception e2) {
String t;
if (O.getText().length() > 1) {
t = O.getText().substring(0, O.getText().length() - 1);
} else {
t = "";
}
O.setText(t);
}
}
background(0);
fill(255);
}
Overall it sounds like you're trying to have the user enter a range of valid values (where the minimum is always smaller than the maximum). There's already a ControlP5 controller for that: Range
Other than allowing to set a min and max value within a range is the constraint to keep a difference between max and min value of at least 500.
You could get away with making the Range slider handles 0px wide, essentially disabling them which means the range you set at the start (via setRangeValues) will be maintained:
import controlP5.*;
ControlP5 cp5;
Range range;
int rangeMinValue;
int rangeMaxValue;
void setup() {
size(700, 400);
PFont font = createFont("arial", 18);
cp5 = new ControlP5(this);
range = cp5.addRange("yourRange")
// disable broadcasting since setRange and setRangeValues will trigger an event
.setBroadcast(false)
.setFont(font)
.setPosition(50,50)
// notice the dimensions are proportional to the min/max range to avoid floating point values
.setSize(500,40)
// set minimum - maximum range here
.setRange(4000,5000)
// example: set initial (recommended) range values
.setRangeValues(4000, 4500)
// workaround to disable left/right handles contraining the range to 500
.setHandleSize(0)
// after the initialization we turn broadcast back on again
.setBroadcast(true)
;
textFont(font);
}
void draw() {
background(0);
fill(255);
}
void controlEvent(ControlEvent event) {
if(event.isFrom("yourRange")) {
// min and max values are stored in an array.
// access this array with controller().arrayValue().
// min is at index 0, max is at index 1.
rangeMinValue = int(event.getController().getArrayValue(0));
rangeMaxValue = int(event.getController().getArrayValue(1));
println("range:",rangeMinValue,"->",rangeMaxValue);
}
}
The one limitation is that ranges can't be > 500. If that's a requirment, you can still manually constrain the values (by setting the range min(low)/max(high) values):
import controlP5.*;
// range constants
final int RANGE_MIN = 4000;
final int RANGE_MAX = 5000;
// the smallest allowed difference between min/max values
final int RANGE_MIN_DIFFERENCE = 500;
final int RANGE_MID = RANGE_MIN + ((RANGE_MAX - RANGE_MIN) / 2);
ControlP5 cp5;
Range range;
int rangeMinValue;
int rangeMaxValue;
void setup() {
size(700, 400);
PFont font = createFont("arial", 18);
cp5 = new ControlP5(this);
range = cp5.addRange("yourCustomRange")
// disable broadcasting since setRange and setRangeValues will trigger an event
.setBroadcast(false)
.setFont(font)
.setPosition(50,50)
// notice the dimensions are proportional to the min/max range to avoid floating point values
.setSize(500,40)
// set minimum - maximum range here
.setRange(RANGE_MIN, RANGE_MAX)
// example: set initial (recommended) range values
.setRangeValues(RANGE_MIN, RANGE_MIN + RANGE_MIN_DIFFERENCE)
// after the initialization we turn broadcast back on again
.setBroadcast(true)
;
textFont(font);
}
void draw() {
background(0);
fill(255);
}
void controlEvent(ControlEvent event) {
if(event.isFrom("yourCustomRange")) {
// min and max values are stored in an array.
// access this array with controller().arrayValue().
// min is at index 0, max is at index 1.
int rangeMinInt = int(event.getController().getArrayValue(0));
int rangeMaxInt = int(event.getController().getArrayValue(1));
// if the values are within the desired range, update global values
if(rangeMaxInt - rangeMinInt >= RANGE_MIN_DIFFERENCE){
rangeMinValue = rangeMinInt;
rangeMaxValue = rangeMaxInt;
}else{
// otherwise check which side of the range should be constrained (right/max) or (left/min) to overwrite user input
if(rangeMaxInt > RANGE_MID){
range.setLowValue(rangeMaxInt - RANGE_MIN_DIFFERENCE);
}else{
range.setHighValue(rangeMinInt + RANGE_MIN_DIFFERENCE);
}
}
// values to use
println("range:",rangeMinValue,"->",rangeMaxValue);
}
}
If that takes too much space you can use Numberbox which compared to the text field has a few advantages:
you don't need to worry about string to integer conversion (it handles numbers by default)
you can set min/max values
Here's an example:
import controlP5.*;
ControlP5 cp5;
// range constants
final int RANGE_MIN = 4000;
final int RANGE_MAX = 5000;
// the smallest allowed difference between min/max values
final int RANGE_MIN_DIFFERENCE = 500;
final int RANGE_MID = RANGE_MIN + ((RANGE_MAX - RANGE_MIN) / 2);
int minValue;
int maxValue;
Numberbox inputMin;
Numberbox inputMax;
void setup() {
size(700, 400);
PFont font = createFont("arial", 18);
cp5 = new ControlP5(this);
inputMin = cp5.addNumberbox("minValue")
.setPosition(100,100)
.setSize(100,20)
.setFont(font)
.setScrollSensitivity(1.1)
// set initial acceptable range
.setMin(RANGE_MIN)
.setMax(RANGE_MAX)
// set default value
.setValue(4000)
;
inputMax = cp5.addNumberbox("maxValue")
.setPosition(100,150)
.setSize(100,20)
.setFont(font)
.setScrollSensitivity(1.1)
// set initial acceptable range
.setMin(RANGE_MIN)
.setMax(RANGE_MAX)
// set default value
.setValue(RANGE_MID + 1)
;
textFont(font);
}
void draw() {
constrainRangeInputs();
background(0);
fill(255);
text("minValue: " + minValue + "\n" +
"maxValue: " + maxValue, 10, 15);
}
void constrainRangeInputs(){
int rangeMinInt = (int)inputMin.getValue();
int rangeMaxInt = (int)inputMax.getValue();
//
if(abs(rangeMaxInt - rangeMinInt) < RANGE_MIN_DIFFERENCE){
if(rangeMaxInt > RANGE_MID){
inputMin.setValue(rangeMaxInt - RANGE_MIN_DIFFERENCE);
}else{
inputMax.setValue(rangeMinInt + RANGE_MIN_DIFFERENCE);
}
}
}
The logic constrain values to a minimum 500 difference is not 100% tight, there may some other edge cases I haven't considered. It's more of a way to illustrate ways of solving the problem so you're better equipt to do so.
I would recommend going through Processing > Examples > Contributed Libraries > ControlP5 and running the examples, in particular the controllers. You can prioritise the ones that sound closer to your current problem, but it's worth getting experience with the options so you can choose the best controllers/UI element to fit your problem.
The example may not include usage of every method the controller has, however there's a comment list at the bottom you could easily copy/paste/run immediately.
Additionally of course you have the full documentation

Java: Drawing a Star from a Polygon Circle w/Point Connections

So, I have been working on this program for drawing a star from a circle created using g.fillPolygon(int, int, int). I was intially having issues with creating an entire circle, but changed double angle = (i * 360) to (i * 720) to fix that (may be a band-aid fix, not sure yet). Now I'm in the process of attempting to connect all the points together (as shown in the "Target Output" section).
Note: I believe that the labeling of the points shown in the modification section was not done wih Java.
My Code: (Where I'm at right now)
import java.awt.*;
public class StarSampler {
public static void main(String[] args)
{
DrawingPanel panel = new DrawingPanel(500, 500);
Graphics2D g = panel.getGraphics();
g.setColor(Color.YELLOW);
fillStar(g, 250, 250, 150, 50, .7);
}
public static void fillStar(Graphics2D g, int ctrX, int ctrY, int radius, int nPoints, double spikiness)
{
double xDouble[] = new double[2*nPoints];
double yDouble[] = new double[2*nPoints];
int xPoint[] = new int[100];
int yPoint[] = new int[100];
for (int i = 0; i < 2*nPoints; i++)
{
double iRadius = (i % 2 == 0) ? radius : (radius * spikiness);
double angle = (i * 720.0) / (2*nPoints);
xDouble[i] = ctrX + iRadius * Math.cos(Math.toRadians(angle));
yDouble[i] = ctrY + iRadius * Math.sin(Math.toRadians(angle));
for (int j = 0; j < nPoints; j++) // Casts for ints and doubles
{
xPoint[j] = (int) xDouble[j];
yPoint[j] = (int) yDouble[j];
}
}
g.fillPolygon(xPoint, yPoint, nPoints); // Creates polygon but
}
}
My Code's Output:
Target Output (What I'm generally aiming for, not both together):

Flowcharts (pie and vertical)

I have been searching for some days on internet a way to make flow charts(pie and vertical) using html and css, but I didn't find anything.Did someone make these types of charts in html and css and could help me ?
Finally I found a way to do this charts but I want the values to be the values computed on servlet side.For vertical pie is working but for pie chart no(nothing displayed).Also I want the scale to be at my max value (("${sumC}")=2000),now it is at 60.
Could anyone hep me with thos problems?
Thank you very much!
Here is my servlet code:
public class ListaCumparaturi extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
try{
...
request.setAttribute("sumG", sumG);
request.setAttribute("sumCa", sumCa);
request.setAttribute("sumP", sumP);
request.setAttribute("sumC", sumC);
}
catch (Exception e2)
{
e2.printStackTrace();
}
finally
{
out.close();
}
}
}
Here is the js code:
<form action= "listacumparaturi" method="get">
<canvas width="1000" height="1000" id="myCanvas"></canvas>
var x= "${sumC}" ;
var y= "${sumG}" ; var z= "${sumP}" ; var w= "${sumCa}" ; total = "${sumT}";
var vertical = {
Calorii: x,
Grasimi: y,
Proteine: z,
Carbo: w
};
var data = Object.keys(vertical);
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.fillStyle = "blue";
total = "${sumT}";
color = ['red', 'blue', 'yellow','green','black'];
start = 0;
for (var i = 0; i < data.length; i++) {
ctx.fillRect((i * 60) + 50, 100, 10, -(vertical[data[i]]));
ctx.font = "9px Arial";
ctx.fillText(data[i], (i * 60) + 51, 112);
ctx.fillText((700 * i), 30, ((20 * -i) + 100));
ctx.beginPath();
ctx.moveTo(600, 150);
ctx.arc(600, 150, 150, start, start +
(Math.PI * 2 * (vertical[data[i]] / total)), false);
ctx.lineTo(600, 150);
ctx.fillStyle = color[i];
ctx.fill();
start += Math.PI * 2 * (vertical[data[i]] / total);
}
</script>
</form>
It is possible to build customm charts with HTML and CSS3 canvas.
I have created one sample codepen URL for reference.
http://codepen.io/nagasai/pen/EyjJLy
You can update your own data and build start charts from there
HTML:
Javascript:
//sample data object
var vertical = {
a: 10,
b: 20,
c: 40
};
var data = Object.keys(vertical);
total = 0;
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.fillStyle = "blue";
for (var i = 0; i < data.length; i++) {
total = total + vertical[data[i]];
}
color = ['red', 'blue', 'yellow'];
start = 0;
for (var i = 0; i < data.length; i++) {
ctx.fillRect((i * 60) + 50, 100, 10, -(vertical[data[i]]));
ctx.font = "9px Arial";
ctx.fillText(data[i], (i * 60) + 51, 112);
ctx.fillText((20 * i), 30, ((20 * -i) + 100));
ctx.beginPath();
ctx.moveTo(600, 150);
ctx.arc(600, 150, 150, start, start +
(Math.PI * 2 * (vertical[data[i]] / total)), false);
ctx.lineTo(600, 150);
ctx.fillStyle = color[i];
ctx.fill();
start += Math.PI * 2 * (vertical[data[i]] / total);
}
Hope this is helpful for you :)

QGraphicsScene grid view of pixmaps

I would like to implement a "grid view" of pixmaps. This is how I would like the UI to behave: You click a button and it shows a QGraphicsView with a QGraphicsScene (done) and then I would like to show all of my QPixmaps in a grid view. I don't actually want to see a grid I just want to organize the pixmaps like 10 columns (pixmaps) pr. row, and then a 10px whitespace in-between each pixmap. (not done). How would this be implemented?
EDIT: Here's what I've done so far (which produces the outcome described in the second comment)
public SpriteScene() {
super(0, 0, 800, 500);
QPixmap[] sprites = GUI.getWInterface().sprites;
List<QPixmap> l = Arrays.asList(sprites);
Iterator<QPixmap> i = l.iterator();
int rows = 10 / sprites.length;
boolean isDone = false;
for(int y = 0; y < rows; y++) {
for(int x = 0; x < 10; x++) {
if(i.hasNext()) {
QGraphicsPixmapItem pixmap = addPixmap(i.next());
pixmap.setPos(x * 64 + 10 , y * 64 + 10);
} else {
isDone = true;
break;
}
}
if(isDone) {
break;
}
}
}
SpriteScene extends QGraphicsScene and is being added to a QGraphicsView like this:
spriteView = new QGraphicsView(new SpriteScene(), this);
spriteView.setGeometry(0, 35, 850, 550);
spriteView.setAlignment(new Qt.AlignmentFlag[]{Qt.AlignmentFlag.AlignLeft, Qt.AlignmentFlag.AlignTop});
spriteView.hide();
Oh and by the way each pixmap is 64x64px :)
pixmap.setPos(x * 64 + 10 , y * 64 + 10);
Write that down on paper for the first few values:
x = 0, y = 0 => pos = ( 10, 10)
x = 1, y = 0 => pos = ( 74, 10)
x = 2, y = 0 => pos = (138, 10)
There's only 64 pixel different between each successive x offset. You need 74 pixels - the size of the pixmap plus the size of the border.
Set a few variables for your image with, height, horizontal and vertical spacing, and your code should look like:
pixmap.setPos(x * (width+hspacing) + offsetx, y * (height+vspacing) + offsety);
The offsetx/y would probably look nicer if they were half the respective spacing valued to get the grid "centered".

Categories

Resources