WebAudio PannerNode Automation with LFO - javascript

Is there an easy way to connect an LFO directly to a panner node to automate x,y, or z? Like osc.connect(pannerNode.position.x)?
Or would it be better to just use a channelSplitter and handle left/right separately?Alternately I could input an LFO into a ScriptProcessorNode and then set the panner's x,y,z with the following, but wasn't sure if there was a better way:
function pan(range) {
var xDeg = parseInt(range.value);
var zDeg = xDeg + 90;
if (zDeg > 90) {
zDeg = 180 - zDeg;
}
var x = Math.sin(xDeg * (Math.PI / 180));
var z = Math.sin(zDeg * (Math.PI / 180));
p.setPosition(x, 0, z);
}
How to create very basic left/right equal power panning with createPanner();

No, I'm afraid there is not. I believe there's an open issue on this - that xyz should be audioparams.

Related

Calculating GUI position from game space position

I am creating my own game engine in Java Script. I have many things working great but one problem I am haveing is converting game space coordinates into screen space coordinates.
In my camera class I calulate the screen position of any given entity like so
draw(Engine, Entity, FollowEntity){
var x = Entity.render_position.x - (FollowEntity.render_position.x - Engine.rendersize.x / 2) - (Entity._get_render_size().x / 2);
var y = Entity.render_position.y - (FollowEntity.render_position.y - Engine.rendersize.y / 2) - (Entity._get_render_size().y / 2);
var _x = Entity.render_position.x - (FollowEntity.render_position.x - Engine.rendersize.x / 2);
var _y = Entity.render_position.y - (FollowEntity.render_position.y - Engine.rendersize.y / 2);
Engine.ctx.save();
Engine.ctx.translate(_x, _y);
Engine.ctx.rotate(Entity.rotation * Math.PI / 180);
Engine.ctx.translate(-_x, -_y);
Engine.ctx.drawImage(Engine.rasterizer.get_cached_img(Entity), x, y); /**/
Engine.ctx.restore();
}
I have tried extensively to aid myself in solving this with ChatGPT to no avail.
here is my current attempt
// Calculate the position of the entity in the game world
var gameX = this.ContextEntity.position.x;
var gameY = this.ContextEntity.position.y;
// Calculate the position of the camera in the game world
var cameraX = this.Engine.follow_entity.position.x;
var cameraY = this.Engine.follow_entity.position.y;
// Calculate the position of the entity on the screen, taking into account the difference in pixel size between the game entities and the GUI elements
var screenX = (gameX - cameraX) * this.GUI.rasterizer.pixel_size / this.Engine.rasterizer.pixel_size;
var screenY = (gameY - cameraY) * this.GUI.rasterizer.pixel_size / this.Engine.rasterizer.pixel_size;
// Adjust the position of the entity on the screen to take into account the size of the entity
screenX -= this.ContextEntity._get_render_size().x / 2;
screenY -= this.ContextEntity._get_render_size().y / 2;
gameToScreen(game) {
var game1 = (typeof game.x !== 'undefined') ? game.x : game[0];
var game2 = (typeof game.y !== 'undefined') ? game.y : game[1];
var x = game1 - (this.control_entity._get_render_midpoint().x - (this.rendersize.x / 2)) / this.rasterizer.pixel_size;
var y = game2 - (this.control_entity._get_render_midpoint().y - (this.rendersize.y / 2)) / this.rasterizer.pixel_size;
return new Vec2(Math.floor(x), Math.floor(y));
}
and here is another previous attempt which only seems to work when my pixel multipliers for the Engine entities are 0
the engine is running at https://soft-crab-57.telebit.io
Any help would be greatly appriciated.

Solar System Javascript Simulation of N-Body Gravity

I am seeking for some already done solution to simulate gravity interaction of n-body system, like our solar system for example, in any programming language (but preferably Javascript or C). I found this question, and it looks like exactly what I need, but, as I see, there's no interoperation between planets theyselves, only between sun and planets. I'm not so bad in JS, but really weak (more lazy) in geometry and gravity, so maybe somebody can give me an advice of how to enhance this code (or make the new one) to be able to simulate not the sun-to-planets, but full n-body gravity interaction? Or maybe you know such a software already written?
Cause as I understand, all I need is to change the code to calculate and display this:
//...
distanceTo: function(p2) {
var dx = p2.position.x - this.position.x,
dy = p2.position.y - this.position.y;
return Math.sqrt(dx ** 2 + dy ** 2);
},
attraction: function(p2) {
var dx = p2.position.x - this.position.x;
var dy = p2.position.y - this.position.y;
var d = Math.sqrt(dx ** 2 + dy ** 2);
this.f = G * (this.mass * p2.mass) / (d ** 2);
var theta = Math.atan2(dy, dx);
var fx = Math.cos(theta) * this.f;
var fy = Math.sin(theta) * this.f;
this.velocity.x += fx / this.mass;
this.velocity.y += fy / this.mass;
this.position.x += this.velocity.x;
this.position.y += this.velocity.y;
}
//...
for every single body in the system, but I'm not sure is it the right way to just iterate this code over bodies, due to such an iteration will dynamically change bodies' positions, which have been used for previous calculations within the iteration. Hope I spell it clear.
Is this possible at all? Is not this related to Three-body problem exponential computation complexity increasing? If not, can you please just direct me to right formulas and spell out simply for me, what to write and how?
Thanks!

Calculating the angle between a velocity (particles motion) and a line

So I am creating a simulation of a bouncing ball, and the user can place lines the ball can collide with on the canvas by dragging from one point to another. There are essentially four lines that can be created:
So the object that stores a line is defined as such:
export interface pathSection {
xfrom: number;
yfrom: number;
xto: number;
yto: number;
length: number;
}
The first and third lines in the image for example dont give the same value from
Math.atan2(yto - yfrom, xto - from);
So given the (relative) complexity of the surfaces, I need to find the angle between a moving object and that surface at the point of collision:
The ball strikes the surface at an angle a, which is what I want!
However I am having trouble finding the angle between the two vectors. This is what I understood would work:
var dx = this.path[index_for_path_section].xfrom - this.path[index_for_path_section].xto;
var dy = this.path[index_for_path_section].yfrom - this.path[index_for_path_section].yto;
var posX = this.particle.pos.x;
var posY = this.particle.pos.y;
var posNextX = posX + this.particle.v.x;
var posNextY = posY + this.particle.v.y;
var angleOfRamp = Math.atan2(dy, dx);
var angleOfvelocity = Math.atan2(posNextY - posY, posNextX - posX);
var angleBetween = angleOfRamp - angleOfvelocity;
This is then used to calculate the speed of the object after the collision:
var spd = Math.sqrt(this.particle.v.x * this.particle.v.x + this.particle.v.y * this.particle.v.y);
var restitution = this.elasticity / 100;
this.particle.v.x = restitution * spd * Math.cos(angleBetween);
this.particle.v.y = restitution * spd * Math.sin(angleBetween);
However the angle calculated is around -4.5 Pi, about -90 degrees for the object directly down and the surface at what looks to be around 45-60 degrees…
The red arrow shows the path of the object moving through the surface - the white dots show where a collision has been detected between the surface and the object.
Any help on how to get the correct and usable angle between the two velocity and the line would be appreciated!
Note I have tried utilizing this solution, but have struggled to adapt it to my own work.
So it took me some time, and I am not 100% sure still of why it works because I think im finding the JavaScript angles system a bit tricky, but:
var dx = this.path[collided].xfrom - this.path[collided].xto;
var dy = this.path[collided].yfrom - this.path[collided].yto;
var spd = Math.sqrt(this.particle.v.x * this.particle.v.x + this.particle.v.y * this.particle.v.y);
var angleOfRamp = Math.atan2(dy, dx);
var angleOfvelocity = Math.atan2(this.particle.v.y, this.particle.v.x);
var angleBetween = angleOfRamp * 2 - angleOfvelocity; // not sure why :)
if (angleBetween < 0) { angleBetween += 2*Math.PI; } // not sure why :)
const restitution = this.elasticity / 100;
this.particle.v.x = restitution * spd * Math.cos(angleBetween);
this.particle.v.y = restitution * spd * Math.sin(angleBetween);
Thanks to all who looked :)

dda algorithm - raycasting

I started a project using the raycasting technique GitHub Project
To find the length of the ray (distance from players pos to wall) I just increment by one. But there are several problems with that, its time consuming, inaccurate & will be difficult for texturing.
I tried to implement the daa algorithm, which doesnt just increments by 1 -> he goes through the grids and returns exact positions.
http://www.geeksforgeeks.org/dda-line-generation-algorithm-computer-graphics/
Has anyone experience with that or any tips?
No algorithm way:
for(let resolution = 0; resolution < display.width / 2; resolution++){ //every 2nd px gets scanned
let ray = this.pov + (-this.fov / 2 + this.fov / (display.width / 2) * resolution);
let distance = 0, hit = false;
/*ugly way of raycasting!*/
do{
let x = this.x + distance * Math.cos(ray * (Math.PI / 180));
let y = this.y + distance * Math.sin(ray * (Math.PI / 180));
if(map[Math.floor(x / block)][Math.floor(y / block)]){
distance = Math.sqrt(Math.pow(this.x - x, 2) + Math.pow(this.y - y, 2));
hit = true
}
distance += 1;
}while(!hit);
distance = convert / distance;
canvas.fillStyle = "#fff";
canvas.fillRect(resolution * 2, display.height / 2 - distance / 2, 2, distance);
}
You don't need DDA or Bresenham algorithm to find intersections of the ray with walls.
If you need one intersection with given border (or box edges) - just calculate it with ray equation and border position.
If you want to get intersections with grid cells - use voxelization algorithm like Amanatides-Woo

How come my lines aren't matching up?

EDIT: So apparently, PI is finite in JavaScript (which makes sense). But that leaves me with a major problem. What's the next best way to calculate the angles I need?
Alright, first, my code:
http://jsfiddle.net/joshlalonde/vtfyj/34/
I'm drawing cubes that open up to a 120 degree angle.
So the coordinates are calculated based on (h)eight and theta (120).
On line 46, I have a for loop that contains a nested for loop used for creating rows/columns.
It's somewhat subtle, but I noticed that the lines aren't matching up exactly. The code for figuring out each cubes position is on line 49. One of the things in the first parameter (my x value) for the origin of the cube is off. Can anyone help figure out what it is?
var cube = new Cube(
origin.x + (j * -w * (Math.PI)) +
(i * w * (Math.PI))
, origin.y + j * (h / 2) +
i * (h / 2) +
(-k*h), h);
Sorry if that's confusing. I,j, and k refer to the variable being incremented by the for loops. So basically, a three dimensional for loop.
I think the problem lies with Math.PI.
The width isn't the problem, or so I believe. I originally used 3.2 (which I somehow guessed and it seemed to line up pretty good. But I have no clue what the magical number is). I'm guessing it has to do with the angle being converted to Radians, but I don't understand why Math.PI/180 isn't the solution. I tried multiple things. 60 (in degrees) * Math.PI/180 doesn't work. What is it for?
EDIT: It might just be a JavaScript related math problem. The math is theoretically correct but can't be calculated correctly. I'll accept the imperfection to spare myself from re-writing code in unorthodox manners. I can tell it would take a lot to circumvent using trig math.
There are 2 problems...
Change line 35 to var w=h*Math.sin(30);. The 30 here matches the this.theta / 4 in the Cube getWidthmethod since this.theta equals 120.
Use the following code to generate the position of your new cube. You don't need Math.Pi. You needed to use both the cube width and height in your calculation.
var cube = new Cube(
origin.x+ -j*w - i*h,
origin.y + -j*w/2 + i*h/2,
h);
Alright I found the solution!
It's really simple - I was using degrees instead of radians.
function Cube(x, y, h) {
this.x = x
this.y = y
this.h = h;
this.theta = 120*Math.PI/180;
this.getWidth = function () {
return (this.h * Math.sin(this.theta / 2));
};
this.width = this.getWidth();
this.getCorner = function () {
return (this.h / 2);
};
this.corner = this.getCorner();
}
So apparently Javascript trig functions use Radians, so that's one problem.
Next fix I made was to the offset of each point in the cube. It doesn't need one! (o.O idk why. But whatever it works. I left the old code just in case I discover why later on).
function draw() {
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
ctx.fillStyle = "#000";
ctx.fillRect(0, 0, canvas.width, canvas.height); // Draw a black canvas
var h = 32;
var width = Math.sin(60*Math.PI/180);
var w = h*width;
var row = 9; // column and row will always be same (to make cube)
var column = row;
var area = row * column;
var height = 1;
row--;
column--;
height--;
var origin = {
x: canvas.width / 2,
y: (canvas.height / 2) - (h * column/2) + height*h
};
var offset = Math.sqrt(3)/2;
offset = 1;
for (var i = 0; i <= row; i++) {
for (var j = 0; j <= column; j++) {
for (var k = 0; k <= height; k++) {
var cube = new Cube(
origin.x + (j * -w * offset) +
(i * w * offset)
, origin.y + (j * (h / 2) * offset) +
(i * (h / 2) * offset) +
(-k*h*offset), h);
var cubes = {};
cubes[i+j+k] = cube; // Store to array
if (j == column) {
drawCube(2, cube);
}
if (i == row) {
drawCube(1, cube);
}
if (k == height) {
drawCube(0,cube);
}
}
}
}
}
See the full Jsfiddle here: http://jsfiddle.net/joshlalonde/vtfyj/41/

Categories

Resources