I have a domain D, and I want to use it to index several matrices A. Something of the form
var dom: domain(1) = {0..5};
var mats: [dom] <?>;
var a0 = [[0.0, 0.1, 0.2], [0.3, 0.4, 0.5]];
var a1 = [[1.0, 1.1, 1.2, 1.3], [1.4, 1.5, 1.6, 1.7]];
mats[0] = a0;
mats[1] = a1;
Each a will be 2D but have different sizes. Yes, some of these will be sparse (but need not be for purposes of this question)
== UPDATE ==
For clarity, I have a series of layers (it's a neural net), say 1..15. I created var layerDom = {1..15} Each layer has multiple objects associated with it, like error so I have
var errors: [layerDom] real; // Just a number
And I'd like to have
var Ws: [layerDom] <matrixy thingy>; // Weight matrices all of different shape.
As of Chapel 1.15 there isn't an elegant way to create an array of arrays where the inner arrays have different sizes. This is because the inner arrays all share the same domain, meaning that changing one array's domain changes all arrays.
To achieve the desired effect, you need to create an array of records/classes that contain an array:
record Weight {
var D : domain(2);
var A : [D] real;
}
var layers = 4;
var weights : [1..layers] Weight;
for i in 1..layers {
weights[i].D = {1..i, 1..i};
weights[i].A = i;
}
for w in weights do writeln(w.A, "\n");
// 1.0
//
// 2.0 2.0
// 2.0 2.0
//
// 3.0 3.0 3.0
// 3.0 3.0 3.0
// 3.0 3.0 3.0
//
// 4.0 4.0 4.0 4.0
// 4.0 4.0 4.0 4.0
// 4.0 4.0 4.0 4.0
// 4.0 4.0 4.0 4.0
//
Related
I'm actually getting started on a small project about music visualization, using Web Audio API and D3. I use the getByteFrequencyData() method as follows (implementation has been modified for clarity. This is just a "setup model"):
const ctx = new (window.AudioContext || window.webkitAudioContext)()
const analyzer = ctx.createAnalyser()
const src = ctx.createMediaElementSource(audioPlayer)
analyzer.fftSize = 512
src.connect(analyzer)
src.connect(ctx.destination)
//...
const getFrequencyData = () => {
audioAnimationFrameId.current = requestAnimationFrame(getFrequencyData)
const bufferLength = audioAnalyzer.frequencyBinCount
const data = new Uint8Array(bufferLength) // 256
audioAnalyzer.getByteFrequencyData(data)
return data
}
if (audioAnalyzer && isAudioPlaying) getFrequencyData()
My problem here, is that on my Uint8Array I'm getting a lot of "0" (mostly at the end of the array) which breaks my radial chart (as the D3 scale domain depends on data array length). I understood that these values represents decibels at some frequency, but is this normal to get all these zeros at the end?
I'm guessing I may have missed some configuration on my analyser, but after a lot of tests I wasn't able to find any solution... Did I miss something, or are these values correct, and finally it would be the D3 scale that I should change?
Here are my D3 scales:
const angle = scaleLinear({
domain: [0, 256], // NB: the array length
range: [0, Math.PI * 2]
})
const radius = scaleLinear({
domain: [0, 255], // NB: frequency data goes from 0 to 255
range: [0, (DIAMETER / 2)]
})
If someone could help me to understand these strange results, it would be really great!
Thx a lot!
See the spec for getByteFrequencyData. The formula there explains why the values are zero. Basically at the higher frequencies, the actual dB values fall below dB_min, so it's clamped to zero. If you don't want this and it's ok to have floating-point values, use getFloatFrequencyData.
I am creating a simple THREE.PlaneBufferGeometry using Threejs. The surface is a geologic surface in the earth.
This surface has local gaps or 'holes' in it represented by NaN's. I have read another similar, but older, post where the suggestion was to fill the position Z component with 'undefined' rather than NaN. I tried that but get this error:
THREE.BufferGeometry.computeBoundingSphere(): Computed radius is NaN. The "position" attribute is likely to have NaN values.
PlaneBufferGeometry {uuid: "8D8EFFBF-7F10-4ED5-956D-5AE1EAD4DD41", name: "", type: "PlaneBufferGeometry", index: Uint16BufferAttribute, attributes: Object, …}
Here is the TypeScript function that builds the surface:
AddSurfaces(result) {
let surfaces: Surface[] = result;
if (this.surfaceGroup == null) {
this.surfaceGroup = new THREE.Group();
this.globalGroup.add(this.surfaceGroup);
}
surfaces.forEach(surface => {
var material = new THREE.MeshPhongMaterial({ color: 'blue', side: THREE.DoubleSide });
let mesh: Mesh2D = surface.arealMesh;
let values: number[][] = surface.values;
let geometry: PlaneBufferGeometry = new THREE.PlaneBufferGeometry(mesh.width, mesh.height, mesh.nx - 1, mesh.ny - 1);
var positions = geometry.getAttribute('position');
let node: number = 0;
// Surfaces in Three JS are ordered from top left corner x going fastest left to right
// and then Y ('j') going from top to bottom. This is backwards in Y from how we do the
// modelling in the backend.
for (let j = mesh.ny - 1; j >= 0; j--) {
for (let i = 0; i < mesh.nx; i++) {
let value: number = values[i][j];
if(!isNaN(values[i][j])) {
positions.setZ(node, -values[i][j]);
}
else {
positions.setZ(node, undefined); /// This does not work? Any ideas?
}
node++;
}
}
geometry.computeVertexNormals();
var plane = new THREE.Mesh(geometry, material);
plane.receiveShadow = true;
plane.castShadow = true;
let xOrigin: number = mesh.xOrigin;
let yOrigin: number = mesh.yOrigin;
let cx: number = xOrigin + (mesh.width / 2.0);
let cy: number = yOrigin + (mesh.height / 2.0);
// translate point to origin
let tempX: number = xOrigin - cx;
let tempY: number = yOrigin - cy;
let azi: number = mesh.azimuth;
let aziRad = azi * Math.PI / 180.0;
// now apply rotation
let rotatedX: number = tempX * Math.cos(aziRad) - tempY * Math.sin(aziRad);
let rotatedY: number = tempX * Math.sin(aziRad) + tempY * Math.cos(aziRad);
cx += (tempX - rotatedX);
cy += (tempY - rotatedY);
plane.position.set(cx, cy, 0.0);
plane.rotateZ(aziRad);
this.surfaceGroup.add(plane);
});
this.UpdateCamera();
this.animate();
}
Thanks!
I have read another similar, but older, post where the suggestion was to fill the position Z component with 'undefined' rather than NaN.
Using undefined will fail in the same way like using NaN. BufferGeometry.computeBoundingSphere() computes the radius based on Vector3.distanceToSquared(). If you call this method with a vector that contains no valid numerical data, NaN will be returned.
Hence, you can't represent the gaps in a geometry with NaN or undefined position data. The better way is to generate a geometry which actually represents the geometry of your geologic surface. Using ShapeBufferGeometry might be a better candidate since shapes do support the concept of holes.
three.js r117
THREE.PlaneBufferGeometry:: parameters: {
width: number;
height: number;
widthSegments: number;
heightSegments: number;
};
widthSegments or heightSegments should be greater 1 ,if widthSegments < 1 ,widthSegments may be equal 0 or nan.
In my case, it was happening when I tried to create a beveled shape based on a single vector or a bunch of identical vectors - so there was only a single point. Filtering out such shapes solved the issue.
I'm writing an export script (ruby) in SketchUp, and I'm having trouble applying the same transformation in Three.js side, so that objects have the same rotation in Three.js as they appear in SketchUp.
I can read the rotation using the SketchUp Transformation class: http://www.sketchup.com/intl/en/developer/docs/ourdoc/transformation.php
I can get these kind of values from a rotated component that I pass to my Three.js code. All are Vectors in the form of X, Y, Z
xaxis: 0.0157771536190692,-0.0,-0.0199058138160762
yaxis: -0.0199058138160762,0.0,-0.0157771536190692
zaxis: 0.0,0.0254,-0.0
origin: 1.4975125146729,0.0,-1.25735397455338
Objects are positioned correctly if I just copy the values from origin to Object3D.position. But I have no idea how to apply the xaxis, yaxis and zaxis values to Object3D.rotation.
Three.js has various ways to rotate a model, via Matrix manipulation, quaternion, angles, radians and whatnot. But how to set object rotation using those axis values?
EDIT:
SketchUp Transformation provides also a .to_a (to array) method, which I think is supposed to return a 16 element matrix. I tried to use that in Three.js:
// tm is from SketchUp:Transformation to_a
var tm = "0.621147780278315,0.783693457325836,-0.0,0.0,-0.783693457325836,0.621147780278315,0.0,0.0,0.0,0.0,1.0,0.0,58.9571856170433,49.5021249824165,0.0,1.0";
tm = tm.split(",");
for (var i = 0; i < tm.length; i++) {
tm[i] = tm[i] * 1.0;
}
var matrix = new THREE.Matrix4(tm[0], tm[1], tm[2], tm[3], tm[4], tm[5], tm[6], tm[7], tm[8], tm[9], tm[10], tm[11], tm[12], tm[13], tm[14], tm[15]);
obj.applyMatrix(matrix);
This results in a total mess however, so there's still something wrong.
Based on information here: http://sketchucation.com/forums/viewtopic.php?f=180&t=46944&p=419606&hilit=matrix#p419606
I was able to construct a working Matrix4. I think the problem was both in unit scales (see the .to_m conversion in some of the elements) and the order of matrix array elements. In Sketchup:
tr = transformation.to_a
trc = [tr[0],tr[8],-(tr[4]),tr[12].to_m, tr[2],tr[10],-(tr[6]),tr[14].to_m, -(tr[1]),-(tr[9]),tr[5],-(tr[13].to_m), 0.0, 0.0, 0.0, 1.0] # the last 4 values are unused in Sketchup
el.attributes["tm"] = trc.join(",") # rotation and scale matrix
el.attributes["to"] = convertscale(transformation.origin) # position
In Three.js
var origin = this.parsevector3(node.getAttribute("to"));
obj.position = origin;
var tm = node.getAttribute("tm");
tm = tm.split(",");
for (var i = 0; i < tm.length; i++) {
tm[i] = tm[i] * 1.0;
}
var matrix = new THREE.Matrix4(tm[0], tm[1], tm[2], tm[3], tm[4], tm[5], tm[6], tm[7], tm[8], tm[9], tm[10], tm[11], tm[12], tm[13], tm[14], tm[15]);
obj.applyMatrix(matrix);
Sorry there is some application specific logic in the code, but I think the idea can be found regardless, if someone runs into similar problems.
SketchUp Transformation provides also a .to_a (to array) method, which I think is supposed to return a 16 element matrix.
It has been a while since you posted this, but here's a useful link for people who bump into this in the future: http://www.martinrinehart.com/models/tutorial/tutorial_t.html
Is there an easy way to add shadows in opengl-es 1.x? Or only in 2.0?
For projecting a shadow on a plane there's a simple way (not very efficient, but simple).
This function is not mine, I forget were I found it. What it does is create a matrix projection that maps everything you draw onto a single plane.
static inline void glShadowProjection(float * l, float * e, float * n)
{
float d, c;
float mat[16];
// These are c and d (corresponding to the tutorial)
d = n[0]*l[0] + n[1]*l[1] + n[2]*l[2];
c = e[0]*n[0] + e[1]*n[1] + e[2]*n[2] - d;
// Create the matrix. OpenGL uses column by column
// ordering
mat[0] = l[0]*n[0]+c;
mat[4] = n[1]*l[0];
mat[8] = n[2]*l[0];
mat[12] = -l[0]*c-l[0]*d;
mat[1] = n[0]*l[1];
mat[5] = l[1]*n[1]+c;
mat[9] = n[2]*l[1];
mat[13] = -l[1]*c-l[1]*d;
mat[2] = n[0]*l[2];
mat[6] = n[1]*l[2];
mat[10] = l[2]*n[2]+c;
mat[14] = -l[2]*c-l[2]*d;
mat[3] = n[0];
mat[7] = n[1];
mat[11] = n[2];
mat[15] = -d;
// Finally multiply the matrices together *plonk*
glMultMatrixf(mat);
}
Use it like this:
Draw your object.
glDrawArrays(GL_TRIANGLES, 0, machadoNumVerts); // Machado
Suply it with a light source position, a plane where the shadow will be projected and the normal.
float lightPosition[] = {383.0, 461.0, 500.0, 0.0}
float n[] = { 0.0, 0.0, -1.0 }; // Normal vector for the plane
float e[] = { 0.0, 0.0, beltOrigin+1 }; // Point of the plane
glShadowProjection(lightPosition,e,n);
Ok, shadow matrix is applied.
Change the drawing color to something that fits.
glColor4f(0.3, 0.3, 0.3, 0.9);
Draw your object again.
glDrawArrays(GL_TRIANGLES, 0, machadoNumVerts); // Machado
That is why this is not efficient, the more complex the object the more useless triangles you waste just for a shadow.
Also remember that every manipulation you made to the unshadowed object needs to be done after the shadow matrix is applied.
For more complex stuff the subject is a bit broad, and depends a lot on your scene and complexity.
Projective texture mapped shadows like they were done with OpenGL-1.2 without shaders are possible. Look for older shadow mapping tutorials, written between 1999 and 2002.
I am trying to find the easiest way to add, subtract a scalar value with a opencv 2.0 cv::Mat class.
Most of the existing function allows only matrix-matrix and matrix-scalar operations.
I am looking for a scalar-matrix operations.
I am doing it currently by creating a temporary matrix with the same scalar value and doing required arithmetic operation. Example below..
Mat M(Size(100,100), CV_8U);
Mat temp = Mat::ones(100, 100, CV_8U)*255;
M = temp-M;
But I think there should be better/easier ways to do it.
Any suggestions ?
You cannot initialize a Mat expression from an int or double. The solution is to use cv::Scalar, even for single channel Matrices:
Mat M = Mat::ones(Size(100, 100), CV_8U);
M = Scalar::all(255) - M;
See http://docs.opencv.org/modules/core/doc/basic_structures.html#matrixexpressions for a list of possible Mat expressions.
Maybe this is a feature of 2.1 or somewhere between 2.1 and current trunk version, but this works fine for me:
Mat cc = channels[k];
double fmin,fmax;
cv::minMaxLoc( cc, &fmin, &fmax );
if( fmax > 1.0 )
fmax = 255.0 ;
else
fmax = 1.0;
cc = ( cc / (fmax + 1e-9) );
channels is coming from:
channels = vector<Mat>(3);
cv::split( img, channels );
So, sure just use a scalar expression, at least in 2.1 / current SVN branch; what happens if you try the above in 2.0 ?