What is the math behind this ray-like animation? - javascript

I have unobfuscated and simplified this animation into a jsfiddle available here. Nevertheless, I still don't quite understand the math behind it.
Does someone have any insight explaining the animation?

Your fiddle link wasn't working for me due to a missing interval speed, should be using getElementById too (just because it works in Internet Explorer doesn't make it cross-browser).
Here, I forked it, use this one instead:
http://jsfiddle.net/spechackers/hJhCz/
I have also cleaned up the code in your first link:
<pre id="p">
<script type="text/javascript">
var charMap=['p','.'];
var n=0;
function myInterval()
{
n+=7;//this is the amount of screen to "scroll" per interval
var outString="";
//this loop will execute exactly 4096 times. Once for each character we will be working with.
//Our display screen will consist of 32 lines or rows and 128 characters on each line
for(var i=64; i>0; i-=1/64)
{
//Note mod operations can result in numbers like 1.984375 if working with non-integer numbers like we currently are
var mod2=i%2;
if(mod2==0)
{
outString+="\n";
}else{
var tmp=(mod2*(64/i))-(64/i);//a number between 0.9846153846153847 and -4032
tmp=tmp+(n/64);//still working with floating points.
tmp=tmp^(64/i);//this is a bitwise XOR operation. The result will always be an integer
tmp=tmp&1;//this is a bitwise AND operation. Basically we just want to know if the first bit is a 1 or 0.
outString+=charMap[tmp];
}
}//for
document.getElementById("p").innerHTML=outString;
}
myInterval();
setInterval(myInterval,64);
</script>
</pre>
The result of the code in the two links you provided are very different from one another.
However the logic in the code is quite similar. Both use a for-loop to loop through all the characters, a mod operation on a non-integer number, and a bitwise xor operation.
How does it all work, well basically all I can tell you is to pay attention to the variables changing as the input and output change.
All the logic appears to be some sort of bitwise cryptic way to decide which of 2 characters or a line break to add to the page.
I don't quite follow it myself from a calculus or trigonometry sort of perspective.

Consider that each line, as it sweeps across the rectangular area, is actually a rotation of (4?) lines about a fixed origin.
The background appears to "move" according to optical illusion. What actually happens is that the area in between the sweep lines is toggling between two char's as the lines rotate through them.
Here is the rotation eq in 2 dimensions:
first, visualize an (x,y) coordinate pair in one of the lines, before and after rotation (motion):
So, you could make a collection of points for each line and rotate them through arbitrarily sized angles, depending upon how "smooth" you want the animation.

The answer above me looks at the whole plane being transformed with the given formulae.
I tried to simplify it here -
The formula above is a trigonometric equation for rotation it is more simply solved
with a matrix.
x1 is the x coordinate before the the rotation transformation (or operator) acts.
same for y1. say the x1 = 0 and y1 = 1. these are the x,y coordinates of of the end of the
vector in the xy plane - currently your screen. if you plug any angle you will get new
coordinates with the 'tail' of the vector fixes in the same position.
If you do it many times (number of times depends on the angle you choose) you will come back to 0 x = 0 and y =1.
as for the bitwise operation - I don't have any insight as for why exactly this was used.
each iteration there the bitwise operation acts to decide if the point the plane will be drawn or not. note k how the power of k changes the result.
Further reading -
http://en.wikipedia.org/wiki/Linear_algebra#Linear_transformations
http://www.youtube.com/user/khanacademy/videos?query=linear+algebra

Related

Higher precision in JavaScript

I am trying to calculate with higher precision numbers in JavaScript to be able to zoom in more on the Mandlebrot set.
(after a certain amount of zooming the results get "pixelated", because of the low precision)
I have looked at this question, so I tried using a library such as BigNumber but it was unusably slow.
I have been trying to figure this out for a while and I think the only way is to use a slow library.
Is there a faster library?
Is there any other way to calculate with higher precision numbers?
Is there any other way to be able to zoom in more on the Mandlebrot set?
Probably unneceseary to add this code, but this is the function I use to check if a point is in the Mandlebrot set.
function mandelbrot(x, y, it) {
var z = [0, 0]
var c1 = [x, y]
for (var i = 0; i < it; i++) {
z = [z[0]*z[0] - z[1]*z[1] + c1[0], 2*z[0]*z[1] + c1[1]]
if (Math.abs(z[0]) > 2, Math.abs(z[1]) > 2) {
break
}
}
return i
}
The key is not so much the raw numeric precision of JavaScript numbers (though that of course has its effects), but the way the basic Mandelbrot "escape" test works, specifically the threshold iteration counts. To compute whether a point in the complex plane is in or out of the set, you iterate on the formula (which I don't exactly remember and don't feel like looking up) for the point over and over again until the point obviously diverges (the formula "escapes" from the origin of the complex plane by a lot) or doesn't before the iteration threshold is reached.
The iteration threshold when rendering a view of the set that covers most of it around the origin of the complex plane (about 2 units in all directions from the origin) can be as low as 500 to get a pretty good rendering of the whole set at a reasonable magnification on a modern computer. As you zoom in, however, the iteration threshold needs to increase in inverse proportion to the size of the "window" onto the complex plane. If it doesn't, then the "escape" test doesn't work with sufficient accuracy to delineate fine details at higher magnifications.
The formula I used in my JavaScript implementation is
maxIterations = 400 * Math.log(1/dz0)
where dz0 is (arbitrarily) the width of the window onto the plane. As one zooms into a view of the set (well, the "edge" of the set, where things are interesting), dz0 gets pretty small so the iteration threshold gets up into the thousands.
The iteration count, of course, for points that do "escape" (that is, points that are not part of the Mandelbrot set) can be used as a sort of "distance" measurement. A point that escapes within a few iterations is clearly not "close to" the set, while a point that escapes only after 2000 iterations is much closer. That distance quality can be used in various ways in visualizations, either to provide a color value (common) or possibly a z-axis value if the set is being rendered as a 3D view (with the set as a sort of "mesa" in three dimensions and the borders being a vertical "cliff" off the sides).

I need to make my function return a more organic collection of results

Whatever it is I'm doing, I don't know what it's called, but I need help because I know it can be done with math. This is for a simulation I'm building, and the role it plays is very difficult to explain, but it has something to do with defining the properties of an object.
Here is my JavaScript: https://jsfiddle.net/vdocnmzu/
DM.prototype.get = function(coords){
var dist;
val = 0;
for(var j,i = 0; i < this.distortions.length; i += 1){
dist = 0;
for(j = 0; j < coords.length; j += 1){
dist += Math.pow( coords[j] - this.distortions[i].coords[j], 2);
}
dist = Math.pow(dist,.5);
if( dist <= this.distortions[i].range){
val += Math.cos( (dist/this.distortions[i].range) * Math.PI/2 ) * this.distortions[i].amp;//;
}
}
return val;
}
What's happening is this: I have this 3D cube, where I can pick x & y, and get Z(the grayscale pixel color). In this sample code, I'm picking a grid of points across the entire x,y plane of the cube. The "bubbles" you see (you may need to refresh a few times) are multiple points being picked and creating that image.
What I'm trying to do is not have bubbles, but rather, organic flows between bubbles.
Right now, the z value comes from these "distortion points" that each of these 3DCubes have. It can have any amount of these points.
These "distortion points" don't have to be points. They can be sets of points, or lines, or any type of base geometry to define the skeleton of some type of distance function.
I think that distance function is what I'm struggling with, because I only know how to do it with points. I feel like lines would still be too rigid. What's the math associated with doing this with curves? Distance to a curve? Are there more approaches to this? If there's not a good single 1 to pick, it's okay to have a collection as well.
Your question is very complicated to understand. The overall feeling is that your expectations are too high. Some advanced math 101 might help (feel free to google buzzwords):
Defining a curve is an very hard problem that challenged the brightest mathematicians of the history. From the naive approach of the greeks, through the calculus of Newton and Leibniz, passing by Euler and Gauss, to the mathematical analysis of Weisstreiss, the word curve changed meaning several times. The accepted definition nowadays says that curves are continous functions in two variables, where continous is a very special word that has an exact meaning coined in the 19th century (naively is a function without jumps from one value to another). Togheter with the notion of continuity, came the notions of connected, compact, differentiable (and so on) curves, which defined new conditions for special curves. The subject developed to what is now known as topology and mathematical analysis.
Mathematicians usually uses definitions to reproduce a class of ideas that can be brought and thought togheter. To their surprise, the definition of continuity did include really weird functions to be curves: space-filling-curves, fractals!!! They called them monsters at the time.
After this introduction, lets go back to your question. You need a geometrical object to calculate distances from a point. Lets avoid weird curves and go from continous to differentiable. Now it's better. A (conected compact) differentiable function can be expanded in Taylor series, for example, which means that all functions of this class can be written as an infinite sum of polynomial functions. In two dimensions, you need to calculate matrices involved in this expansion (Calculus in many variables is a pre-requisite). Another step further is truncating this expansion in some degree, lets say 3. Then the general curve in this case is: ax + by + cx^2 + dy^2 + ex^3 + fy^3 + gx^2y + hxy^2 + ixy + j = 0 (ab...j are free parameters). Oh! This is reasonable, you might think. Well, actually there is a name for this kind of curve: algebraic curve of deggre 3. This is an active research theme of algebraic geometry, which is a very hard field even among mathematicians. Generally speaking, there are milestone theorems about the general behavior of those curves, which involves singularities and intersection points that are allowed in the general case.
In essence, what you are looking for does not exist, and is a very hard subject. Your algorithm works with points (really cool pictures by the way) and you should baby step it into a straight line. This step already requires you to think about how to calculate distance between a point and a straight line. This is another subject that was developed in general in the 19th century, togheter with mathematical analysis: metric spaces. The straightfoward answer to this question is defining the distance between a point and a line to be the smallest distance from the point to all line points. In this case, it can be shown that the distance is the modulus of the vector that connects the point to the line in a 90 degrees angle. But this is just one definition among infinte possible ones. To be considered a distance (like the one I just described and the euclidean distance) there is a set of axioms that needs to be verified. You can have hyperbolic metrics, discrete metrics, metrics that count words, letters, LotsOfFamousPeople metric spaces... the possibilities are infinite.
So, baby steps. Do it with straight lines and euclidean minimum distance metric. Play around with other metrics you find on google. Understand the axioms and make your own!!! Going to second degree polynomials is already a big challenge, as you have to understand everything that those curves can make (they can really do weird unexpect stuff) and define a distance to it (metric space).
Well thats it! Good luck with your project. Looks really cool!

Calculate Angle between two 3D Vectors

Note: I have absolutely no clue about Vector math, especially not in 3D.
I am currently working on some Javascript code that determines if a Finger that got captured by a Leap Motion Controller is extended (i.e. completely straight) or not.
Leap Motion provides us with an API that gives us Object for Hands, Fingers and Bones. Bones in particular have several properties, such as position Vectors, direction Vectors and so on, see here for the Documentation.
My idea was to take the Distal Phalang (tip of your finger) and Proximal Phalang (first bone of your finger), calculate the angle between them by getting the dot product of the two direction Vectors of the bones and then decide if it is straight or not. Like this, essentially:
var a = hand.indexFinger.distal.direction();
var b = hand.indexFinger.proximal.direction();
var dot = Leap.vec3.dot(a,b);
var degree = Math.acos(dot)*180/Math.PI;
The issue here is that these values are not reliable, especially if other fingers move about. It seems like the direction Vectors of the bones change when other fingers change direction (???).
For example, when all my Fingers are extended, the value of degree is roughly 0 and fluctuates between -5 and 5. When I make a fist, the value shoots up to 10, 15, 20. Logging the values of the direction Vectors reveals that they indeed do get changed, but how does this make sense? The Finger doesn't move, so its direction should stay the same.
Even worse for the thumb, the values don't add up there at all. An extended thumb can get values similar to the IndexFinger, but rotation the thumb upwards or downwards has changes in the range of 60 degrees!
I've tried using positional values instead, which gives me NaN results because the values seem to be to big.
So, my question is: how could I reliably calculate the angle between two Vectors? What am I missing here?
The correct formula is
cos(angle) = dot(a,b)/(norm(a)*norm(b))
where norm is the euclidean norm or length.
You should have gotten a wrong result, but the lengths of a and b should be constant, so the result should have been consistently wrong…
dot product is the cosine of the angle between vectors if those vectors are normalized. So be sure that a and b are normalized prior to calculate the dot product

Determine if a 2D point is within a quadrilateral

I'm working on a JS program which I need to have determine if points are within four corners in a coordinate system.
Could somebody point me in the direction of an answer?
I'm looking at what I think is called a convex quadrilateral. That is, four pretty randomly chosen corner positions with all angles smaller than 180°.
Thanks.
There are two relatively simple approaches. The first approach is to draw a ray from the point to "infinity" (actually, to any point outside the polygon) and count how many sides of the polygon the ray intersects. The point is inside the polygon if and only if the count is odd.
The second approach is to go around the polygon in order and for every pair of vertices vi and vi+1 (wrapping around to the first vertex if necessary), compute the quantity (x - xi) * (yi+1 - yi) - (xi+1 - xi) * (y - yi). If these quantities all have the same sign, the point is inside the polygon. (These quantities are the Z component of the cross product of the vectors (vi+1 - vi) and (p - vi). The condition that they all have the same sign is the same as the condition that p is on the same side (left or right) of every edge.)
Both approaches need to deal with the case that the point is exactly on an edge or on a vertex. You first need to decide whether you want to count such points as being inside the polygon or not. Then you need to adjust the tests accordingly. Be aware that slight numerical rounding errors can give a false answer either way. It's just something you'll have to live with.
Since you have a convex quadrilateral, there's another approach. Pick any three vertices and compute the barycentric coordinates of the point and of the fourth vertex with respect to the triangle formed by the three chosen vertices. If the barycentric coordinates of the point are all positive and all less than the barycentric coordinates of the fourth vertex, then the point is inside the quadrilateral.
P.S. Just found a nice page here that lists quite a number of strategies. Some of them are very interesting.
You need to use winding, or the ray trace method.
With winding, you can determine whether any point is inside any shape built with line segments.
Basically, you take the cross product of each line segment with the point, then add up all the results. That's the way I did it to decide if a star was in a constellation, given a set of constellation lines. I can see that there are other ways..
http://en.wikipedia.org/wiki/Point_in_polygon
There must be some code for this in a few places.
It is MUCH easier to see if a point lies within a triangle.
Any quadrilateral can be divided into two triangles.
If the point is in any of the two triangles that comprise the quadrilateral, then the point is inside the quadrilateral.

Click detection in a 2D isometric grid?

I've been doing web development for years now and I'm slowly getting myself involved with game development and for my current project I've got this isometric map, where I need to use an algorithm to detect which field is being clicked on. This is all in the browser with Javascript by the way.
The map
It looks like this and I've added some numbers to show you the structure of the fields (tiles) and their IDs. All the fields have a center point (array of x,y) which the four corners are based on when drawn.
As you can see it's not a diamond shape, but a zig-zag map and there's no angle (top-down view) which is why I can't find an answer myself considering that all articles and calculations are usually based on a diamond shape with an angle.
The numbers
It's a dynamic map and all sizes and numbers can be changed to generate a new map.
I know it isn't a lot of data, but the map is generated based on the map and field sizes.
- Map Size: x:800 y:400
- Field Size: 80x80 (between corners)
- Center position of all the fields (x,y)
The goal
To come up with an algorithm which tells the client (game) which field the mouse is located in at any given event (click, movement etc).
Disclaimer
I do want to mention that I've already come up with a working solution myself, however I'm 100% certain it could be written in a better way (my solution involves a lot of nested if-statements and loops), and that's why I'm asking here.
Here's an example of my solution where I basically find a square with corners in the nearest 4 known positions and then I get my result based on the smallest square between the 2 nearest fields. Does that make any sense?
Ask if I missed something.
Here's what I came up with,
function posInGrid(x, y, length) {
xFromColCenter = x % length - length / 2;
yFromRowCenter = y % length - length / 2;
col = (x - xFromColCenter) / length;
row = (y - yFromRowCenter) / length;
if (yFromRowCenter < xFromColCenter) {
if (yFromRowCenter < (-xFromColCenter))--row;
else++col;
} else if (yFromRowCenter > xFromColCenter) {
if (yFromRowCenter < (-xFromColCenter))--col;
else++row;
}
return "Col:"+col+", Row:"+row+", xFC:"+xFromColCenter+", yFC:"+yFromRowCenter;
}
X and Y are the coords in the image, and length is the spacing of the grid.
Right now it returns a string, just for testing.. result should be row and col, and those are the coordinates I chose: your tile 1 has coords (1,0) tile 2 is(3,0), tile 10 is (0,1), tile 11 is (2,1). You could convert my coordinates to your numbered tiles in a line or two.
And a JSFiddle for testing http://jsfiddle.net/NHV3y/
Cheers.
EDIT: changed the return statement, had some variables I used for debugging left in.
A pixel perfect way of hit detection I've used in the past (in OpenGL, but the concept stands here too) is an off screen rendering of the scene where the different objects are identified with different colors.
This approach requires double the memory and double the rendering but the hit detection of arbitrarily complex scenes is done with a simple color lookup.
Since you want to detect a cell in a grid there are probably more efficient solutions but I wanted to mention this one for it's simplicity and flexibility.
This has been solved before, let me consult my notes...
Here's a couple of good resources:
From Laserbrain Studios, The basics of isometric programming
Useful article in the thread posted here, in Java
Let me know if this helps, and good luck with your game!
This code calculates the position in the grid given the uneven spacing. Should be pretty fast; almost all operations are done mathematically, using just one loop. I'll ponder the other part of the problem later.
def cspot(x,y,length):
l=length
lp=length+1
vlist = [ (l*(k%2))+(lp*((k+1)%2)) for k in range(1,y+1) ]
vlist.append(1)
return x + sum(vlist)

Categories

Resources