Pass Pointer to Array Element to Function - javascript

I am working on a program for a task in Linear Algebra that performs computations on vectors and matrices of floating point numbers.
i.e.,
v = [3.14159, 2.256, 1.5783, 6.782]
A = [ 9.7 2.333 5.467 5.2123
6.789 4.789 5.671 9.111
1.113 4.562 8.223 5.2125
6.666 7.8181 3.426 4.3567]
A part of the program performs the same operations on an input vector as it does on a specified row of an input matrix, handled by a function in C++. In C++, the same function can accept input of either a vector or matrix by having it accept a pointer to a specific array element; as long as the pointer arithmetic is meticulous and, knowing memory layout is row-major, it works. I am wondering if the same can be done in JavaScript.
I could write either of two functions:
i) A function that expects a vector.
Passing the vector in works.
However, passing in the matrix doesn't work.
I had hoped to pass in the pointer to, say, the first element in the second row (the element containing 6.789). Then to access the entire row by something like A[0][i]. But JavaScript doesn't like that.
ii) A function that expects a matrix.
Passing the matrix in works.
However, passing in the vector doesn't work. If I try to access the vector elements as v[0][i], JavaScript doesn't like that.
Either my syntax is incorrect, or I am trying to do something that cannot be done.
The vector and array cannot be changed in form (i.e., flattened, etc.) because the rest of the program needs them to keep their forms; the vector needs to remain a vector and the matrix needs to remain a matrix.
In JavaScript, is it possible to pass a pointer to a specific array element into a function and then, within the function, have the vector (or row of matrix) treated as just a regular array?
If not, is there a suggested work-around?

Does this do what you're after?
function doSomethingWithVectorOrMatrixRow(vectorOrMatrix, matrixRow) {
const aVector = matrixRow === undefined ? vectorOrMatrix : vectorOrMatrix[matrixRow];
return doSomething(aVector);
}
/* Use it as */ doSomethingWithVectorOrMatrixRow(v);
/* or */ doSomethingWithVectorOrMatrixRow(A, 1);
Although of course it would be more efficient to store a matrix as a flat Array, and simply operate on a given range of that Array, which would work equally well for a vector (range = whole vector), but you say you can't change the data structure used.

Related

need tool to : draw curve in browser (javascript) and get math function

I'm looking for the exact oposite of this tools : http://fooplot.com/#W3sidHlwZSI6MCwiZXEiOiJ4XjIiLCJjb2xvciI6IiMwMDAwMDAifSx7InR5cGUiOjEwMDB9XQ--
Here, we give a math function, it draw the function.
I need to draw some function and get the math function correspondent
EDIT : If it's impossible, may be can get a resembling function ?
If you can restrict yourself to some specific class of functions, e.g. polynomials of degree no more than 10, then you have a bunch of parameters and you can use some optimization to tune these parameters to best match your input.
But your question doesn't specify such a class of functions, and the general form is not solvable: anything that you draw that might be a function (i.e. has at most one y coordinate for each x coordinate) can be explained by very different (and often very complicated) functions, which behave completely different outside the area of your drawing.

InDesign extendScript: How do I transform the entire selection?

By using the simple array app.selection[x], you can apply a transformation to any object in the selection, independently. But how do I apply a transformation to the entire selection together?
For example: inside InDesign, I can select two side-by-side objects and flip them horizontally, causing them to switch places and flip.
Inside a script, I can target each object in the selection, but they will not switch places; they will remain in the same place and flip.
for ( var x = 0; x < app.selection.length; x++ ){
app.selection[x].absoluteFlip = Flip.HORIZONTAL;
}
I could possibly group the selection, apply a transformation, then ungroup when finished, but this seems like unnecessary bulk that could slow down the code. I can easily do it manually inside InDesign, so it should follow that there's some way to access app.selection as a single object instead of an array. Does such an object exist?
Not really a solution, but it's worth noting that I don't think absoluteFlip is the action being performed, but a state indicating if the item has ben flipped. It's writable so you can set the state, but I think what's happening when using the menu to flip is flipItem: http://jongware.mit.edu/idcs6js/pc_PageItem.html#flipItem,
in which you can set "around" coordinates.
Now getting the origin of the selection box isn't straightforward for some reason (or maybe it is but I don't know how), but you can either use first object coordinates to set the origin so you can flip it around different coordinates depending on order of selection. Or you can sort the array to find left most coordinates (or whichever is needed), like this:
var selection_array = app.selection;
selection_array.sort(function(a, b){return a.visibleBounds[1]-b.visibleBounds[1]})
var flip_origin = [selection_array[0].visibleBounds[1],selection_array[0].visibleBounds[0]]
for(i=0;i<app.selection.length;i++){
app.selection[i].flipItem(Flip.HORIZONTAL, flip_origin);
}
Not sure it's easier or faster than grouping and ungrouping though.
Consider resize. It has a "individual/global" parameter :
void resize (in: varies, from: varies, by: ResizeMethods, values: Array of varies[, resizeIndividually: bool=true][, consideringRulerUnits: bool=false])
Resize the page item.

JS Canvas get pixel value very frequently

I am creating a video game based on Node.js/WebGL/Canvas/PIXI.js.
In this game, blocks have a generic size: they can be circles, polygons, or everything. So, my physical engine needs to know where exactly the things are, what pixels are walls and what pixels are not. Since I think PIXI don't allow this, I create an invisible canvas where I put all the wall's images of the map. Then, I use the function getImageData to create a function "isWall" at (x, y):
function isWall(x, y):
return canvas.getImageData(x, y, 1, 1).data[3] != 0;
However, this is very slow (it takes up to 70% of the CPU time of the game, according to Chrome profiling). Also, since I introduced this function, I sometimes got the error "Oops, WebGL crashed" without any additional advice.
Is there a better method to access the value of the pixel? I thought about storing everything in a static bit array (walls have a fixed size), with 1 corresponding to a wall and 0 to a non-wall. Is it reasonable to have a 10-million-cells array in memory?
Some thoughts:
For first check: Use collision regions for all of your objects. The regions can even be defined for each side depending on shape (ie. complex shapes). Only check for collisions inside intersecting regions.
Use half resolution for hit-test bitmaps (or even 25% if your scenario allow). Our brains are not capable of detecting pixel-accurate collisions when things are moving so this can be taken advantage of.
For complex shapes, pre-store the whole bitmap for it (based on its region(s)) but transform it to a single value typed array like Uint8Array with high and low values (re-use this instead of getting one and one pixels via the context). Subtract object's position and use the result as a delta for your shape region, then hit-testing the "bitmap". If the shape rotates, transform incoming check points accordingly (there is probably a sweet-spot here where updating bitmap becomes faster than transforming a bunch of points etc. You need to test for your scenario).
For close-to-square shaped objects do a compromise and use a simple rectangle check
For circles and ellipses use un-squared values to check distances for radius.
In some cases you can perhaps use collision predictions which you calculate before the games starts and when knowing all objects positions, directions and velocities (calculate the complete motion path, find intersections for those paths, calculate time/distance to those intersections). If your objects change direction etc. due to other events during their path, this will of course not work so well (or try and see if re-calculating is beneficial or not).
I'm sure why you would need 10m stored in memory, it's doable though - but you will need to use something like a quad-tree and split the array up, so it becomes efficient to look up a pixel state. IMO you will only need to store "bits" for the complex shapes, and you can limit it further by defining multiple regions per shape. For simpler shapes just use vectors (rectangles, radius/distance). Do performance tests often to find the right balance.
In any case - these sort of things has to be hand-optimized for the very scenario, so this is just a general take on it. Other factors will affect the approach such as high velocities, rotation, reflection etc. and it will quickly become very broad. Hope this gives some input though.
I use bit arrays to store 0 || 1 info and it works very well.
The information is stored compactly and gets/sets are very fast.
Here is the bit library I use:
https://github.com/drslump/Bits-js/blob/master/lib/Bits.js
I've not tried with 10m bits so you'll have to try it on your own dataset.
The solution you propose is very "flat", meaning each pixel must have a corresponding bit. This results in a large amount of memory being required--even if information is stored as bits.
An alternative testing data ranges instead of testing each pixel:
If the number of wall pixels is small versus the total number of pixels you might try storing each wall as a series of "runs". For example, a wall run might be stored in an object like this (warning: untested code!):
// an object containing all horizontal wall runs
var xRuns={}
// an object containing all vertical wall runs
var yRuns={}
// define a wall that runs on y=50 from x=100 to x=185
// and then runs on x=185 from y=50 to y=225
var y=50;
var x=185;
if(!xRuns[y]){ xRuns[y]=[]; }
xRuns[y].push({start:100,end:185});
if(!yRuns[x]){ yRuns[x]=[]; }
yRuns[x].push({start:50,end:225});
Then you can quickly test an [x,y] against the wall runs like this (warning untested code!):
function isWall(x,y){
if(xRuns[y]){
var a=xRuns[y];
var i=a.length;
do while(i--){
var run=a[i];
if(x>=run.start && x<=run.end){return(true);}
}
}
if(yRuns[x]){
var a=yRuns[x];
var i=a.length;
do while(i--){
var run=a[i];
if(y>=run.start && y<=run.end){return(true);}
}
}
return(false);
}
This should require very few tests because the x & y exactly specify which array of xRuns and yRuns need to be tested.
It may (or may not) be faster than testing the "flat" model because there is overhead getting to the specified element of the flat model. You'd have to perf test using both methods.
The wall-run method would likely require much less memory.
Hope this helps...Keep in mind the wall-run alternative is just off the top of my head and probably requires tweaking ;-)

Create SVGPoint inside an element with user coordinate

I have a small project (to learn SVG) running (using javascript).
I would like to be able to track a point in a shape with its own user coordinate system. My idea is to find the coordinates of the point within the shape, then create an SVGPoint, so that I can pass on that element. I have seen the method create SVGPoint in examples, but it seems it is used in the context of the 'SVG_root' (that is, document.documentElement.createSVGPoint() works).
When I use (in Firefox)
inSvgObj.createSVGPoint()
where inSVGObj is a element, the web console says "TypeError: inSvgObj.createSVGPoint is not a function". Is it possible to create an SVG point within the to subsequently set with values representing coordinates in that 's user coordinate system?
EDIT (after considernig Robert Longson's answer):
Given that SVGPoint is created only within an "SVG root" and that I have been unable to find a way to move that to within another element, I have found more convenient to use a different svg element type: SVGMatrix. In case it helps someone (as I have spent some time trying to deal with this),It is possible to manipulate analogue values inside an SVG Point by creating an SVGMatrix that would work as a simulated point (for the purposes of coordinates. To that endthe methods .createSVGMatrix(), getCTM() and.multiply() (this last from SVGMatrix) are used. To illustrate that, I will include a (js) function that takes 4 arguments: x-coordinate in user coordinate system (ucs) to transform, y-coordinate is that ucs, object whose ucs is the want we want to transform and an object in the ucs we want to transform to; and returns am object with thrre poperties the x-coordinate in the transformed ucs, its y-coordinate and 1 (for consistency with SVG Recommendations).
function coorUcsAToUcsB(ucsAx,ucsAy,svgObjUcsA,svgObjUcsB){
var ctmUcsA=svgObjUcsA.getCTM();
var ctmUcsB=svgObjUcsB.getCTM().inverse();
var mtx=document.getElementsByTagName('svg')[0].createSVGMatrix();
mtx.e=ucsAx;
mtx.f=ucsAy;
var simulSvgP=ctmUcsB.multiply(ctmUcsA.multiply(mtx)); //1
return {"x":simulSvgP.e,"y":simulSvgP.f,"z":1};
}
//1 this line creates an svg matrix with 1st and 2nd column at 0, 3rd with coordinates of ucsB from the analogue svg matrix with coordinates in ucsA - it takes the coordinates in ucsA to viewport's cs and from there to coordinates in ucsB. For the matrix operation explanation, see this.
Any comments, in particular having overlooked a existing method that does the same or any drawbacks, will be more than welcome.
You create the SVG Point using the root element creation but once you've done that you can set whatever values in it you want. When you assign those values to an object the object will interpret them in its coordinate system.

"Apply" a transformation in RaphaelJs

I've written a wrapper class around RaphaelElement. It has a property elem which stores the corresponding Element and the two convenience methods setPos and getPos. Moreover there's a position member with the two entries x and y.
Therefore getPos() merely returns the position. setPos accepts a new position as a parameter and has to update the coordinates of elem.
Unfortunately there is no information what type of RaphaelElement will be stored in elem, it could be a circle as well as a rectangle. Right now the code inside setPos looks like this:
//position is the parameter, this.pos is the member
this.pos = position;
this.elem.attr("x",this.pos.x);
this.elem.attr("y",this.pos.y);
this.elem.attr("cx", this.pos.x);
this.elem.attr("cy", this.pos.y);
This feels like a dirty workaround. It works with both circles and rectangles, but on a rectangle there's no attribute "cx" or "cy" and on a circle both "x" and "y" don't exist.
I browsed the documentation for a better way to modify the position of a RaphaelElement and found the method transform. But there's a problem: I haven't found a way to give "absolute" new coordinates to transform. It only offers means to translate, rotate or scale. If I have to change the position by applying a translation from my current position to the new position, then I have to append a new translation to the transformation string. I fear that it might grow VERY long. Moreover, I would have to evaluate an increasingly long string to get my current position.
It certainly is possible to move my Elements by appending new translations to the transformation but I would like to be able to either set the new position directly or to "apply" or "finalise" a transformation, so that it's string doesn't grow infinitely.
The consolidate method on a TransformList will convert a list of transforms into a single matrix. You could call this after you've added your translation.
Alternatively you could call getItem on the transformList which will give you an SVGTransform object and you can call setTranslate on that which would set the new position directly. You'd need to be careful that there is a transform and create one if there isn't.

Categories

Resources