Syncing overlay to displacement map filter - actionscript-3

I'm using a DisplacementMapFilter to created a globe-like effect on a flat map. My problem is, I also want to sync some labels to this map. I have the x/y coordinates for their locations on the flat map, but I need to map them to the now-displaced image.
I would like to be able to do this using the BitmapData that contains the displacement map, so that changing the Bitmap changes both the displacement filter and the label locations. Also, the labels will not be static, and accuracy is fairly important.

There is a formula in DisplacementMapFilter reference:
dstPixel[x, y] =
srcPixel[
x + ((componentX(x, y) - 128) * scaleX) / 256,
y + ((componentY(x, y) - 128) *scaleY) / 256)
]
componentX/Y are color channels in the bitmap (you can bind any channel to coordinates).
As I understand, you need to shift map labels as filter would do. Just take label coordinates (x, y), sample source bitmap with getPixel32(x, y). Then you need to figure out which bytes to take for x, y - I guess by default it would be R, G components, respectively. Then use formula to get displaced label coordinates.
Note: getPixel32 returns uint color in ARGB format. Use shift operator (>>) to get color components:
uint ARGB = bitmap.getPixel32(x, y);
int B = ARGB & 0xFF;
int G = (ARGB >> 8) & 0xFF;
int R = (ARGB >> 16) & 0xFF;

Related

Octave - gradients of a circle function do not plot correctly

Question
Trying to follow Gradients, Gradient Plots and Tangent Planes.
The gradient vectors of (X^2 + Y^2) do not show up correctly in Octave 4.2.0 on Windows. With the code, expected the gradients of a circle diverge from center outwards. However the actual is diagonal.
Please assist to understand what is wrong.
syms x y
f1 = x^2 + y^2;
gradf1 = jacobian(f1,[x,y]);
f1fun = function_handle(f1);
f1xfun = function_handle(gradf1(1));
f1yfun = function_handle(gradf1(2));
[xx, yy] = meshgrid(-1:.1:1,-1:.1:1);
hold on
contour(xx, yy, f1fun(xx, yy), 10)
quiver(xx, yy, f1xfun(xx, yy), f1yfun(xx, yy), 0.5)
axis equal tight
hold off
Expected
Actual
When you perform:
f1xfun = function_handle(gradf1(1));
f1yfun = function_handle(gradf1(2));
The output is:
f1xfun =
#(x) 2 * x % note: single-argument function
f1yfun =
#(y) 2 * y % note: single-argument function
that is AS OPPOSED TO
f1xfun =
#(x,y) 2 * x % two-argument function
f1yfun =
#(x,y) 2 * y % two-argument function
which is what you seem to think was happening. (i.e. the resulting functions actually only take a single input, not both x and y).
Therefore later on when you call f1yfun with two inputs, the second input (i.e. y) is simply silently discarded, and you are essentially calculating 2*x in both axes, hence the diagonal arrows.
tl;dr Your call to quiver should be:
quiver(xx, yy, f1xfun(xx), f1yfun(yy), 0.5);
I think you have a bug in your code and the call to quiver should be
quiver(xx, yy, f1xfun(xx), f1yfun(yy), 0.5)
which then gives (with colormap("jet"))

In Starling, how do you transform Filters to match the target Sprite's rotation & position?

Let's say your Starling display-list is as follows:
Stage
|___MainApp
|______Canvas (filter's target)
Then, you decide your MainApp should be rotated 90 degrees and offset a bit:
mainApp.rotation = Math.PI * 0.5;
mainApp.x = stage.stageWidth;
But all of a sudden, the filter keeps on applying itself to the target (canvas) in the angle it was originally (as if the MainApp was still at 0 degrees).
(notice in the GIF how the Blur's strong horizontal value continues to only apply horizontally although the parent object turned 90 degrees).
What would need to be changed to apply the filter to the target object before it gets it's parents transform? That way (I'm assuming) the filter's result would get transformed by the parent objects.
Any guess as to how this could be done?
https://github.com/bigp/StarlingShaderIssue
(PS: the filter I'm actually using is custom-made, but this BlurFilter example shows the same issue I'm having with the custom one. If there's any patching-up to do in the shader code, at least it wouldn't necessarily have to be done on the built-in BlurFilter specifically).
I solved this myself with numerous trial and error attempts over the course of several hours.
Since I only needed the shader to run in either at 0 or 90 degrees (not actually tweened like the gif demo shown in the question), I created a shader with two specialized sets of AGAL instructions.
Without going in too much details, the rotated version basically requires a few extra instructions to flip the x and y fields in the vertex and fragment shader (either by moving them with mov or directly calculating the mul or div result into the x or y field).
For example, compare the 0 deg vertex shader...
_vertexShader = [
"m44 op, va0, vc0", // 4x4 matrix transform to output space
"mov posOriginal, va1", // pass texture positions to fragment program
"mul posScaled, va1, viewportScale", // pass displacement positions (scaled)
].join("\n");
... with the 90 deg vertex shader:
_vertexShader = [
"m44 op, va0, vc0", // 4x4 matrix transform to output space
"mov posOriginal, va1", // pass texture positions to fragment program
//Calculate the rotated vertex "displacement" UVs
"mov temp1, va1",
"mov temp2, va1",
"mul temp2.y, temp1.x, viewportScale.y", //Flip X to Y, and scale with viewport Y
"mul temp2.x, temp1.y, viewportScale.x", //Flip Y to X, and scale with viewport X
"sub temp2.y, 1.0, temp2.y", //Invert the UV for the Y axis.
"mov posScaled, temp2",
].join("\n");
You can ignore the special aliases in the AGAL example, they're essentially posOriginal = v0, posScaled = v1 variants and viewportScale = vc4constants, then I do a string-replace to change them back to their respective registers & fields ).
Just a human-readable trick I use to avoid going insane. \☻/
The part that I struggled with the most was calculating the correct scale to adjust the UV's scale (with proper detection to Stage / Viewport resize and render-texture size shifts).
Eventually, this is what I came up with in the AS3 code:
var pt:Texture = _passTexture,
dt:RenderTexture = _displacement.texture,
notReady:Boolean = pt == null,
star:Starling = Starling.current;
var finalScaleX:Number, viewRatioX:Number = star.viewPort.width / star.stage.stageWidth;
var finalScaleY:Number, viewRatioY:Number = star.viewPort.height / star.stage.stageHeight;
if (notReady) {
finalScaleX = finalScaleY = 1.0;
} else if (isRotated) {
//NOTE: Notice how the native width is divided with height, instead of same side. Weird, but it works!
finalScaleY = pt.nativeWidth / dt.nativeHeight / _imageRatio / paramScaleX / viewRatioX; //Eureka!
finalScaleX = pt.nativeHeight / dt.nativeWidth / _imageRatio / paramScaleY / viewRatioY; //Eureka x2!
} else {
finalScaleX = pt.nativeWidth / dt.nativeWidth / _imageRatio / viewRatioX / paramScaleX;
finalScaleY = pt.nativeHeight / dt.nativeHeight / _imageRatio / viewRatioY / paramScaleY;
}
Hopefully these extracted pieces of code can be helpful to others with similar shader issues.
Good luck!

flash/actionscript 3.0 how to logically partition an image

I'm new to flash and I'm trying to create a board game with actionscript 3.0
I have already created the background (checker squares) for the board and now I have to partition the background by each box. What are the ways I can achieve that? I want to logically put numbers for each square as seen in the picture.
I realized its possible to do it using lasso tool and convert each to symbols. But is there any "lazy" way of doing that? There are lots of cuts I'd have to make in order to do that.
We can use some simple calculations to map some (x, y) value to a number. Lets say:
widht = width of the image
height = height of the image
gridCount = 8
gridWidth = width / gridCount
gridHeight = height / gridCount
Now first we would like to map user click point (x, y) to some integer index i, j to the logical 8 x 8 matrix where top left is index 0, 0.
i = x / gridWidth
j = y / gridHeight
For example, if gridWidth = 60, gridHeight = 50 and user clicks on (10, 15) then i = 0, j = 0.
Now we have to map this i, j to the specified numbers. As bottom line contains 11, 21, 31, ... and every column is increasing, the final number will be:
num = (11 + i * 10) + (gridCount - j - 1)
Converting these equations to AS3 code is straight forward, so I'm not adding them.

Mapping a 2D grid onto a sphere

I want to map a grid to a sphere like this:
In other words, for every point (x, y) ∈[0,1] on the left, I need the (x, y, z) coordinates of the equivalent point on the sphere, between the -45º and +45º meridians on each axis. You can also think of the source coordinates as two angles such that:
phi = -45º + x * 90º
theta = -45º + y * 90º
The traditional latitude-longitude or polar formulas I've found elsewhere are of no use because the results they produce are only distorted along one axis. Any other suggestions?
Define two functions, a and b, that map your x and y coordinates to the appropriate theta and phi angles:
a(x) = (pi / 4) * (2x - 1)
b(y) = (pi / 4) * (4y + 1)
And then just map the resulting spherical coordinate back into a Cartesian coordinate:
You'll get a function of r, x', y', members of [0, 1] x [0, 1], which will map the 2D coordinate onto a sphere of radius r.

How to create intensity mask for heatmap?

I'm trying to develop heat map, now initially I would have to draw the intensity mask, and since I'm using GWT so I have randomly generated some coordinates and placed my circles ( with required gradience ) at those locations so the output comes out to be circles overlapping each other. And If I look at the intensity mask from Dylan Vester, it comes to be very smooth How can I draw my heat map ?? Also how the output is achieved similar to Dylan Vester?? Question also is if I'm drawing circles then how to decide the intensity at the intersection of two or more circles, how they have achieved ?? Here is my code
// creating the object for the heat points
Heat_Point x = new Heat_Point();
// Variables for random locations
int Min = 1,Max = 300;
int randomx,randomy;
// Generating set of random values
for( int i = 0 ; i < 100 ; i++ ) {
// Generating random x and y coordinates
randomx = Min + (int)(Math.random() * ((Max - Min) + 1));
randomy = Min + (int)(Math.random() * ((Max - Min) + 1));
// Drawing the heat points at generated locations
x.Draw_Heatpoint(c1, randomx, randomy);
}
And Here is how I'm plotting my heat point that is Heat_Point class
Context con1 = c1.getContext2d(); // c1 is my canvas
CanvasGradient x1;
x1 = ((Context2d) con1).createRadialGradient(x,y,10,x,y,20);
x1.addColorStop(0,"black");
x1.addColorStop(1,"white");
((Context2d) con1).beginPath();
((Context2d) con1).setFillStyle(x1);
((Context2d) con1).arc(x,y,20, 0, Math.PI * 2.0, true);
((Context2d) con1).fill();
((Context2d) con1).closePath();`
here I was supposed to add some images but I didn't have enough reputation :D :P
I took a quick look at HeatmapJS (http://www.patrick-wied.at/static/heatmapjs/) and it seems he uses radial gradients (like you have above) and he also uses opacity and a color filter called "multiply blend" to smooth out the intensity of the colors in the heat map.
His code is quite impressive. It's open source, so you might want to check it out!