Reputation: 55
I'm working on a Java program that prints a sine wave to the console. This is what I've written so far:
int num = 7;
for (double y = 2; y >= 0; y-=0.2) {
for (double x = 0; x <= num; x+=0.2) {
if ( ((0.1+x) >= Math.asin((double)y-1)) && (((double)x-0.1) <= Math.asin((double)y-1)) )
System.out.print('*');
else
System.out.print(' ');
}
System.out.println();
}
Essentially, this program treats each character on each line as a 0.2 x 0.2 area on a coordinate plane. If the sine function crosses this area, an asterisk is printed to the screen. Otherwise, a space is printed. When run, this is printed to the console:
*
*
*
*
*
*
Can anybody tell me why my program stops after printing the first quarter of the wave?
Upvotes: 4
Views: 4542
Reputation: 55
Thank you all for the help! Based on @dasblinkenlight's suggestion to use sin instead of asin, I found a very simple solution:
int num = 7;
for (double y = 1; y >= -1; y-=0.2) {
for (double x = 0; x <= num; x+=0.2) {
double sin = Math.sin(x);
if ( (0.1+y) >= sin && (y-0.1) <= sin )
System.out.print('*');
else
System.out.print(' ');
}
System.out.println();
}
This prints this to the console:
*****
** *
* **
* * **
* * *
* * *
* *
* *
* *
** **
****
Upvotes: 0
Reputation: 178293
The reason it only prints the first quarter of the sine wave is because of the indicated range of Math.asin
:
Returns the arc sine of a value; the returned angle is in the range -pi/2 through pi/2.
Once you advance x
past Math.PI / 2
, then the if
statement's condition will always be false
.
You can take advantage of the fact that
sin(π - x) = sin(x)
and
sin(2π - x) = -sin(x)
by including more conditions. (I've also removed the unnecessary casts to double
for clarity.)
if ( (0.1+x >= Math.asin(y-1)) && (x-0.1 <= Math.asin(y-1)) ||
(0.1+x >= Math.PI - Math.asin(y-1)) && (x-0.1 <= Math.PI - Math.asin(y-1))
(2*Math.PI -(0.1 + x) <= -Math.asin(y-1)) && (2*Math.PI -(x-0.1) >= -Math.asin(y-1)) )
Output:
*
* *
* *
* * *
* * *
* * *
* *
* *
* *
* *
*
Upvotes: 1
Reputation: 1748
Edit: Whoops, skimmed the code a little too fast. This is wrong.
Well, you set num
to 7, then in your loop you take x from 0 to num-1
, so you're only looping over 7 columns. Increase num and your graph should add additional columns. You'll have to increase the range of y values you loop over too, if you want the graph to extend to negative numbers.
However, your algorithm is extremely inefficient. You're calculating asin(y-1)
twice for every square on your graph, when all you really need to do is calculate sin(x)
once for every column. Why not just fill an array with precalculated sine values and then consult the array while drawing the graph? (I realize, of course, that on a modern computer it's fast enough to be practically irrelevant either way.)
Upvotes: 0
Reputation:
The problem seems to arise from the condition of your if-statement, which almost always evaluates to false
. You should check the calculus behind your conditional expression. I find increasing num
does not really help here.
Maybe you should print another character instead of a whitespace by replacing System.out.print(' ');
with System.out.print('_');
for instance. This way you may be able to figure out why your program behaves that way. Reworking that algorithm of yours may also be helpful.
Upvotes: 0