JavaScript: How do i use a string as a piece of code - javascript

I am making a simple-ish graph maker to visualise equations. I need to be able to have the user input a string in a textbox and then interpret that as a piece of code I can execute to produce the graph. The way I am displaying the graph is by going through x in small increments and using an equation to then calculate the y position and then drawing a line between the points. At the moment I am just manually making a function in the code for example:
function(val) { return (val * val) + 5; }
but I need to be able to create a similar function from a string so the user could just input something like "(x*x)+(2*x)". is there any way to do this?

Canonically, this is done with eval(), although it comes with many caveats and should probably be avoided.
There are several questions on SO that discuss eval alternatives, but in your case, I would suggest a very bare-bones parser -- especially if all you're handling are mathematical equations.

Related

Converting Vector Processing syntax to p5 sketch

I am learning coding and am a novice. I am currently trying to convert a Processing(java) sketch to a p5(javascript) sketch to put on my first website.
I'm having trouble translating the Vector and Array syntax from the Processing sketch.
This is the Vector from the processing Sketch (working):
for (int i = pts.size()-1; i >= 0; i --){
PVector pt = (PVector)pts.get(i);
......
PVector pt2 = (PVector)pts.get(j);
if (pt.dist(pt2) < 20){
......
Here is how I've been trying to translate it in p5 (not working)
for (var i = pts.size()-1; i >= 0; i --){
pt = p5.Vector.pts.get(i);
...........
var pt2 = (PVector)pts.get(j);
if (pt.dist(pt2) < 20){
line(pt.x, pt.y, pt2.x, pt2.y);
}
}
You shouldn't try to translate code by going line-by-line and translating the syntax. Instead, you need to take a step back and convert the program into English first. Then you take that English and try to implement it in the targed language. That might sound dumb, but that English is called an algorithm.
So, you should have a description of your program like this:
"Show 10 circles bouncing around the screen. If a circle touches the edge of the screen, it should bounce off by..."
That's just an example, but you get the idea. Then you'd take that and implement it in P5.js.
So instead of saying "how do I convert this array syntax to P5.js", you should be asking yourself "how do arrays work in JavaScript" or even "how do variables work in JavaScript". From there you can read tutorials to figure out how to implement your algorithm in P5.js.
Then if you get stuck on a specific syntax error, please look in the JavaScript console for any errors you're getting. We can't really help if all you tell us is that it's not working. What error are you getting? Where is your MCVE?
All of that being said, I'll try to help with your specific question. Let's take the original line:
PVector pt = (PVector)pts.get(i);
This line is declaring a variable named pt and is pointing it at whatever is returned from pts.get(i), which it casts to a PVector because Java is statically typed so everything needs a type.
Compare that to what you're trying to do in P5.js:
pt = p5.Vector.pts.get(i);
First off, where did you declare the pt variable? Secondly what is p5.Vector.pts? This syntax doesn't make any sense. You need to read up on how variables and arrays work in JavaScript.
Similarly, let's look at this line in your P5.js code:
var pt2 = (PVector)pts.get(j);
Again, where is pts declared? And you never have to cast anything in JavaScript, because it's dynamically typed. Again, you need to go back and read up on how variables in JavaScript work.
Shameless self-promotion: I've written a series of tutorials geared towards Processing developers trying to learn JavaScript, available here.

CANNON.js: check if a body is being constrained

I've been trying to make a multiplayer game using javascript (most of which is on the server, using Node.js); one of the core mechanics I want to make is that players will be able to design their own fighting style (right down to how they swing their sword etc). Problem is that I can't find any simple way of constraining players' movements.
I first tried to write a method that checks then clamps the player's style so it doesn't look like they're breaking every limb simultaneously, but that didn't really work. I then found the wonderful CANNON.ConeTwistConstraint, but after looking through the documentation I've found that CANNON.js's constraints don't seem to have any sort of built-in function for just testing whether two bodies are exceeding the constraint's limits. I've thought about having my game just create objects in a separate simulation and check whether a force is being applied to either object, but I'm not sure about how to go about this, or if there's a better way.
Is there a simple/easier solution to my problem? If not, what would be the least CPU-intensive way of implementing the above?
You can manually check if the ConeTwistConstraint is hitting its limit. If you have a look at the method CANNON.ConeEquation.prototype.computeB, you can see that it computes the constraint violation, "g", using cos() and a dot product. You can simply do the same with the following code.
var eq = coneTwistConstraint.coneEquation;
var g = Math.cos(eq.angle) - eq.axisA.dot(eq.axisB);
if(g > 0) {
// Constraint limit exceeded
} else {
// Constraint is within limits
}
Using the same strategy, you can check if the twist limit is exceeded. Since the twist equation is a CANNON.RotationalEquation, the code becomes:
var eq2 = coneTwistConstraint.twistEquation;
var g2 = Math.cos(eq2.maxAngle) - eq2.axisA.dot(eq2.axisB);

Drawing plots interactively in a web app

I am looking for a library preferably in JavaScript, that will allow a user to draw a plot (simple one consisting of vertical and horizontal steps) like this one:
The idea is that when the user is done with the plot I can generate data points from the graph and process them.
I don't know where to start, I am looking to start learning to do this within a JS based framework (meteor) but I can't find a library that allows for something like this. The closest library I found is d3.js but I couldn't find any example that allows for this.
Would anyone be able to point out to me a sample example to start from? Would you know of a better suited library to accomplish what I am asking for?
Here is a relatively simple fiddle which accomplishes some of what you asked for, excluding axis (which are relatively easy and has plenty of examples). It uses D3 for all the drawing and mouse event handling. On click it simply executes svg.append("circle").attr("r", 5), and if it's not the first click (i.e. linking points) then it also will create a path element using the previous mouse click coordinates:
svg.insert("path", "circle").attr("d", function () {
return [
"M", prevClickLoc[0], prevClickLoc[1],
"L", prevClickLoc[0], y,
"L", x, y].join(" ");
})
Where x and y are the current mouse coordinates. Also has an export button that will output a list in the form of cx,cy,cx,cy,... :: d,d,d,d,.... On import, you could easily split this array into two using indexOf("::") or whatever you choose if you want to change the formatting. Then just exectue for (x in circles) {svg.append("circle").attr("cx", function...).attr("cy", function...);} and do something similar for paths for (y in paths) {svg.append("path").attr("d", function(){return paths[y];});}. It would be even easier if on export you made the cxcy array in the format cx;cy,cx;cy since then you could simply split the array at each comma and then split each index of the resulting array at the semicolon for a nice nested array.
Small update in this version, you can only place points if the current mouse x is greater than the previous x coordinate, and it also has the line d3.event.stopPropagation(); which prevents accidental highlighting of the page.

Math.log, a Natural logarithmic y scale for currency time-series?

My attempts to make my y values scale to logarithmic are turning my data upside-down.
I have vanilla js code and every implementation I read about are tied up in huge libraries of production code, I am not sure how/what to extract, I need some guidance as I could not put my finger on the problem weather it be sum or miss-use of the Math functions.
I am testing this by drawing the y 'data' to canvas (no libraries used) my x axis is constant 2px difference
Math.log uses e (2.718) as default base which is what I have read.. So I should be seeing my price data on a natural log scale but it wont work.
function logScale(data){
var log=data.slice(0);
var i=log.length;
while(i--){
log[i]=Math.log(data[i]); // should be natural but I don't see a change
// log[i]=Math.pow(Math.log(data[i]),10); //upside-down
// log[i]=Math.log(data[i])/Math.LN10; //no visible change when drawn to canvas
}
console.dir(log);
return log;
}
Another attempt from a couple of weeks ago where I am using the data min, max and difference. then removing all the infinity.
function ᐄlogarithm(data){
var Lmax,Lmin,Ldif,Logarithm,infinity;
Lmax=Math.max.apply(this,data);
Lmin=Math.min.apply(this,data);
Ldif=(Lmax-Lmin);
Logarithm=[];
infinity=[];
for(var i=data.length-1;i>=0;i--){
Logarithm[i]=Math.log((data[i]-Lmin)/Ldif);
if(Logarithm[i]===-Infinity){infinity.push(i);}
}
for(var i=0;i<=infinity.length-1;i++){Logarithm.splice(infinity[i],1);}
return Logarithm;
}
The data looks different but still not quite like log scale. It is vertically warped to best describe it.
Please note jsfiddle-ing this won't work as The data is bitcoin prices (real time) so as there is no working code for a log scale there is no good way to show a comparison. Bitcoin or any other exchange data gets served as is so these functions would (if they worked) transfom any data array to log scale.
How do D3 do it? What is wrong with my code?

How to generate level for a laser game in Javascript?

I am trying to generate a random level for my silly game. The game consists of having laser/detector pairs around a square field of possible mirrors. Like this:
/*
LLLLLLLLLL
LmmmmmmmmL
LmmmmmmmmL
LmmmmmmmmL
LLLLLLLLLL
*/
Now, I have an algorithm which generates a level, quite poorly, by relying on random placement, and rejecting bad positions. This is not very fast, and does not really generate the kind of fields I'd like to have. Please feel free to try it out at http://cmouse.desteem.org/laser/
Any suggestions are welcome.
The current algorithm looks something like this:
function createLevel:
for i=0 to mirrors:
mirrorLocation = pickRandomPosition
mirrorType = pickRandomType
if (verifyPosition(mirrorLocation, mirrorType)):
i = i - 1
next
else:
storeMirror(mirrorLocation, mirrorType)
In verifyPosition, we test the mirror that it reaches a laser in all four directions, in hope of avoiding undetectedable mirrors. It is somewhat boring code, so I omit it here.
One way to make sure it's not trying multiple fields more than once is to iterate over the fields and put a mirror or not based on some probability. The probability to put a mirror should be #mirros / #fields, so that the expected number of mirrors is #mirrors at the end.

Categories

Resources