xOr'ing Two Images Together Using Actionscript 3.0/Flex - apache-flex

Isn't there some way to combine two images together using the xOr operator? I realize I can step through pixel by pixel, but with all the graphics options available to Flash, I am reluctant to take such a ham-fisted approach. How can this be accomplished efficiently?
var pixel1:uint;
var pixel2:uint;
var xorMergedPixel:uint;
for (var x:int=0;x<22;x++) {
for (var y:int=0;y<22;y++) {
pixel1=bitmapData1.getPixel(x,y);
pixel2=bitmapData2.getPixel(x,y);
xorMergedPixel=pixel1^pixel2;
bitmapData3.setPixel(x,y,xorMergedPixel);
}
}

Pixel Bender is your best option.
http://www.adobe.com/devnet/flex/articles/pixel_bender_basics_flex_air.html

Related

How can I merge geometries in A-Frame without losing material information?

I have a large set of block objects using a custom geometry, that I am hoping to merge into a smaller number of larger geometries, as I believe this will reduce rendering costs.
I have been following guidance here: https://aframe.io/docs/1.2.0/introduction/best-practices.html#performance which has led me to the geometry-merger component here:
https://github.com/supermedium/superframe/tree/master/components/geometry-merger/
The A-Frame docs say:
"You can use geometry-merger and then make use a three.js material with vertex colors enabled. three.js geometries keep data such as color, uvs per vertex."
The geometry-merger component also says:
"Useful if using vertex or face coloring as individual geometries' colors can still be manipulated individually since this component keeps a faceIndex and vertexIndex."
However I have a couple of problems.
If I set vertexColors on my material (as suggested by the A-Frame docs), then this ruins the appearance of my blocks.
Whether or not I set vertexColors on my material, all material information seems to be lost when the geometries are merged, and everything just ends up white.
See this glitch for a demonstration of both problems.
https://tundra-mercurial-garden.glitch.me/
My suspicion is that the A-Frame geometry-merger component just won't do what I need here, and I need to implement something myself using the underlying three.js functions.
Is that right, or is there a way that I could make this work using geometry-merger?
For the vertexColors to work, you need to have your vertices coloured :)
More specifically - the BufferGeometry expects an array of rgb values for each vertex - which will be used as color for the material.
In this bit of code:
var geometry = new THREE.BoxGeometry();
var mat = new THREE.MeshStandardMaterial({color: 0xffffff, vertexColors: THREE.FaceColors});
var mesh = new THREE.Mesh(geometry, mat);
The mesh will be be black unless the geometry contains information about the vertex colors:
// create a color attribute in the geometry
geometry.setAttribute('color', new THREE.BufferAttribute(new Float32Array(vertices_count), 3));
// grab the array
const colors = this.geometry.attributes.color.array;
// fill the array with rgb values
const faceColor = new THREE.Color(color_hex);
for (var i = 0; i < vertices_count / 3; i += 3) {
colors[i + 0] = faceColor.r; // lol +0
colors[i + 1] = faceColor.g;
colors[i + 2] = faceColor.b;
}
// tell the geometry to update the color attribute
geometry.attributes.color.needsUpdate = true;
I can't make the buffer-geometry-merger component work for some reason, but It's core seems to be valid:
AFRAME.registerComponent("merger", {
init: function() {
// replace with an event where all child entities are ready
setTimeout(this.mergeChildren.bind(this), 500);
},
mergeChildren: function() {
const geometries = [];
// traverse the child and store all geometries.
this.el.object3D.traverse(node => {
if (node.type === "Mesh") {
const geometry = node.geometry.clone();
geometry.applyMatrix4(node.parent.matrix);
geometries.push(geometry)
// dispose the merged meshes
node.parent.remove(node);
node.geometry.dispose();
node.material.dispose();
}
});
// create a mesh from the "merged" geometry
const mergedGeo = THREE.BufferGeometryUtils.mergeBufferGeometries(geometries);
const mergedMaterial = new THREE.MeshStandardMaterial({color: 0xffffff, roughness: 0.3, vertexColors: THREE.FaceColors});
const mergedMesh = new THREE.Mesh(mergedGeo, mergedMaterial);
this.el.object3D.add(mergedMesh)
}
})
You can check it out in this glitch. There is also an example on using the vertex colors here (source).
I agree it sounds like you need to consider other solutions. Here are two different instances of instancing with A-Frame:
https://github.com/takahirox/aframe-instancing
https://github.com/EX3D/aframe-InstancedMesh
Neither are perfect or even fully finished, but can hopefully get you started as a guide.
Although my original question was about geometry merging, I now believe that Instanced Meshes were a better solution in this case.
Based on this suggestion I implemented this new A-Frame Component:
https://github.com/diarmidmackenzie/instanced-mesh
This glitch shows the scene from the original glitch being rendered with just 19 calls using this component. That compares pretty well with > 200 calls that would have been required if every object were rendered individually.
https://dull-stump-psychology.glitch.me/
A key limitation is that I was not able to use a single mesh for all the different block colors, but had to use one mesh per color (7 meshes total).
InstancedMesh can support different colored elements, but each element must have a single color, whereas the elements in this scene had 2 colors each (black frame + face color).

Support for variable thickness stroke

Are there any vector graphics standards that support variable-thickness paths / strokes, e.g. from a stylus input:
Some amount of smoothing may be acceptable. I'd assume that the best way to store it would be as a regular path (e.g. this) and then point-wise sparse thickness information at various points in the path, with gradients between them.
I have looked at SVG but there doesn't seem to be an element that can support it. Are there any vector graphics standards that can?
A single path as currently implemented does not allow variable thickness. There is a W3.org proposal for SVG standard, but no implementation so far in pure SVG.
There are several implementation of a "path with variable thickness", but that relies on svg objects (eg., multiple paths) and a c++ or javascript functions.
PowerStroke is an implementation of such idea of a variable thickness stroke in Inkscape. A good entry to the source in c++ is here.
There are other implementations in SVG and javascript, relying on multiple paths:
Tubefy, a set of few js functions, the principle is based on a linear interpolation. There are several implementation of Tubefy, the simplest is:
$ = function (id) { return typeof id=='string'?document.getElementById(id):id };
var root = document.rootElement;
function lerp(p, a, b) { return Number(a)+(b-a)*p; }
function lerpA(p, a, b) { var c=[];
for(var i=0; i<a.length; i++) c[i]=lerp(p, a[i], b[i]);
return c;
}
function toCss(a){
for(var i=0; i<a.length; i++) a[i]=Math.round(a[i]);
return "rgb(" + a.join() + ")";
}
Variable Stroke-Width, based on multiple path, which could be the best answer to your needs.
In one of the examples, the js function uses Tubefy and is directly implemented in the svg file:
<script>//<![CDATA[
var op=1, op1=1;
function vsw0(p0, n, g){ p0=$(p0);
var SW=p0.getAttribute('stroke-widths').replace(/ /g,'').split(',');
var T=p0.getTotalLength();
var n_1=n-1, dt=T/n, dash=(dt+1)+','+T;
p0.setAttribute('stroke-dasharray', dash);
for(var i=0; i<n; i++){ p=i/n_1;
var sw=lerp(p, SW[0], SW[1]); // current stroke width
var off=-i*dt; // current dash offset
var c=toCss(lerpA(p, [255,0,0], [255,255,0])); // curr color
var newP=p0.cloneNode(true);
newP.setAttribute('style', 'stroke-width:'+sw+';stroke-dashoffset:'+off+';stroke:'+c);
$(g).appendChild(newP);
}
}
function f(){ $('abg').setAttribute('stroke', $('bg').getAttribute('fill')) }
//]]></script>
</svg>
Unfortunately this has been proposed but not further developed as an SVG standard:
https://www.w3.org/Graphics/SVG/WG/wiki/Proposals/Variable_width_stroke
Your best bet would be to generate your own outline curve based on the desired inner curve and stroke widths.
Adobe Illustrator does this when using their width tool, and Inkscape has a feature which does that too.
So technically to answer your question, the .ai file format does save stroke width information, but when exported to SVG it is a closed path with fill.

Direct linear transformation in CSS

Is it possible to do a DLT in CSS? If so, how is this accomplished? I can't think of a way using just transform: matrix... If this is not possible, what would be an alternative approach?
The particular effect I'm trying to achieve is laying out divs in a way similar to how Safari does this:
Here is a very rough and non-generic answer to your request. http://jsfiddle.net/3t5SM/
You could easily extend it to get a generic much better solution.
in my CSS,
#id1, #id4, #id7{
-webkit-transform: rotateY(40deg);
}
#id3, #id6, #id9{
-webkit-transform: rotateY(-40deg);
}
#id2, #id5, #id8{
-webkit-transform: scale(0.94);
}
the basic idea is to create a style for each column (here i'm calling the id's but again, it would be better to have a style for each column and define the columns as .left, .middle, .right, etc)
I'll update my post tonight if I have the time to go into the details :)
EDIT: as promise, here is a little better version. Now it is much more generic and depending on the size of your window, you'll get the right number of cubes. It is still far from being perfect (you could play with the size of the cubes in order to get a better depth feeling), but in general you see that it is possible, even dynamically :)
here is the fiddle: http://jsfiddle.net/P84qd/4/
To go a little into the details of the javascript:
function dispatch(){
var sizeOfImg = 150;
var windowWith = document.body.offsetWidth;
var widthRest = windowWith%sizeOfImg;
var nbSquareRow = Math.floor(windowWith/sizeOfImg);
dlt(nbSquareRow);
var marginVal = widthRest/(nbSquareRow+1);
var lineout = document.getElementById('lineout');
lineout.style.paddingLeft = marginVal+'px';
lineout.style.paddingTop = marginVal+'px';
var square = document.getElementsByTagName('div');
for(var i=0, length = square.length;i<length; i++){
if(square[i].className === 'square'){
square[i].style.marginRight = marginVal+'px';
square[i].style.marginBottom = marginVal+'px';
}
}
}
dispatch();
window.onresize = function(e){dispatch();};
function dlt(nbSquareRow){
var maxRotatDeg = 40;
var isEven=true;
if(nbSquareRow%2 == 0){
var unityRotatDeg = maxRotatDeg/(nbSquareRow/2);
}else{
var unityRotatDeg = maxRotatDeg/((nbSquareRow-1)/2);
isEven = false;
}
var middle = Math.floor(nbSquareRow/2);
var mySquares = document.getElementsByTagName('div');
for(var j=0, sqleng = mySquares.length;j<sqleng; j++){
if(mySquares[j].className == 'square'){
var colNumb = (parseInt(mySquares[j].id)-1)%nbSquareRow;
var myMultiplier = (middle-colNumb);
if(isEven && myMultiplier<=0){
myMultiplier--;
}
mySquares[j].style.webkitTransform = 'rotateY('+(unityRotatDeg*myMultiplier)+'deg)';
}
}
}
The dispatch function is a simple function that will distribute the squares on your web page with equal margins (top, left, right, bottom). I took it from 1.
The dlt function calculates the number of columns and defines the rotation amount for each column (in my example the maximum rotation value is 40). The rest of the code are purely some math checks in order to make it work correctly.
In order to get a better result, you should play with the size of each square, but be careful because the dispatch function also needs to know the size of the square to calculate how many squares will be allowed to be displayed per row. I'll let you have fun with it ;)
​

Implementing an IObservable to compute digits of Pi

This is an academic exercise, I'm new to Reactive Extensions and trying to get my head around the technology. I set myself a goal of making an IObservable that returns successive digits of Pi (I happen to be really interested in Pi right at the moment for unrelated reasons). Reactive Extensions contains operators for making observables, the guidance they give is that you should "almost never need to create your own IObsevable". But I can't see how I can do this with the ready-made operators and methods. Let me elucidate a bit more.
I was planning to use an algorithm that would involve the expansion of a Taylor series for Arctan. To get the next digit of Pi, I'd expand a few more terms in the series.
So I need the series expansion going on asynchronously, occasionally throwing out the next computed digit to the IObserver. I obviosly don't want to restart the computation from scratch for each new digit.
Is there a way to implement this behaviour using RX's built-in operators, or am I going to have to code an IObservable from scratch? What strategy suggests itself?
For something like this, the simplest method would be to use a Subject. Subject is both an IObservable and IObserver, which sounds a bit strange but it allows you to use them like this:
class PiCalculator
{
private readonly Subject<int> resultStream = new Subject<int>();
public IObservable<int> ResultStream
{
get { return resultStream; }
}
public void Start()
{
// Whatever the algorithm actually is
for (int i = 0; i < 1000; i++)
{
resultStream.OnNext(i);
}
}
}
So inside your algorithm, you just call OnNext on the subject whenever you want to produce the next value.
Then to use it, you just need something like:
var piCalculator = new PiCalculator();
piCalculator.ResultStream.Subscribe(n => Console.WriteLine((n)));
piCalculator.Start();
Simplest way is to create an Enumerable and then convert it:
IEnumerable<int> Pi()
{
// algorithm here
for (int i = 0; i < 1000; i++)
{
yield return i;
}
}
Usage (for a cold observable, that is every new 'subscription' starts creating Pi from scratch):
var cold = Pi().ToObservable(Scheduler.ThreadPool);
cold.Take(5).Subscribe(Console.WriteLine);
If you want to make it hot (everyone shares the same underlying calculation), you can just do this:
var hot = cold.Publish().RefCount();
Which will start the calculation after the first subscriber, and stop it when they all disconnect. Here's a simple test:
hot.Subscribe(p => Console.WriteLine("hot1: " + p));
Thread.Sleep(5);
hot.Subscribe(p => Console.WriteLine("hot2: " + p));
Which should show hot1 printing only for a little while, then hot2 joining in after a short wait but printing the same numbers. If this was done with cold, the two subscriptions would each start from 0.

Flex skew Object

I was wondering how to distort a Flex object like Panel so it looks like a trapezoid?
Are you trying to do something like this? Flex skewing
private function skewit():void {
var smat:Matrix = new Matrix();
smat.b = Math.tan(50);
var mat:Matrix = myobject.transform.matrix;
mat.concat(smat);
myobject.transform.matrix = mat;
}
http://livedocs.adobe.com/flex/3/html/help.html?content=15_Geometry_6.html
If you're really serious about this stuff, you should write it in ActionScript and pick up the book Numerical Recipes and read the chapter on "Computational Geometry". It will probably answer all your questions and more! Have fun :)

Resources