Why is xspeed != 0? - rotation

I'm making a game in which the player should move in its facing direction.
So I've come up with this.
int speed = 50;
float rotation = 90;
int speedx = speed * cos(rotation);
int speedy = speed * sin(rotation);
player->move(speedx, speedy);
But the problem is this:cos(90) returns -0.448074 and sin(90) returns 0.893997. They should return 0 and 1.
Does any one of you have an idea why?

Your cos and sin functions are expecting angles in radians, not degrees.
Cosine of 90 radians is -0.448074 as you've found.

Related

Processing Physics Sim

I am very new to processing and coding in general.
I am trying to make a bit of a physics sim of a ball bouncing with gravity accelerating and decelerating it.
You can see that it works reasonable well on the way down, but then after bouncing it never reaches the top again and I don't understand why. On the way down the speed should be multiplying by gravity, and on the way up it's dividing by gravity. I guess for some reason the code loops faster/more times on the way up and so the speed slows faster. In this sample I was hoping to flip the direction once it hits ypos = 0 again, however I did try instead flipping the direction once ballspeed = very slow and it did a few bounces and got lower and lower each time. Ironically, it behaved more realistically as if there was some loss of energy, but that's not what I want for now since I haven't added any such factor!
void setup(){
size(500,650);
background(0);
}
float ballspeed = (0.1);
float ypos = (20);
int direction=(1);
float gravity=(1.098);
void draw(){
background(0);
ballmove();
}
void ballmove(){
stroke(255);
noFill();
ellipse(250,ypos,50,50);
if ( direction == 1){
ballspeed = ballspeed * gravity;
ypos = ypos + ballspeed;
}
if ( direction ==- 1 ){
ballspeed = ballspeed / gravity;
ypos = ypos + (ballspeed);
}
if ( ypos > 600 ){
direction =- direction;
ballspeed =- ballspeed;
}
if ( ypos == 0 ){
ballspeed = 0.1;
direction =- direction;
}
}
It's due to the fact that what you're doing here is the Euler's integration and that it's only an approximation of the real world because the timesteps aren't infinitely short. In the real world, the speed and the positon of an object aren't updated every n milliseconds, it happens all the time so with this method, the best you can do is to reduce your timesteps but it will never be perfect.
EDIT : I just noticed that you were multiplying and dividing by the gravity. That's not how physic works: you should just subtract by gravity*timestep since the speed is the antiderivative of the acceleration (which in your case is -gravity). like that your model would be way more realistic and you wouldn't even have to make a difference between the way up and the way down.
In any case, this formula : Ypos = h - g / 2 * (time % sqrt(8 * h / g) - sqrt(2 * h / g)) ^ 2 will give the exact result even if it's not a real sim anymore.

using spherical coordinates in opengl

I am trying to plot points around a center point using spherical coordinates. I know this is by far not the most efficient way to plot a sphere in OpenGL but i want to do it as an excersive to understand spherical coordinates better.
I want to step through each point by a certain angle so for this i have a nested for loop itterating through theta 0 - 360 and phi 0-360 and i am attempting to get the Cartesian coordinates of each of these steps and display it as a single point.
so far i have this:
float r = 1.0;
for( float theta = 0.0; theta < 360.0; theta += 10.0){
for(float phi = 0.0; phi < 360.0; phi += 10.0){
float x = r * sin(theta) * cos(phi);
float y = r * sin(theta) * sin(phi);
float z = r * cos(theta);
}
}
i store these points a display them. the display function works fine as i have used it to display other point structure before but for some reason i can't get this to work.
I have also tried converting the angles from degrees to radians:
float rTheta = theta * M_PI * 180.0;
float rPhi = phi * M_PI * 18.0;
as sin() and cos() both use radians but it yields the same results.
Am i doing something wrong and badly misunderstanding something?
In the conversion from degrees to radians of angle x, the correct formula is x * M_PI / 180..

animating sine waves in processing

how do I animate the sin lines in the following code to move along the y-axis, to somehow look more like moving water waves?
-if you take out the velocity and acceleration codes you will see what I was trying to work with
float scaleVal = 6.0;
float angleInc = 0.19;
float velocity=0.0;
float acceleration=0.01;
void setup(){
size(750,750);
stroke(255);
}
void draw(){
background (0);
float angle=0.0;
for (int offset = -10; offset < width+10; offset += 10) {
for (int y = 1; y <= height; y += 3) {
float x = offset + (sin(angle) * scaleVal);
line(x, y, x, y+2);
angle += angleInc;
velocity += acceleration;
y += velocity;
}
angle += PI;
}
}
Try using sin() to change the y position instead of x.
The x position can simply increment.
The math may be daunting, but it gets fun once you get the hang of it.
Imagine going around a circle with the radius of 1.0 in a cartesian coordinate system (0 is centre , x and y increase to the right and down and decrease towards left and top):
Let's say you start at the top, the highest value, the length radius of your circle (1.0).
As you decrease the angle, the x move to the left, but the y will go towards the centre( 0.0 )
then x will increase as it gets close to the centre and y will drop to bottom of the circle (-1.0)
then x will keep increasing until it reaches the right edge of the circle and the y value will increase and reach the vertical centre (0.0)
finally the x will decrease until it reaches the horizontal centre and y will increase and reach back to the top of the circle (1.0)
This image explains it pretty well:
Essentially it's like a converter: you plug in an angle from 0 to 360 degrees or TWO_PI radians (as sin works with angles in radians) and you get back a value between -1.0 and 1.0.
If you want to draw a sine wave, you have to draw multiple points:
the x position will increase value directly
the y position will increase the angle, but use the result of the sin() function to obtain a value that goes up and down.
The last thing to do is multiple the result of the sin() function by a larger number to essentially scale the sine wave (from -1.0 to 1.0) to a size more appropate for the screen.
Here's a quick commented demo you can use the mouse position to play with:
function setup(){
createCanvas(640,100);
}
function draw(){
background(255);
var numberOfPoints = 1+(mouseX/2);
//how often apart will the points be
var widthPerPoint = width / numberOfPoints;
//how much will the angle change from one point to another
var anglePerPoint = TWO_PI/numberOfPoints;
var waveHeight = 25;
for(var i = 0; i < numberOfPoints; i++){
var x = i * widthPerPoint;
var y = sin(anglePerPoint * i) * waveHeight;
ellipse(x,50 + y,5,5);
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.4/p5.min.js"></script>
The gist of it is this line:
var y = sin(anglePerPoint * i) * waveHeight;
which can be broken down to:
//increment the angle
var incrementedAngle = anglePerPoint * i;
//compute sine (-1.0,1.0)
var sine = sin(incrementedAngle);
//scale sine result
var waveY = sine * waveHeight;
Once you can draw a static sine wave, it's pretty easy to animate: to the angle increment at each point you add an increasing value. This increases the angle and essentially goes around the circle (TWO_PI) for you.
You can create your own variable to increase at your own rate or you
can easily use an increasing value based on time(millis()) or frame(frameCount) which you can scale down (divide by a large number...or better yet multiple by a small fractional number):
function setup(){
createCanvas(640,100);
}
function draw(){
background(255);
var numberOfPoints = 1+(mouseX/2);
//how often apart will the points be
var widthPerPoint = width / numberOfPoints;
//how much will the angle change from one point to another
var anglePerPoint = TWO_PI/numberOfPoints;
var waveHeight = 25;
for(var i = 0; i < numberOfPoints; i++){
var x = i * widthPerPoint;
var y = sin(anglePerPoint * i + frameCount * 0.01) * waveHeight;
ellipse(x,50 + y,5,5);
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.4/p5.min.js"></script>
Hopefully the animation and simple demos above help illustrate the point.
In even simpler terms, it's a bit of an illustion: you draw points that only move up and down, but each point use an increasing angle along the circle.
Have a look at Reuben Margolin's kinectic sculpture system demo:
(I recommend checking out the whole PopTech talk: it's inspiring)
You should have a look at the Processing SineWave example as well.
Here's a more complex encapsulating the notions in a resuable function to draw multiple waves to hint at an atmospheric perspective:
int numWaves = 5;
void setup(){
size(400,400);
noStroke();
}
void draw(){
background(255);
for(int i = 0 ; i < numWaves; i++){
fill(30,120,180,map(i,0,numWaves-1,192,32));
drawSineWave(HALF_PI,0.00025 * (i+1),50 + (10 * i),8,width,mouseY);
}
fill(255);
text("drag mouse x to change number of waves",10,height-10);
}
/*
* radians - how often does the wave cycle (larges values = more peaks)
* speed - how fast is the wave moving
* amplitude - how high is the wave (from centre point)
* detail - how many points are used to draw the wave (small=angled, many = smooth)
* y - y centre of the wave
*/
void drawSineWave(float radians,float speed,float amplitude,int detail,float size,float y){
beginShape();
vertex(0,height);//fix to bottom
//compute the distance between each point
float xoffset = size / detail;
//compute angle offset between each point
float angleIncrement = radians / detail;
//for each point
for(int i = 0 ; i <= detail; i++){
//compute x position
float px = xoffset * i;
//use sine function compute y
//millis() * speed is like an ever increasing angle
//to which we add the angle increment for each point (so the the angle changes as we traverse x
//the result of sine is a value between -1.0 and 1.0 which we multiply to the amplitude (height of the wave)
//finally add the y offset
float py = y + (sin((millis() * speed) + angleIncrement * i) * amplitude);
//add the point
vertex(px,py);
}
vertex(size,height);//fix to bottom
endShape();
}
void mouseDragged(){
numWaves = 1+(int)mouseX/40;
}
Which you can also run bellow:
var numWaves = 5;
function setup(){
createCanvas(400,400);
noStroke();
}
function draw(){
background(255);
for(var i = 0 ; i < numWaves; i++){
fill(30,120,180,map(i,0,numWaves-1,192,32));
drawSineWave(HALF_PI,0.00025 * (i+1),50 + (10 * i),8,width,mouseY);
}
fill(255);
text("drag mouse x to change number of waves",10,height-10);
}
/*
* radians - how often does the wave cycle (larges values = more peaks)
* speed - how fast is the wave moving
* amplitude - how high is the wave (from centre point)
* detail - how many points are used to draw the wave (small=angled, many = smooth)
* y - y centre of the wave
*/
function drawSineWave(radians,speed,amplitude,detail,size,y){
beginShape();
vertex(0,height);//fix to bottom
//compute the distance between each point
var xoffset = size / detail;
var angleIncrement = radians / detail;
for(var i = 0 ; i <= detail; i++){
var px = xoffset * i;
var py = y + (sin((millis() * speed) + angleIncrement * i) * amplitude);
vertex(px,py);
}
vertex(size,height);//fix to bottom
endShape();
}
function mouseDragged(){
numWaves = ceil(mouseX/40);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.4/p5.min.js"></script>
The only other suggestion I have, in terms of rendering, it to have play with beginShape(). Rather than having to worry about where to draw each line, simply pass a bunch of points(via vertex(x,y)) in between beginShape()/endShape() calls and let Processing connect the dots for you.
Stack Overflow isn't really designed for general "how do I do this" type questions. It's for more specific "I tried X, expected Y, but got Z instead" type questions. That being said, I'll try to help in a general sense.
If you want to animate something going up and down, you have to modify its Y position over time.
One approach is to use the sin() or cos() functions to come up with a value that alternates between -1 and 1, which you can then multiply by a height and add to a center:
void setup() {
size(100, 200);
}
void draw() {
background (0);
float centerY = height/2;
float waveHeight = 75;
float input = frameCount/10.0;
float ballY = centerY+sin(input)*waveHeight;
ellipse(width/2, ballY, 10, 10);
}
Another approach is to keep track of the position and speed yourself. When the position reaches a min or max, just reverse the speed. Something like this:
float ballY = 100;
float ySpeed = 1;
void setup() {
size(100, 200);
}
void draw() {
background (0);
ballY += ySpeed;
if(ballY < 0 || ballY > height){
ySpeed *= -1;
}
ellipse(width/2, ballY, 10, 10);
}
You could also use the lerp() function. The point is that there are a million different ways to do this. The best thing you can do is to try something and post an MCVE if you get stuck. Good luck.

Using the processing.org trig functions correctly

This is really driving me nuts and I know I'm being silly somehow. Why isn't this line 45 degrees?
size(800, 600);
background (30);
stroke(255);
float r = 100;
float a= 20+ r * cos(radians(QUARTER_PI)) ;
float b= 20+ r * sin(radians(QUARTER_PI)) ;
line(20,20,a,b);
I've simplified this code from a larger project and if I do a lot of iterations the circle appears. What have I done to make the angle scale?
I would start off by debugging the code. The line is not 45 degrees because of the values being passed to line(). By printing the values for a and b, it's obvious the line is being drawn from coordinate (20,20) to roughly (119, 21). So you are telling the program to draw a straight line.
print(a + "\n"); // returns 119.99
print(b); // returns 21.37
If you want to draw a circle, why not use the ellipse() function?
EDIT:
The problem with your code is that you are passing into the radians() function the value QUARTER_PI, which is already in radians. Therefore, your problem could be solved in either of these ways:
// Pass in an amount of radians directly.
float r = 100;
float a = 20 + r * cos(QUARTER_PI);
float b = 20 + r * sin(QUARTER_PI);
line(20,20,a,b);
or
// Pass in degrees converted to radians.
float r = 100;
float a = 20 + r * cos(radians(45));
float b = 20 + r * sin(radians(45));
line(20,20,a,b);

What is the method for converting radians to degrees?

I run into this occasionally and always forget how to do it.
One of those things that pop up ever so often.
Also, what's the formula to convert angles expressed in radians to degrees and back again?
radians = degrees * (pi/180)
degrees = radians * (180/pi)
As for implementation, the main question is how precise you want to be about the value of pi. There is some related discussion here
a complete circle in radians is 2*pi. A complete circle in degrees is 360. To go from degrees to radians, it's (d/360) * 2*pi, or d*pi/180.
x rads in degrees - > x*180/pi
x degrees in rads -> x*pi/180
I guess if you wanted to make a function for this [in PHP]:
function convert($type, $num) {
if ($type == "rads") {
$result = $num*180/pi();
}
if ($type == "degs") {
$result = $num*pi()/180;
}
return $result;
}
Yes, that could probably be written better.
In javascript you can do it this way
radians = degrees * (Math.PI/180);
degrees = radians * (180/Math.PI);
This works well enough for me :)
// deg2rad * degrees = radians
#define deg2rad (3.14159265/180.0)
// rad2deg * radians = degrees
#define rad2deg (180/3.14159265)
180 degrees = PI * radians
360 degrees is 2*PI radians
You can find the conversion formulas at: http://en.wikipedia.org/wiki/Radian#Conversion_between_radians_and_degrees.
360 degrees = 2*pi radians
That means deg2rad(x) = x*pi/180 and rad2deg(x) = 180x/pi;
pi Radians = 180 degrees
So 1 degree = pi/180 radians
or 1 radian = 180/pi degrees
For double in c# this might be helpful:
public static double Conv_DegreesToRadians(this double degrees)
{
//return degrees * (Math.PI / 180d);
return degrees * 0.017453292519943295d;
}
public static double Conv_RadiansToDegrees(this double radians)
{
//return radians * (180d / Math.PI);
return radians * 57.295779513082323d;
}
Here is some code which extends Object with rad(deg), deg(rad) and also two more useful functions: getAngle(point1,point2) and getDistance(point1,point2) where a point needs to have a x and y property.
Object.prototype.rad = (deg) => Math.PI/180 * deg;
Object.prototype.deg = (rad) => 180/Math.PI * rad;
Object.prototype.getAngle = (point1, point2) => Math.atan2(point1.y - point2.y, point1.x - point2.x);
Object.prototype.getDistance = (point1, point2) => Math.sqrt(Math.pow(point1.x-point2.x, 2) + Math.pow(point1.y-point2.y, 2));
radians = (degrees/360) * 2 * pi

Resources