MVArray, MVPtr, and MVMask
MVArray
is based on FFArray
, but it stores
[ horizontal, vertical ]
motion vectors instead of simple integers.
MVArray
provides optimized functions which can greatly speed up
processing large chunks of motion vectors.
MVArray
is fixed length
, which means that once it is created, it
cannot be made larger or smaller.
MVArray
is a dense array
(in contrast to a sparse array
), which
means there are no holes in the array.
If any motion vector is not available (i.e.: it wasn’t available in the
input file to start with) it will be represented as a null
, but it
will be an MV(null)
, so all the methods from MV
can be used.
All motion vectors from 0
to length-1
can be read/written.
MVPtr
is very similar to MVArray
, and shares all the same methods.
The main difference is that MVPtr
does not have any memory allocated
for its data. Instead, it points to data from MVArray
.
Be careful not to play around with MVPtr
s once the object they were
created from has run out of its scope. You will write into unallocated
memory and the program will segfault.
MVMask
is an array of boolean
s that can be used with certain
methods from MVArray
/MVPtr
. This allows for very efficient code
which does not need to check for conditions inside loops every time.
The conditions are tested once to create the MVMask
, and then the
mask is applied on subsequent calls.
MVArray Constructor
The constructor is used to create a new MVArray
object of length
length
. All motion vectors are initialized to [0,0]
.
Syntax
new MVArray(length)
Parameters
length
must be a non-zero positive number that specifies the length
of the array to be created.
Return value
The new MVArray
object.
Examples
const mvarr = new MVArray(6);
print(mvarr); // [0,0],[0,0],[0,0],[0,0],[0,0],[0,0]
MVPtr Constructor
The constructor is used to create a new MVPtr
object from either an
MVArray
object or another MVPtr
object. The new object will have
the same length as the source
object.
Syntax
new MVPtr(source)
Parameters
source
must be either an MVArray
or an MVPtr
object.
Return value
The new MVPtr
object.
Examples
const mvarr = new MVArray(6);
print(mvarr); // [0,0],[0,0],[0,0],[0,0],[0,0],[0,0]
print(mvarr instanceof MVArray); // true
print(mvarr instanceof MVPtr); // false
const mvptr = new MVPtr(mvarr);
print(mvptr instanceof MVArray); // false
print(mvptr instanceof MVPtr); // true
mvptr[1] = MV(1,1);
print(mvarr); // [0,0],[1,1],[0,0],[0,0],[0,0],[0,0]
print(mvptr); // [0,0],[1,1],[0,0],[0,0],[0,0],[0,0]
MVMask Constructor
The constructor is used to create a new MVMask
object of length
length
. All motion vectors are initialized to true
.
Syntax
new MVMask(length)
Parameters
length
must be a non-zero positive number that specifies the length
of the mask array to be created.
Return value
The new MVMask
object.
Examples
const mvmask = new MVMask(6);
print(mvmask); // true,true,true,true,true,true
for ( let i = 0; i < 6; i++ ) mvmask[i] = (i&1);
print(mvmask); // false,true,false,true,false,true
MVArray.prototype.toString()
The toString()
method returns a string representing the specified
array and its motion vectors.
Syntax
toString()
Return value
The string representation.
Examples
const mvarr = new MVArray(6);
print(mvarr.toString()); // [0,0],[0,0],[0,0],[0,0],[0,0],[0,0]
MVArray.prototype.join()
The join()
method is kind of like toString()
, but it allows you to
specify a custom separator
for each motion vector. This allows you to
make some funny old-school emoticon sequences…
Syntax
join()
join(separator)
Parameters
separator
(optional) is a string that will separate each motion
vector. The default separator is a comma (,
).
Return value
The string representation.
Examples
const mvarr = new MVArray(4);
print(mvarr.join("")) // [0,0][0,0][0,0][0,0]
print(mvarr.join("^ ^")) // [0,0]^ ^[0,0]^ ^[0,0]^ ^[0,0] (birds)
MVArray.prototype.copyWithin()
The copyWithin()
method copies the chunk of data from the start
to
the end
indexes into the chunk starting at the target
index.
It works kind of like memmove()
in C
.
Syntax
copyWithin(target, start)
copyWithin(target, start, end)
Parameters
target
is the starting index where data is copied to.
start
is the starting index where data is copied from.
end
(optional) is the end index where data is copied from.
If this value is omitted, end
is length
.
Note: the target
, start
, and end
parameters can be negative values.
In that case, the values wrap around from the last index.
Return value
The modified motion vector array.
Examples
const mvarr = new MVArray(6);
for ( let i = 0; i < 6; i++ ) mvarr[i] = MV(i,i);
print(mvarr); // [0,0],[1,1],[2,2],[3,3],[4,4],[5,5]
print(mvarr.copyWithin(0, 4)); // [4,4],[5,5],[2,2],[3,3],[4,4],[5,5]
print(mvarr.copyWithin(2, 4, 5)); // [4,4],[5,5],[4,4],[3,3],[4,4],[5,5]
print(mvarr.copyWithin(-2, -4)); // [4,4],[5,5],[4,4],[3,3],[4,4],[3,3]
print(mvarr.copyWithin(0, -2)); // [4,4],[3,3],[4,4],[3,3],[4,4],[3,3]
MVArray.prototype.subarray()
The subarray()
method returns an MVPtr
that points to a chunk of
data inside the current object, starting from index begin
and ending
in index end
.
Syntax
subarray()
subarray(begin)
subarray(begin, end)
Parameters
begin
(optional) is the starting index where the new object will
point to.
If this value is omitted, begin
is 0
.
end
(optional) is the end index where the new object will point to.
If this value is omitted, end
is length
.
Note: the begin
and end
parameters can be negative values.
In that case, the values wrap around from the last index.
Return value
The new MVPtr
object.
Examples
const mvarr = new MVArray(6);
for ( let i = 0; i < 6; i++ ) mvarr[i] = MV(i,i);
const mvptr = mvarr.subarray();
print(mvptr); // [0,0],[1,1],[2,2],[3,3],[4,4],[5,5]
print(mvptr instanceof MVArray); // false
print(mvptr instanceof MVPtr); // true
print(mvarr.subarray(4)); // [4,4],[5,5]
print(mvarr.subarray(-2)); // [4,4],[5,5]
print(mvarr.subarray(3, -2)); // [3,3]
MVArray.prototype.set()
The set()
method copies data from the source
array into the current
object, starting at the optional targetOffset
index. If the current
object is not large enough to copy the entire data from source
, an
error is thrown.
It works kind of like memcpy()
in C
.
Syntax
set(source)
set(source, targetOffset)
Parameters
source
is either an MVArray
or an MVPtr
.
targetOffset
(optional) specifies which index to start copying to.
If this value is omitted, targetOffset
is 0
.
Note: the targetOffset
parameter can be a negative value.
In that case, the value wraps around from the last index.
Return value
The modified motion vector array.
Examples
const mvarr = new MVArray(6);
for ( let i = 0; i < 6; i++ ) mvarr[i] = MV(i,i);
const mvarr2 = new MVArray(2);
for ( let i = 0; i < 4; i++ ) mvarr2[i] = MV(-i,-i);
print(mvarr); // [0,0],[1,1],[2,2],[3,3],[4,4],[5,5]
print(mvarr2); // [0,0],[-1,-1]
print(mvarr.set(mvarr2)); // [0,0],[-1,-1],[2,2],[3,3],[4,4],[5,5]
print(mvarr.set(mvarr2, 2)); // [0,0],[-1,-1],[0,0],[-1,-1],[4,4],[5,5]
print(mvarr.set(mvarr2, -1)); // RangeError: out-of-bound access
const mvptr = mvarr.subarray(0, 1);
print(mvptr); // [0,0]
print(mvarr.set(mvptr, -1)); // [0,0],[-1,-1],[0,0],[-1,-1],[4,4],[0,0]
MVArray.prototype.fill()
The fill()
method fills all the motion vectors of an array from an
start
index to an end
index with a motion vector mv
.
Syntax
fill(mv)
fill(mv, start)
fill(mv, start, end)
Parameters
mv
to fill the array with.
start
(optional) is the index where the filling starts.
If this value is omitted, start
is 0
.
end
(optional) is the index where the filling ends.
If this value is omitted, end
is length
.
Note: the start
and end
parameters can be negative values.
In that case, the values wrap around from the last index.
Return value
The modified motion vector array.
Examples
const mvarr = new MVArray(6);
print(mvarr); // [0,0],[0,0],[0,0],[0,0],[0,0],[0,0]
print(mvarr.fill(MV(1,1))); // [1,1],[1,1],[1,1],[1,1],[1,1],[1,1]
print(mvarr.fill(MV(2,2), 4)); // [1,1],[1,1],[1,1],[1,1],[2,2],[2,2]
print(mvarr.fill(MV(3,3), 2, 4)); // [1,1],[1,1],[3,3],[3,3],[2,2],[2,2]
print(mvarr.fill(MV(4,4), -4, -2)); // [1,1],[1,1],[4,4],[4,4],[2,2],[2,2]
print(mvarr.fill(MV(5,5), -4, 4)); // [1,1],[1,1],[5,5],[5,5],[2,2],[2,2]
MVArray.prototype.reverse()
The reverse()
method reverses all motion vectors in the array in-place.
This operation applies to the entire array (there are no range arguments).
If you want to reverse just a small chunk of the array, use the
subarray()
method and call reverse()
on that.
Syntax
reverse()
Return value
The modified motion vector array.
Examples
const mvarr = new MVArray(6);
for ( let i = 0; i < 6; i++ ) mvarr[i] = MV(i,i);
print(mvarr); // [0,0],[1,1],[2,2],[3,3],[4,4],[5,5]
print(mvarr.reverse()); // [5,5],[4,4],[3,3],[2,2],[1,1],[0,0]
print(mvarr.subarray(2,4).reverse()); // [2,2],[3,3]
print(mvarr); // [5,5],[4,4],[2,2],[3,3],[1,1],[0,0]
MVArray.prototype.sort()
The sort()
method sorts all motion vectors in the array in-place.
If the optional compareFn
argument is not supplied, a numerical
comparison of the squared magnitude of the motion vectors is
performed.
This operation applies to the entire array (there are no range arguments).
If you want to sort just a small chunk of the array, use the
subarray()
method and call sort()
on that.
Syntax
sort()
sort(compareFn(a,b))
Parameters
compareFn
(optional) is a function (inline
, arrow
, or normal)
that is called for each pair of motion vectors during the sorting
algorithm.
The function’s parameters are a
and b
(a pair of motion vectors
from the array).
The function should return a negative number for (a
> b
), a
positive number for (a
< b
), and zero if (b
== a
).
Return value
The modified motion vector array.
Examples
const mvarr = new MVArray(6);
for ( let i = 0; i < 6; i++ ) mvarr[i] = MV(i,-i);
print(mvarr); // [0,0],[1,-1],[2,-2],[3,-3],[4,-4],[5,-5]
print(mvarr.sort((a,b) => b[0]-a[0])); // [5,-5],[4,-4],[3,-3],[2,-2],[1,-1],[0,0]
print(mvarr.sort((a,b) => b[1]-a[1])); //[0,0],[1,-1],[2,-2],[3,-3],[4,-4],[5,-5]
const mvptr = mvarr.subarray(2, 4);
print(mvptr); // [2,-2],[3,-3]
print(mvptr.sort((a,b) => b[1]-a[1])); // [3,-3],[2,-2]
print(mvarr); // [0,0],[1,-1],[3,-3],[2,-2],[4,-4],[5,-5]
print(mvarr.sort()); // [0,0],[1,-1],[2,-2],[3,-3],[4,-4],[5,-5]
function compareFn(a, b) {
return b.magnitude_sq() - a.magnitude_sq();
};
print(mvarr.sort(compareFn)); // [5,-5],[4,-4],[3,-3],[2,-2],[1,-1],[0,0]
MVArray.prototype.slice()
The slice()
method returns a new MVArray
object with a copy of the
data specified in the (optional) start
and end
range arguments.
If no range is specified, the entire array is copied, effectively
performing a deep copy
of the current object.
Syntax
slice()
slice(start)
slice(start, end)
Parameters
start
(optional) is the index where the copying starts.
If this value is omitted, start
is 0
.
end
(optional) is the index where the copying ends.
If this value is omitted, end
is length
.
Note: the start
and end
parameters can be negative values.
In that case, the values wrap around from the last index.
Return value
The new MVArray
object.
Examples
const mvarr = new MVArray(6);
for ( let i = 0; i < 6; i++ ) mvarr[i] = MV(i,i);
const mvptr = new MVPtr(mvarr);
const mvslc = mvarr.slice();
print(mvarr instanceof MVArray); // true
print(mvptr instanceof MVPtr); // true
print(mvslc instanceof MVArray); // true
print(mvslc instanceof MVPtr); // false
print(mvarr); // [0,0],[1,1],[2,2],[3,3],[4,4],[5,5]
print(mvptr); // [0,0],[1,1],[2,2],[3,3],[4,4],[5,5]
print(mvslc); // [0,0],[1,1],[2,2],[3,3],[4,4],[5,5]
mvslc.fill(MV(1,1));
print(mvarr); // [0,0],[1,1],[2,2],[3,3],[4,4],[5,5]
print(mvptr); // [0,0],[1,1],[2,2],[3,3],[4,4],[5,5]
print(mvslc); // [1,1],[1,1],[1,1],[1,1],[1,1],[1,1]
print(mvarr.slice(2)); // [2,2],[3,3],[4,4],[5,5]
print(mvarr.slice(-4)); // [2,2],[3,3],[4,4],[5,5]
print(mvarr.slice(2, 4)); // [2,2],[3,3]
print(mvarr.slice(2, -2)); // [2,2],[3,3]
print(mvarr.slice(-4, -2)); // [2,2],[3,3]
print(mvarr.slice(-4, 4)); // [2,2],[3,3]
MVArray.prototype.dup()
The dup()
method performs a deep copy
of the current object.
It has the same behaviour as calling slice()
with no range arguments.
Syntax
dup()
Return value
The new MVArray
object.
Examples
const mvarr = new MVArray(6);
for ( let i = 0; i < 6; i++ ) mvarr[i] = MV(i,i);
print(mvarr); // [0,0],[1,1],[2,2],[3,3],[4,4],[5,5]
const mvdup = mvarr.dup();
print(mvdup); // [0,0],[1,1],[2,2],[3,3],[4,4],[5,5]
mvarr[1] = MV(-1,-1);
mvdup[1] = MV(-2,-2);
print(mvarr); // [0,0],[-1,-1],[2,2],[3,3],[4,4],[5,5]
print(mvdup); // [0,0],[-2,-2],[2,2],[3,3],[4,4],[5,5]
MVArray.prototype.every()
The every()
method tests whether every motion vector in the array
passes the test implemented by the callbackFn
function.
If any motion vector does not pass the test, the method returns
early with false
.
Syntax
every(callbackFn(mv, index, array))
every(callbackFn(mv, index, array), thisArg)
Parameters
callbackFn
is a function (inline
, arrow
, or normal) that is
called for each motion vector of the array.
The function’s parameters are mv
(an MVRef
to the current motion
vector being tested), index
(the index it corresponds to in the
array), and array
(the array itself).
The function should return either true
or false
.
thisArg
(optional) is a value to use as this
when executing
callbackFn
.
Return value
true
or false
.
Examples
const mvarr = new MVArray(6);
for ( let i = 0; i < 6; i++ ) mvarr[i] = MV(i,i);
print(mvarr); // [0,0],[1,1],[2,2],[3,3],[4,4],[5,5]
print(mvarr.every((mv) => mv[0] >= 0)); // true
print(mvarr.every((mv) => mv[0] > 0)); // false
function is_monotonic(mv, i, arr) {
if ( i > 0 )
return mv[0] > arr[i-1][0] && mv[1] > arr[i-1][1];
return true;
}
print(mvarr.every(is_monotonic)); // true
mvarr[3] = MV(-1,-1);
print(mvarr); // [0,0],[1,1],[2,2],[-1,-1],[4,4],[5,5]
print(mvarr.every(is_monotonic)); // false
MVArray.prototype.some()
The some()
method tests whether at least one motion vector in the
array passes the test implemented by the callbackFn
function.
If any motion vector does pass the test, the method returns early
with true
.
Syntax
some(callbackFn(mv, index, array))
some(callbackFn(mv, index, array), thisArg)
Parameters
callbackFn
is a function (inline
, arrow
, or normal) that is
called for each motion vector of the array.
The function’s parameters are mv
(an MVRef
to the current motion
vector being tested), index
(the index it corresponds to in the
array), and array
(the array itself).
The function should return either true
or false
.
thisArg
(optional) is a value to use as this
when executing
callbackFn
.
Return value
true
or false
.
Examples
const mvarr = new MVArray(6);
for ( let i = 0; i < 6; i++ ) mvarr[i] = MV(i,i);
print(mvarr); // [0,0],[1,1],[2,2],[3,3],[4,4],[5,5]
print(mvarr.some((mv) => mv[0] <= 0)); // true
print(mvarr.some((mv) => mv[0] < 0)); // false
MVArray.prototype.forEach()
The forEach()
method calls the callbackFn
function for each motion
vector of the array. It has the same functionality as calling the code
below, but it’s slightly faster.
Note that you can modify mv
directly, since it is passed as an
MVRef
.
for ( let i = 0; i < mvarr.length; i++ )
callbackFn(mvarr[i], i, mvarr);
Syntax
forEach(callbackFn(mv, index, array))
forEach(callbackFn(mv, index, array), thisArg)
Parameters
callbackFn
is a function (inline
, arrow
, or normal) that is
called for each motion vector of the array.
The function’s parameters are mv
(an MVRef
to the current motion
vector being tested), index
(the index it corresponds to in the
array), and array
(the array itself).
thisArg
(optional) is a value to use as this
when executing
callbackFn
.
Return value
undefined
.
Examples
const mvarr = new MVArray(6);
for ( let i = 0; i < 6; i++ ) mvarr[i] = MV(i,i);
print(mvarr); // [0,0],[1,1],[2,2],[3,3],[4,4],[5,5]
mvarr.forEach((mv, i, arr) => mv = MV(4,4));
print(mvarr); // [0,0],[1,1],[2,2],[3,3],[4,4],[5,5]
// Note that the previous call to `forEach()` did not modify the array
// since the scoped variable mv was replaced instead of modified.
mvarr.forEach((mv, i, arr) => mv.assign(MV(i+2,i+2)));
print(mvarr); // [2,2],[3,3],[4,4],[5,5],[6,6],[7,7]
function is_four_four(mv, i, arr) {
const not_str = (mv.compare_neq(4,4)) ? "not " : "";
print(`mv [${i}] is ${mv}, which is ${not_str}[four,four]`);
}
mvarr.forEach(is_four_four);
// mv [0] is [2,2], which is not [four,four]
// mv [1] is [3,3], which is not [four,four]
// mv [2] is [4,4], which is [four,four]
// mv [3] is [5,5], which is not [four,four]
// mv [4] is [6,6], which is not [four,four]
// mv [5] is [7,7], which is not [four,four]
MVArray.prototype.maskedForEach()
The maskedForEach()
method calls the callbackFn
function for each
motion vector of the array that is selected by the mvmask
argument.
It has the same functionality as calling the code below, but it’s
slightly faster.
Note that you can modify mv
directly, since it is passed as an
MVRef
.
for ( let i = 0; i < arr.length; i++ )
if ( mvmask[i] )
callbackFn(arr[i], i, arr);
Syntax
maskedForEach(mvmask, callbackFn(mv, index, array))
maskedForEach(mvmask, callbackFn(mv, index, array), thisArg)
Parameters
mvmask
is an MVMask
that specifies on which motion vectors the
callbackFn
function should be called on.
callbackFn
is a function (inline
, arrow
, or normal) that is
called for each motion vector of the array that is selected by the
mvmask
argument.
The function’s parameters are mv
(an MVRef
to the current motion
vector being tested), index
(the index it corresponds to in the
array), and array
(the array itself).
thisArg
(optional) is a value to use as this
when executing
callbackFn
.
Return value
undefined
.
Examples
const mvarr = new MVArray(6);
for ( let i = 0; i < 6; i++ ) mvarr[i] = MV(i,i);
print(mvarr); // [0,0],[1,1],[2,2],[3,3],[4,4],[5,5]
const mvmask = new MVMask(6);
for ( let i = 0; i < 6; i++ ) mvmask[i] = (i&1);
print(mvmask); // false,true,false,true,false,true
mvarr.maskedForEach(mvmask, (mv) => mv.clear());
print(mvarr); // [0,0],[0,0],[2,2],[0,0],[4,4],[0,0]
MVArray.prototype.map()
The map()
method creates a new MVArray
and calls the callbackFn
on each motion vector of the source array, storing the result in the
corresponding motion vector in the new array.
Syntax
map(callbackFn(mv, index, array))
map(callbackFn(mv, index, array), thisArg)
Parameters
callbackFn
is a function (inline
, arrow
, or normal) that is
called for each motion vector of the array.
The function’s parameters are mv
(an MVRef
to the current motion
vector being tested), index
(the index it corresponds to in the
array), and array
(the array itself).
The function should return a motion vector value to be stored in the
new array.
thisArg
(optional) is a value to use as this
when executing
callbackFn
.
Return value
The new MVArray
object.
Examples
const mvarr = new MVArray(6);
for ( let i = 0; i < 6; i++ ) mvarr[i] = MV(i,i);
print(mvarr); // [0,0],[1,1],[2,2],[3,3],[4,4],[5,5]
const mvmap = mvarr.map((mv) => MV(mv[0]*mv[0],mv[1]*mv[1]));
print(mvmap instanceof MVArray); // true
print(mvarr); // [0,0],[1,1],[2,2],[3,3],[4,4],[5,5]
print(mvmap); // [0,0],[1,1],[4,4],[9,9],[16,16],[25,25]
MVArray.prototype.find()
The find()
method returns a value of a motion vector in the array,
if it satisfies the provided callbackFn
testing function.
Otherwise undefined
is returned.
Syntax
find(callbackFn(mv, index, array))
find(callbackFn(mv, index, array), thisArg)
Parameters
callbackFn
is a function (inline
, arrow
, or normal) that is
called for each motion vector of the array.
The function’s parameters are mv
(an MVRef
to the current motion
vector being tested), index
(the index it corresponds to in the
array), and array
(the array itself).
The function should return either true
or false
.
thisArg
(optional) is a value to use as this
when executing
callbackFn
.
Return value
A value in the array if a motion vector passes the test; otherwise, undefined
.
Examples
const mvarr = new MVArray(6);
for ( let i = 0; i < 6; i++ ) mvarr[i] = MV(i+2,i+2);
print(mvarr); // [2,2],[3,3],[4,4],[5,5],[6,6],[7,7]
print(mvarr.find((mv) => mv.compare_eq(1,1))); // undefined
print(mvarr.find((mv) => mv.compare_eq(4,4))); // [4,4]
MVArray.prototype.findIndex()
The findIndex()
method returns the index of a value of a motion
vector in the array, if it satisfies the provided callbackFn
testing
function. Otherwise -1
is returned.
Syntax
findIndex(callbackFn(mv, index, array))
findIndex(callbackFn(mv, index, array), thisArg)
Parameters
callbackFn
is a function (inline
, arrow
, or normal) that is
called for each motion vector of the array.
The function’s parameters are mv
(an MVRef
to the current motion
vector being tested), index
(the index it corresponds to in the
array), and array
(the array itself).
The function should return either true
or false
.
thisArg
(optional) is a value to use as this
when executing
callbackFn
.
Return value
The index of a value in the array if a motion vector passes the test; otherwise, -1
.
Examples
const mvarr = new MVArray(6);
for ( let i = 0; i < 6; i++ ) mvarr[i] = MV(i+2,i+2);
print(mvarr); // [2,2],[3,3],[4,4],[5,5],[6,6],[7,7]
print(mvarr.findIndex((mv) => mv.compare_eq(1,1))); // -1
print(mvarr.findIndex((mv) => mv.compare_eq(4,4))); // 2
MVArray.prototype.indexOf()
The indexOf()
method returns the first index at which a given motion
vector searchMV
can be found in the array (starting from the optional
fromIndex
argument), or -1
if it is not present.
Syntax
indexOf(searchMV)
indexOf(searchMV, fromIndex)
Parameters
searchMV
is the motion vector to search for in the array.
fromIndex
(optional) specifies which index to start the search from.
If this value is omitted, fromIndex
is 0
.
Note: the fromIndex
parameter can be a negative value.
In that case, the value wraps around from the last index.
Return value
The first index of the motion vector in the array; -1
if not found.
Examples
const mvarr = new MVArray(6);
for ( let i = 0; i < 6; i++ ) mvarr[i] = MV(i+2,i+2);
print(mvarr); // [2,2],[3,3],[4,4],[5,5],[6,6],[7,7]
print(mvarr.indexOf(MV(1,1))); // -1
print(mvarr.indexOf(MV(4,4))); // 2
print(mvarr.indexOf(MV(4,4), 1)); // 2
print(mvarr.indexOf(MV(4,4), 2)); // 2
print(mvarr.indexOf(MV(4,4), 3)); // -1
print(mvarr.fill(MV(4,4))); // [4,4],[4,4],[4,4],[4,4],[4,4],[4,4]
print(mvarr.indexOf(MV(4,4))); // 0
MVArray.prototype.lastIndexOf()
The lastIndexOf()
method returns the last index at which a given
motion vector searchMV
can be found in the array (starting from the
optional fromIndex
argument), or -1
if it is not present.
Syntax
lastIndexOf(searchMV)
lastIndexOf(searchMV, fromIndex)
Parameters
searchMV
is the motion vector to search for in the array.
fromIndex
(optional) specifies which index to start the search from.
If this value is omitted, fromIndex
is 0
.
Note: the fromIndex
parameter can be a negative value.
In that case, the value wraps around from the last index.
Return value
The last index of the motion vector in the array; -1
if not found.
Examples
const mvarr = new MVArray(6);
for ( let i = 0; i < 6; i++ ) mvarr[i] = MV(i+2,i+2);
print(mvarr); // [2,2],[3,3],[4,4],[5,5],[6,6],[7,7]
print(mvarr.lastIndexOf(MV(1,1))); // -1
print(mvarr.lastIndexOf(MV(4,4))); // 2
print(mvarr.lastIndexOf(MV(4,4), 1)); // -1
print(mvarr.lastIndexOf(MV(4,4), 2)); // 2
print(mvarr.lastIndexOf(MV(4,4), 3)); // 2
print(mvarr.fill(MV(4,4))); // [4,4],[4,4],[4,4],[4,4],[4,4],[4,4]
print(mvarr.lastIndexOf(MV(4,4))); // 5
MVArray.prototype.includes()
The includes()
method determines whether an array includes a certain
motion vector searchMV
(starting from the optional fromIndex
argument), returning true
or false
as appropriate.
Syntax
includes(searchMV)
includes(searchMV, fromIndex)
Parameters
searchMV
is the motion vector to search for in the array.
fromIndex
(optional) specifies which index to start the search from.
If this value is omitted, fromIndex
is 0
.
Note: the fromIndex
parameter can be a negative value.
In that case, the value wraps around from the last index.
Return value
true
or false
.
Examples
const mvarr = new MVArray(6);
for ( let i = 0; i < 6; i++ ) mvarr[i] = MV(i+2,i+2);
print(mvarr); // [2,2],[3,3],[4,4],[5,5],[6,6],[7,7]
print(mvarr.includes(MV(1,1))); // false
print(mvarr.includes(MV(2,2))); // true
MVArray.prototype.reduce()
The reduce()
method, much like forEach()
, calls the callbackFn
function for each motion vector of the array. The difference here is an
extra argument accumulator
being passed to callbackFn
, which is
actually just the return value from the previous call to the function.
Syntax
reduce(callbackFn(accumulator, mv, index, array))
reduce(callbackFn(accumulator, mv, index, array), initialValue)
Parameters
callbackFn
is a function (inline
, arrow
, or normal) that is
called for each motion vector of the array.
The function’s parameters are accumulator
(the return value from the
previous call to the function), mv
(the current motion vector being
tested), index
(the index it corresponds to in the array), and
array
(the array itself).
The function should return an updated accumulator
.
initialValue
(optional) is the value to be passed to the first call
to callbackFn
.
If this value is omitted, initialValue
is the first motion vector
from the array, and callbackFn
starts being called from the second
motion vector of the array.
Return value
The accumulator
.
Examples
const mvarr = new MVArray(6);
for ( let i = 0; i < 6; i++ ) mvarr[i] = MV(i/2,i/2);
print(mvarr); // [0,0],[0,0],[1,1],[1,1],[2,2],[2,2]
let mvsum = mvarr.reduce((acc, mv) => acc.add(mv));
print(mvsum); // [6,6] (sum of all motion vectors)
// find extreme values (accumulator is [ smallest, largest ], where
// smallest and largest are arrays with [ index, new MV() ]).
function find_extremes(acc, mv, i) {
// first iteration, return initial value
if ( acc === null )
return [ [ new MV(mv), i ], [ new MV(mv), i ] ];
// subsequente iterations, update accumulator with largest and
// smallest values
if ( mv.magnitude_sq() < acc[0][0].magnitude_sq() )
acc[0] = [ new MV(mv), i ];
if ( mv.magnitude_sq() > acc[1][0].magnitude_sq() )
acc[1] = [ new MV(mv), i ];
return acc;
}
// note the use of initialValue being set to null!
e = mvarr.reduce(find_extremes, null);
print(`the smallest motion vector '${e[0][0]}' is at index ${e[0][1]}`);
// the smallest motion vector '[0,0]' is at index 0
print(`the largest motion vector '${e[1][0]}' is at index ${e[1][1]}`);
// the largest motion vector '[2,2]' is at index 4
MVArray.prototype.reduceRight()
The reduceRight()
method does the same thing as the reduce()
method, but it runs through the array from right-to-left instead
of left-to-right.
The reduceRight()
method, much like forEach()
, calls the
callbackFn
function for each motion vector of the array (starting
with the last motion vector). The difference here is an extra argument
accumulator
being passed to callbackFn
, which is actually just the
return value from the previous call to the function.
Syntax
reduceRight(callbackFn(accumulator, mv, index, array))
reduceRight(callbackFn(accumulator, mv, index, array), initialValue)
Parameters
callbackFn
is a function (inline
, arrow
, or normal) that is
called for each motion vector of the array, starting from the last
motion vector and going down to the first motion vector.
The function’s parameters are accumulator
(the return value from the
previous call to the function), mv
(the current motion vector being
tested), index
(the index it corresponds to in the array), and
array
(the array itself).
The function should return an updated accumulator
.
initialValue
(optional) is the value to be passed to the first call
to callbackFn
.
If this value is omitted, initialValue
is the last motion vector from
the array, and callbackFn
starts being called from the penultimate
motion vector of the array.
Return value
The accumulator
.
Examples
const mvarr = new MVArray(6);
for ( let i = 0; i < 6; i++ ) mvarr[i] = MV(i/2,i/2);
print(mvarr); // [0,0],[0,0],[1,1],[1,1],[2,2],[2,2]
let mvsum = mvarr.reduceRight((acc, mv) => acc.add(mv));
print(mvsum); // [6,6] (sum of all motion vectors)
// find extreme values (accumulator is [ smallest, largest ], where
// smallest and largest are arrays with [ new MV(), index ]).
function find_extremes(acc, mv, i) {
// first iteration, return initial value
if ( acc === null )
return [ [ new MV(mv), i ], [ new MV(mv), i ] ];
// subsequente iterations, update accumulator with largest and
// smallest values
if ( mv.magnitude_sq() < acc[0][0].magnitude_sq() )
acc[0] = [ new MV(mv), i ];
if ( mv.magnitude_sq() > acc[1][0].magnitude_sq() )
acc[1] = [ new MV(mv), i ];
return acc;
}
// note the use of initialValue being set to null!
e = mvarr.reduceRight(find_extremes, null);
print(`the smallest motion vector '${e[0][0]}' is at index ${e[0][1]}`);
// the smallest motion vector '[0,0]' is at index 1
print(`the largest motion vector '${e[1][0]}' is at index ${e[1][1]}`);
// the largest motion vector '[2,2]' is at index 5
// Note that the smallest and largest indexes are 1 and 5 instead of
// 0 and 4 like it was with reduce(), because of the order the array
// is scanned.
MVArray.prototype.values()
The values()
method returns an array iterator
object that contains
the values for each index in the array.
Syntax
values()
Return value
The new array iterator
.
Examples
const mvarr = new MVArray(4);
for ( let i = 0; i < 4; i++ ) mvarr[i] = MV(i+2,i+2);
print(mvarr); // [2,2],[3,3],[4,4],[5,5]
for ( const mv of mvarr.values() ) print(mv);
// [2,2]
// [3,3]
// [4,4]
// [5,5]
MVArray.prototype.keys()
The keys()
method returns an array iterator
object that contains
the keys for each index in the array.
Syntax
keys()
Return value
The new array iterator
.
Examples
const mvarr = new MVArray(4);
for ( let i = 0; i < 4; i++ ) mvarr[i] = MV(i+2,i+2);
print(mvarr); // [2,2],[3,3],[4,4],[5,5]
for ( const key of mvarr.keys() ) print(key);
// 0
// 1
// 2
// 3
MVArray.prototype.entries()
The entries()
method returns an array iterator
object that contains
the key/value pairs for each index in the array.
Syntax
entries()
Return value
The new array iterator
.
Examples
const mvarr = new MVArray(4);
for ( let i = 0; i < 4; i++ ) mvarr[i] = MV(i+2,i+2);
print(mvarr); // [2,2],[3,3],[4,4],[5,5]
for ( const entry of mvarr.entries() ) print(entry);
// 0,[2,2]
// 1,[3,3]
// 2,[4,4]
// 3,[5,5]
MVArray.prototype.largest_sq()
The largest_sq()
method returns an [ index, mv.magnitude_sq() ]
array with the index and the value of the squared magnitude of the
motion vector with the largest squared magnitude in the array.
Syntax
largest_sq()
Return value
An [ index, mv.magnitude_sq() ]
array of the largest motion vector.
Examples
const mvarr = new MVArray(4);
for ( let i = 0; i < 4; i++ ) mvarr[i] = MV(i+2,i+2);
print(mvarr); // [2,2],[3,3],[4,4],[5,5]
print(mvarr.largest_sq()); // 3,50
// array element 3 ([5,5]) has a squared magnitude of 5*5+5*5 = 50.
MVArray.prototype.smallest_sq()
The smallest_sq()
method returns an [ index, mv.magnitude_sq() ]
array with the index and the value of the squared magnitude of the
motion vector with the smallest squared magnitude in the array.
Syntax
smallest_sq()
Return value
An [ index, mv.magnitude_sq() ]
array of the smallest motion vector.
Examples
const mvarr = new MVArray(4);
for ( let i = 0; i < 4; i++ ) mvarr[i] = MV(i+2,i+2);
print(mvarr); // [2,2],[3,3],[4,4],[5,5]
print(mvarr.smallest_sq()); // 0,8
// array element 0 ([2,2]) has a squared magnitude of 2*2+2*2 = 8.
MVArray.prototype.swap_hv()
The swap_hv()
method swaps the horizontal and vertical elements of
all the motion vectors in the array in-place.
If you want to swap just a small chunk of the array, use the
subarray()
method and call swap_hv()
on that.
Syntax
swap_hv()
Return value
The modified motion vector array.
Examples
const mvarr = new MVArray(4);
for ( let i = 0; i < 4; i++ ) mvarr[i] = MV(i,-i);
print(mvarr); // [0,0],[1,-1],[2,-2],[3,-3]
print(mvarr.swap_hv()); // [0,0],[-1,1],[-2,2],[-3,3]
print(mvarr); // [0,0],[-1,1],[-2,2],[-3,3]
MVArray.prototype.clear()
The clear()
method zeroes the horizontal and vertical elements of all
of the motion vectors in the array in-place.
If you want to clear just a small chunk of the array, use the
subarray()
method and call clear()
on that.
Syntax
clear()
Return value
The modified motion vector array.
Examples
const mvarr = new MVArray(4);
for ( let i = 0; i < 4; i++ ) mvarr[i] = MV(i,-i);
print(mvarr); // [0,0],[1,-1],[2,-2],[3,-3]
print(mvarr.clear()); // [0,0],[0,0],[0,0],[0,0]
print(mvarr); // [0,0],[0,0],[0,0],[0,0]
MVArray.prototype.mathOp()
There is no real mathOp()
method in the MVArray
prototype.
Instead, there are a bunch of math operation methods, listed below:
add()
sub()
mul()
div()
assign()
The arguments passed to the methods above should first start with a source of motion vectors, and then an optional mask.
The source of motion vectors should be either an MVArray
(of the same
length as the array), null
(only for the assign
operation), an
MV
constant, an MV
object, or an MVRef
object, or a motion vector
specified in terms of its horizontal and vertical components.
The mask
argument is optional, and it must be of type MVMask
. It
must have the same length as the array. If a mask is supplied, the
operation is only applied to the motion vectors selected by the mask.
The operations do exactly what the names mean. add()
will add the
argument to the motion vector array, sub()
will subtract, mul()
will multiply, div()
will divide (rounding to nearest integer), and
assign()
will assign (just copy).
If the motion vector source is a single motion vector, that motion
vector will be applied to the entire array. If the motion vector source
is an MVArray
, each element in the MVArray
will be applied to the
corresponding element of the array.
There are also similar methods that operate only on the horizontal or
vertical elements of the motion vector array. These methods have either
_h
(horizontal) or _v
(vertical) appended to the names.
These methods also take a mandatory source of motion vectors as
argument, and then an optional mask. They can also take only one
argument (the horizontal
or vertical
element) as motion vector
source.
They are listed below:
add_h()
sub_h()
mul_h()
div_h()
assign_h()
add_v()
sub_v()
mul_v()
div_v()
assign_v()
Syntax
mathOp(mvarray)
mathOp(null)
mathOp(mv)
mathOp(horizontal, vertical)
mathOp(mvarray, mask)
mathOp(null, mask)
mathOp(mv, mask)
mathOp(horizontal, vertical, mask)
mathOp_h(mvarray)
mathOp_h(mv)
mathOp_h(horizontal, vertical)
mathOp_h(horizontal)
mathOp_h(mvarray, mask)
mathOp_h(mv, mask)
mathOp_h(horizontal, vertical, mask)
mathOp_h(horizontal, mask)
mathOp_v(mvarray)
mathOp_v(mv)
mathOp_v(horizontal, vertical)
mathOp_v(vertical)
mathOp_v(mvarray, mask)
mathOp_v(mv, mask)
mathOp_v(horizontal, vertical, mask)
mathOp_v(vertical, mask)
Parameters
mvarray
(optional) is an MVArray
object.
mv
(optional) must be either an MV
constant, an MV
object, or an MVRef
object.
horizontal
(optional) is the horizontal component of the motion vector.
vertical
(optional) is the vertical component of the motion vector.
mask
(optional) is an MVMask
that specifies on which motion vectors
of the array the operation should be carried out on.
Return value
The modified motion vector array.
Examples
const mv12 = MV(1,2);
const mvarr = new MVArray(4);
for ( let i = 0; i < 4; i++ ) mvarr[i] = MV(i,i);
const mvarr2 = mvarr.dup().reverse();
const mvmask = new MVMask(4);
for ( let i = 0; i < 4; i++ ) mvmask[i] = (i&1);
print(mvarr2); // [3,3],[2,2],[1,1],[0,0]
print(mvmask); // false,true,false,true
// good luck keeping track of the value of the motion vectors!
print(mvarr); // [0,0],[1,1],[2,2],[3,3]
print("add"); // add
print(mvarr.add(mvarr2)); // [3,3],[3,3],[3,3],[3,3]
print(mvarr.add(mv12)); // [4,5],[4,5],[4,5],[4,5]
print(mvarr.add(2, 1)); // [6,6],[6,6],[6,6],[6,6]
print(mvarr.add(mvarr2, mvmask)); // [6,6],[8,8],[6,6],[6,6]
print(mvarr.add(mv12, mvmask)); // [6,6],[9,10],[6,6],[7,8]
print(mvarr.add(2, 1, mvmask)); // [6,6],[11,11],[6,6],[9,9]
print(mvarr.add_h(mvarr2)); // [9,6],[13,11],[7,6],[9,9]
print(mvarr.add_h(mv12)); // [10,6],[14,11],[8,6],[10,9]
print(mvarr.add_h(2, 1)); // [12,6],[16,11],[10,6],[12,9]
print(mvarr.add_h(2)); // [14,6],[18,11],[12,6],[14,9]
print(mvarr.add_h(mvarr2, mvmask)); // [14,6],[20,11],[12,6],[14,9]
print(mvarr.add_h(mv12, mvmask)); // [14,6],[21,11],[12,6],[15,9]
print(mvarr.add_h(2, 1, mvmask)); // [14,6],[23,11],[12,6],[17,9]
print(mvarr.add_h(2, mvmask)); // [14,6],[25,11],[12,6],[19,9]
print(mvarr.add_v(mvarr2)); // [14,9],[25,13],[12,7],[19,9]
print(mvarr.add_v(mv12)); // [14,11],[25,15],[12,9],[19,11]
print(mvarr.add_v(2, 1)); // [14,12],[25,16],[12,10],[19,12]
print(mvarr.add_v(2)); // [14,14],[25,18],[12,12],[19,14]
print(mvarr.add_v(mvarr2, mvmask)); // [14,14],[25,20],[12,12],[19,14]
print(mvarr.add_v(mv12, mvmask)); // [14,14],[25,22],[12,12],[19,16]
print(mvarr.add_v(2, 1, mvmask)); // [14,14],[25,23],[12,12],[19,17]
print(mvarr.add_v(2, mvmask)); // [14,14],[25,25],[12,12],[19,19]
print("sub"); // sub
print(mvarr.sub(mvarr2)); // [11,11],[23,23],[11,11],[19,19]
print(mvarr.sub(mv12)); // [10,9],[22,21],[10,9],[18,17]
print(mvarr.sub(2, 1)); // [8,8],[20,20],[8,8],[16,16]
print(mvarr.sub(mvarr2, mvmask)); // [8,8],[18,18],[8,8],[16,16]
print(mvarr.sub(mv12, mvmask)); // [8,8],[17,16],[8,8],[15,14]
print(mvarr.sub(2, 1, mvmask)); // [8,8],[15,15],[8,8],[13,13]
print(mvarr.sub_h(mvarr2)); // [5,8],[13,15],[7,8],[13,13]
print(mvarr.sub_h(mv12)); // [4,8],[12,15],[6,8],[12,13]
print(mvarr.sub_h(2, 1)); // [2,8],[10,15],[4,8],[10,13]
print(mvarr.sub_h(2)); // [0,8],[8,15],[2,8],[8,13]
print(mvarr.sub_h(mvarr2, mvmask)); // [0,8],[6,15],[2,8],[8,13]
print(mvarr.sub_h(mv12, mvmask)); // [0,8],[5,15],[2,8],[7,13]
print(mvarr.sub_h(2, 1, mvmask)); // [0,8],[3,15],[2,8],[5,13]
print(mvarr.sub_h(2, mvmask)); // [0,8],[1,15],[2,8],[3,13]
print(mvarr.sub_v(mvarr2)); // [0,5],[1,13],[2,7],[3,13]
print(mvarr.sub_v(mv12)); // [0,3],[1,11],[2,5],[3,11]
print(mvarr.sub_v(2, 1)); // [0,2],[1,10],[2,4],[3,10]
print(mvarr.sub_v(2)); // [0,0],[1,8],[2,2],[3,8]
print(mvarr.sub_v(mvarr2, mvmask)); // [0,0],[1,6],[2,2],[3,8]
print(mvarr.sub_v(mv12, mvmask)); // [0,0],[1,4],[2,2],[3,6]
print(mvarr.sub_v(2, 1, mvmask)); // [0,0],[1,3],[2,2],[3,5]
print(mvarr.sub_v(2, mvmask)); // [0,0],[1,1],[2,2],[3,3]
print("mul"); // mul
print(mvarr.mul(mvarr2)); // [0,0],[2,2],[2,2],[0,0]
print(mvarr.mul(mv12)); // [0,0],[2,4],[2,4],[0,0]
print(mvarr.mul(2, 1)); // [0,0],[4,4],[4,4],[0,0]
print(mvarr.mul(mvarr2, mvmask)); // [0,0],[8,8],[4,4],[0,0]
print(mvarr.mul(mv12, mvmask)); // [0,0],[8,16],[4,4],[0,0]
print(mvarr.mul(2, 1, mvmask)); // [0,0],[16,16],[4,4],[0,0]
print(mvarr.mul_h(mvarr2)); // [0,0],[32,16],[4,4],[0,0]
print(mvarr.mul_h(mv12)); // [0,0],[32,16],[4,4],[0,0]
print(mvarr.mul_h(2, 1)); // [0,0],[64,16],[8,4],[0,0]
print(mvarr.mul_h(2)); // [0,0],[128,16],[16,4],[0,0]
print(mvarr.mul_h(mvarr2, mvmask)); // [0,0],[256,16],[16,4],[0,0]
print(mvarr.mul_h(mv12, mvmask)); // [0,0],[256,16],[16,4],[0,0]
print(mvarr.mul_h(2, 1, mvmask)); // [0,0],[512,16],[16,4],[0,0]
print(mvarr.mul_h(2, mvmask)); // [0,0],[1024,16],[16,4],[0,0]
print(mvarr.mul_v(mvarr2)); // [0,0],[1024,32],[16,4],[0,0]
print(mvarr.mul_v(mv12)); // [0,0],[1024,64],[16,8],[0,0]
print(mvarr.mul_v(2, 1)); // [0,0],[1024,64],[16,8],[0,0]
print(mvarr.mul_v(2)); // [0,0],[1024,128],[16,16],[0,0]
print(mvarr.mul_v(mvarr2, mvmask)); // [0,0],[1024,256],[16,16],[0,0]
print(mvarr.mul_v(mv12, mvmask)); // [0,0],[1024,512],[16,16],[0,0]
print(mvarr.mul_v(2, 1, mvmask)); // [0,0],[1024,512],[16,16],[0,0]
print(mvarr.mul_v(2, mvmask)); // [0,0],[1024,1024],[16,16],[0,0]
print("div"); // div
print(mvarr.div(mvarr2)); // [0,0],[512,512],[16,16],[0,0]
print(mvarr.div(mv12)); // [0,0],[512,256],[16,8],[0,0]
print(mvarr.div(2, 1)); // [0,0],[256,256],[8,8],[0,0]
print(mvarr.div(mvarr2, mvmask)); // [0,0],[128,128],[8,8],[0,0]
print(mvarr.div(mv12, mvmask)); // [0,0],[128,64],[8,8],[0,0]
print(mvarr.div(2, 1, mvmask)); // [0,0],[64,64],[8,8],[0,0]
print(mvarr.div_h(mvarr2)); // [0,0],[32,64],[8,8],[0,0]
print(mvarr.div_h(mv12)); // [0,0],[32,64],[8,8],[0,0]
print(mvarr.div_h(2, 1)); // [0,0],[16,64],[4,8],[0,0]
print(mvarr.div_h(2)); // [0,0],[8,64],[2,8],[0,0]
print(mvarr.div_h(mvarr2, mvmask)); // [0,0],[4,64],[2,8],[0,0]
print(mvarr.div_h(mv12, mvmask)); // [0,0],[4,64],[2,8],[0,0]
print(mvarr.div_h(2, 1, mvmask)); // [0,0],[2,64],[2,8],[0,0]
print(mvarr.div_h(2, mvmask)); // [0,0],[1,64],[2,8],[0,0]
print(mvarr.div_v(mvarr2)); // [0,0],[1,32],[2,8],[0,0]
print(mvarr.div_v(mv12)); // [0,0],[1,16],[2,4],[0,0]
print(mvarr.div_v(2, 1)); // [0,0],[1,16],[2,4],[0,0]
print(mvarr.div_v(2)); // [0,0],[1,8],[2,2],[0,0]
print(mvarr.div_v(mvarr2, mvmask)); // [0,0],[1,4],[2,2],[0,0]
print(mvarr.div_v(mv12, mvmask)); // [0,0],[1,2],[2,2],[0,0]
print(mvarr.div_v(2, 1, mvmask)); // [0,0],[1,2],[2,2],[0,0]
print(mvarr.div_v(2, mvmask)); // [0,0],[1,1],[2,2],[0,0]
print("assign"); // assign
print(mvarr.assign(mvarr2)); // [3,3],[2,2],[1,1],[0,0]
print(mvarr.assign(mv12)); // [1,2],[1,2],[1,2],[1,2]
print(mvarr.assign(2, 1)); // [2,1],[2,1],[2,1],[2,1]
print(mvarr.assign(mvarr2, mvmask));// [2,1],[2,2],[2,1],[0,0]
print(mvarr.assign(mv12, mvmask)); // [2,1],[1,2],[2,1],[1,2]
print(mvarr.assign(3, 4, mvmask)); // [2,1],[3,4],[2,1],[3,4]
print(mvarr.assign_h(5)); // [5,1],[5,4],[5,1],[5,4]
print(mvarr.assign_h(6, mvmask)); // [5,1],[6,4],[5,1],[6,4]
print(mvarr.assign_h(7, 8, mvmask));// [5,1],[7,4],[5,1],[7,4]
print(mvarr.assign_v(5)); // [5,5],[7,5],[5,5],[7,5]
print(mvarr.assign_v(6, mvmask)); // [5,5],[7,6],[5,5],[7,6]
print(mvarr.assign_v(0, 9, mvmask));// [5,5],[7,9],[5,5],[7,9]
// the null argument is only allowed when assigning
print(mvarr.assign(null, mvmask)); // [5,5],null,[5,5],null
print(mvarr.assign(null)); // null,null,null,null
MVArray.prototype.compare()
The compare()
returns an MVMask
with the result from running the
provided compareFn()
function on all elements of the array.
Syntax
compare(compareFn(mv, index, array))
compare(compareFn(mv, index, array), thisArg)
Parameters
compareFn
is a function (inline
, arrow
, or normal) that is
called for each motion vector of the array.
The function’s parameters are mv
(an MVRef
to the current motion
vector being tested), index
(the index it corresponds to in the
array), and array
(the array itself).
The function should return either true
or false
.
thisArg
(optional) is a value to use as this
when executing
compareFn
.
Return value
An MVMask
filled with the results from each comparison.
Examples
const mvarr = new MVArray(6);
for ( let i = 0; i < 6; i++ ) mvarr[i] = MV(i,i);
print(mvarr); // [0,0],[1,1],[2,2],[3,3],[4,4],[5,5]
function is_even(mv, i, arr) {
return !(mv[0] & 1) && !(mv[1] & 1);
}
const mvmask = mvarr.compare(is_even);
print(mvmask instanceof MVMask); // true
print(mvmask); // true,false,true,false,true,false
MVArray.prototype.compareOp()
There is no real compareOp()
method in the MVArray
prototype.
Instead, there are a bunch of comparison methods, listed below:
compare_eq()
compare_neq()
compare_gt()
compare_gte()
compare_lt()
compare_lte()
The difference between the compare()
method and the compareOp()
methods is that compare()
takes a function, and compareOp()
will
run some predefined comparisons, which should be much faster than
calling a function for each iteration.
The arguments passed to the methods above should be either an MVArray
(of the same length as the array), null
(only for the compare_eq()
and compare_neq()
methods), specified as an MV
constant, an MV
object, or an MVRef
object, a motion vector specified in terms of
its horizontal and vertical components, or a single integer, which will
be used as the squared magnitude of a motion vector.
The behaviour of each method is defined as follows:
compare_eq()
tests forequality
(==
).compare_neq()
tests forinequality
(!=
).compare_gt()
tests forgreater than
(>
)compare_gte()
tests forgreater than or equal
(>=
).compare_lt()
tests forless than
(<
).compare_lte()
tests forless than or equal
(<
).
There are also similar methods that operate only on the horizontal or
vertical elements of the motion vector. These methods take only one
argument (the horizontal
or vertical
element), and have either
_h
(horizontal) or _v
(vertical) appended to the method names.
They are listed below:
compare_eq_h()
compare_neq_h()
compare_gt_h()
compare_gte_h()
compare_lt_h()
compare_lte_h()
compare_eq_v()
compare_neq_v()
compare_gt_v()
compare_gte_v()
compare_lt_v()
compare_lte_v()
Syntax
compareOp(null)
compareOp(mvarray)
compareOp(mv)
compareOp(magnitude_sq)
compareOp(horizontal, vertical)
compareOp_h(horizontal)
compareOp_v(vertical)
Parameters
mvarray
(optional) is an MVArray
object.
mv
(optional) must be either an MV
constant, an MV
object, or an MVRef
object.
magnitude_sq
(optional) is the squared magnitude to compare against.
horizontal
(optional) is the horizontal component of the motion vector.
vertical
(optional) is the vertical component of the motion vector.
Return value
An MVMask
filled with the results from each comparison.
Examples
let mvarray = new MVArray(7);
for ( let i = 0; i < 6; i++ ) mvarray[i] = MV(i,i%3);
mvarray[6] = null;
let mvarr2 = new MVArray(7);
for ( let i = 0; i < 7; i++ ) mvarr2[i] = MV(i,i%2);
mv11 = new MV(1,1);
let mg_sq = 8;
print(mv11); // [1,1]
print(mvarray); // [0,0],[1,1],[2,2],[3,0],[4,1],[5,2],null
print(mvarr2); // [0,0],[1,1],[2,0],[3,1],[4,0],[5,1],[6,0]
print("compare_eq"); // compare_eq
print(mvarray.compare_eq(mvarr2)); // true,true,false,false,false,false,false
print(mvarray.compare_eq(mv11)); // false,true,false,false,false,false,false
print(mvarray.compare_eq(0,0)); // true,false,false,false,false,false,false
print(mvarray.compare_eq(mg_sq)); // false,false,true,false,false,false,false
print(mvarray.compare_eq(null)); // false,false,false,false,false,false,true
print(mvarray.compare_eq_h(1)); // false,true,false,false,false,false,false
print(mvarray.compare_eq_h(2)); // false,false,true,false,false,false,false
print(mvarray.compare_eq_v(1)); // false,true,false,false,true,false,false
print(mvarray.compare_eq_v(2)); // false,false,true,false,false,true,false
print("compare_neq"); // compare_neq
print(mvarray.compare_neq(mvarr2)); // false,false,true,true,true,true,true
print(mvarray.compare_neq(mv11)); // true,false,true,true,true,true,true
print(mvarray.compare_neq(0,0)); // false,true,true,true,true,true,true
print(mvarray.compare_neq(mg_sq)); // true,true,false,true,true,true,true
print(mvarray.compare_neq(null)); // true,true,true,true,true,true,false
print(mvarray.compare_neq_h(1)); // true,false,true,true,true,true,true
print(mvarray.compare_neq_h(2)); // true,true,false,true,true,true,true
print(mvarray.compare_neq_v(1)); // true,false,true,true,false,true,true
print(mvarray.compare_neq_v(2)); // true,true,false,true,true,false,true
print("compare_gt"); // compare_gt
print(mvarray.compare_gt(mvarr2)); // false,false,true,false,true,true,false
print(mvarray.compare_gt(mv11)); // false,false,true,true,true,true,false
print(mvarray.compare_gt(0,0)); // false,true,true,true,true,true,false
print(mvarray.compare_gt(mg_sq)); // false,false,false,true,true,true,false
print(mvarray.compare_gt_h(1)); // false,false,true,true,true,true,false
print(mvarray.compare_gt_h(2)); // false,false,false,true,true,true,false
print(mvarray.compare_gt_v(1)); // false,false,true,false,false,true,false
print(mvarray.compare_gt_v(2)); // false,false,false,false,false,false,false
print("compare_gte"); // compare_gte
print(mvarray.compare_gte(mvarr2)); // true,true,true,false,true,true,false
print(mvarray.compare_gte(mv11)); // false,true,true,true,true,true,false
print(mvarray.compare_gte(0,0)); // true,true,true,true,true,true,false
print(mvarray.compare_gte(mg_sq)); // false,false,true,true,true,true,false
print(mvarray.compare_gte_h(1)); // false,true,true,true,true,true,false
print(mvarray.compare_gte_h(2)); // false,false,true,true,true,true,false
print(mvarray.compare_gte_v(1)); // false,true,true,false,true,true,false
print(mvarray.compare_gte_v(2)); // false,false,true,false,false,true,false
print("compare_lt"); // compare_lt
print(mvarray.compare_lt(mvarr2)); // false,false,false,true,false,false,false
print(mvarray.compare_lt(mv11)); // true,false,false,false,false,false,false
print(mvarray.compare_lt(0,0)); // false,false,false,false,false,false,false
print(mvarray.compare_lt(mg_sq)); // true,true,false,false,false,false,false
print(mvarray.compare_lt_h(1)); // true,false,false,false,false,false,false
print(mvarray.compare_lt_h(2)); // true,true,false,false,false,false,false
print(mvarray.compare_lt_v(1)); // true,false,false,true,false,false,false
print(mvarray.compare_lt_v(2)); // true,true,false,true,true,false,false
print("compare_lte"); // compare_lte
print(mvarray.compare_lte(mvarr2)); // true,true,false,true,false,false,false
print(mvarray.compare_lte(mv11)); // true,true,false,false,false,false,false
print(mvarray.compare_lte(0,0)); // true,false,false,false,false,false,false
print(mvarray.compare_lte(mg_sq)); // true,true,true,false,false,false,false
print(mvarray.compare_lte_h(1)); // true,true,false,false,false,false,false
print(mvarray.compare_lte_h(2)); // true,true,true,false,false,false,false
print(mvarray.compare_lte_v(1)); // true,true,false,true,true,false,false
print(mvarray.compare_lte_v(2)); // true,true,true,true,true,true,false
MVMask.prototype.fill()
The fill()
method fills all the elements of a mask array from an
start
index to an end
index with the boolean value
.
Syntax
fill(value)
fill(value, start)
fill(value, start, end)
Parameters
value
boolean to fill the mask array with.
start
(optional) is the index where the filling starts.
If this value is omitted, start
is 0
.
end
(optional) is the index where the filling ends.
If this value is omitted, end
is length
.
Note: the start
and end
parameters can be negative values.
In that case, the values wrap around from the last index.
Return value
The modified mask array.
Examples
const mvmask = new MVMask(8);
print(mvmask); // true,true,true,true,true,true,true,true
print(mvmask.fill(false)); // false,false,false,false,false,false,false,false
print(mvmask.fill(true, 4)); // false,false,false,false,true,true,true,true
print(mvmask.fill(true, 2, 3)); // false,false,true,false,true,true,true,true
print(mvmask.fill(false, -4, -2)); // false,false,true,false,false,false,true,true
print(mvmask.fill(false, -4, 5)); // false,false,true,false,false,false,true,true
MVMask.prototype.forEach()
The forEach()
method calls the callbackFn
function for each element
of the mask array. It has the same functionality as calling the code
below, but it’s slightly faster.
for ( let i = 0; i < mvmask.length; i++ )
callbackFn(mvmask[i], i, mvmask);
Syntax
forEach(callbackFn(element, index, array))
forEach(callbackFn(element, index, array), thisArg)
Parameters
callbackFn
is a function (inline
, arrow
, or normal) that is
called for each element of the mask array.
The function’s parameters are element
(the current element being
tested), index
(the index it corresponds to in the mask array), and
array
(the mask array itself).
thisArg
(optional) is a value to use as this
when executing
callbackFn
.
Return value
undefined
.
Examples
const mvmask = new MVMask(6);
print(mvmask); // true,true,true,true,true,true
mvmask.forEach((el,i,arr) => arr[i] = i&1);
print(mvmask); // false,true,false,true,false,true
MVMask.prototype.not()
The not()
method inverts all the elements of a mask array from an
start
index to an end
index.
Syntax
not()
not(start)
not(start, end)
Parameters
start
(optional) is the index where the filling starts.
If this value is omitted, start
is 0
.
end
(optional) is the index where the filling ends.
If this value is omitted, end
is length
.
Note: the start
and end
parameters can be negative values.
In that case, the values wrap around from the last index.
Return value
The modified mask array.
Examples
const mvmask = new MVMask(8);
print(mvmask); // true,true,true,true,true,true,true,true
print(mvmask.not()); // false,false,false,false,false,false,false,false
print(mvmask.not(4)); // false,false,false,false,true,true,true,true
print(mvmask.not(2, 3)); // false,false,true,false,true,true,true,true
print(mvmask.not(-4, -2)); // false,false,true,false,false,false,true,true
print(mvmask.not(-4, 5)); // false,false,true,false,true,false,true,true
MVMask.prototype.and()
The and
method performs an AND
binary operator with the mvmask
argument.
Syntax
and(mvmask)
Parameters
mvmask
is the source mask array for the binary operation.
Return value
The modified mask array.
Examples
const mvmaskx = new MVMask(8);
for ( let i = 0; i < 8; i++ ) mvmaskx[i] = (i & 1);
const mvmask = new MVMask(8);
print(mvmask); // true,true,true,true,true,true,true,true
print(mvmaskx); // false,true,false,true,false,true,false,true
print(mvmask.and(mvmaskx)); // false,true,false,true,false,true,false,true
MVMask.prototype.or()
The or
method performs an OR
binary operator with the mvmask
argument.
Syntax
or(mvmask)
Parameters
mvmask
is the source mask array for the binary operation.
Return value
The modified mask array.
Examples
const mvmaskx = new MVMask(8);
for ( let i = 0; i < 8; i++ ) mvmaskx[i] = (i & 1);
const mvmask = new MVMask(8);
print(mvmask.fill(false)); // false,false,false,false,false,false,false,false
print(mvmaskx); // false,true,false,true,false,true,false,true
print(mvmask.or(mvmaskx)); // false,true,false,true,false,true,false,true
MVMask.prototype.xor()
The xor
method performs an XOR
binary operator with the mvmask
argument.
Syntax
xor(mvmask)
Parameters
mvmask
is the source mask array for the binary operation.
Return value
The modified mask array.
Examples
const mvmaskx = new MVMask(8);
for ( let i = 0; i < 8; i++ ) mvmaskx[i] = (i & 1);
const mvmask = new MVMask(8);
print(mvmask); // true,true,true,true,true,true,true,true
print(mvmaskx); // false,true,false,true,false,true,false,true
print(mvmask.xor(mvmaskx)); // true,false,true,false,true,false,true,false
print(mvmask.xor(mvmaskx)); // true,true,true,true,true,true,true,true
print(mvmask.xor(mvmask)); // false,false,false,false,false,false,false,false