Cairo Radial Gradient - cairo

I'm using a radial gradient in Cairo, but I'm not getting the expected results. The radial gradient I'm getting is much less fuzzy than I'd expect and I can't seem to fiddle with the color stops in order to get the desired results. Here is the code:
cairo_pattern_t *pat;
pat = cairo_pattern_create_radial(100.0, 100.0, 0.0, 100.0, 100.0, 20.0);
cairo_pattern_add_color_stop_rgba(pat, 0, 0, 0, 0, 1);
cairo_pattern_add_color_stop_rgba(pat, 1, 0, 0, 0, 0);
Here is an image of what I'm talking about.

The #cairo IRC channel suggested (Thanks Company!) to use cairo_mask() instead of cairo_paint() to draw the gradient. That results in a squared instead of linear progression.
I did the following in lua. Sorry for the language, but it's easier to prototype something. This maps 1:1 to the C API and shouldn't be hard to translate:
cairo = require("lgi").cairo
s = cairo.ImageSurface(cairo.Format.ARGB32, 200, 100)
c = cairo.Context(s)
c:set_source_rgb(1, 1, 1)
c:paint()
p = cairo.Pattern.create_radial(50, 50, 0, 50, 50, 20)
p:add_color_stop_rgba(0, 0, 0, 0, 1)
p:add_color_stop_rgba(1, 0, 0, 0, 0)
c:save()
c:rectangle(0, 0, 100, 100)
c:clip()
c.source = p
c:paint()
c:restore()
p = cairo.Pattern.create_radial(50, 50, 2, 50, 50, 25)
p:add_color_stop_rgba(0, 0, 0, 0, 1)
p:add_color_stop_rgba(1, 0, 0, 0, 0)
c:translate(100, 0)
c:save()
c:rectangle(0, 0, 100, 100)
c:clip()
c.source = p
c:mask(p)
c:restore()
s:write_to_png("test.png")
To me, the second circle (The one that was cairo_mask()'d with a black source) looks a lot more like what you want:

Related

How do I fill Matrix4 with translation, skew and scale values in flutter?

Suppose, I have these values for a container of height 200 and width 300:
scaleX = 0.9198
scaleY = 0.9198
skewX = -0.3923
skewY = 0.3923
translateX = 150
translateY = 150
Now, how do I fill this values in Matrix4 correctly?
I tried doing this:
Matrix4(
0.9198, 0, 0, 0, //
0, 0.9198, 0, 0, //
0, 0, 1, 0, //
150, 150, 0, 1,
)
which is,
Matrix4(
scaleX, 0, 0, 0, //
0, scaleY, 0, 0, //
0, 0, 1, 0, //
translateX, translateY, 0, 1,
)
But I am not sure where to put skewX and skewY values in this matrix. Please help me with this.
Skew Values
This is a bit of a nuanced topic, as it could be interpreted in a couple of different ways. There are specific cells of a matrix that are associated with specific names, as identified in your question, translate x, translate y, scale x, and scale y. In this context, you most likely mean the values from a matrix that are called skew x and skew y (also sometimes known as shear x and shear y), which refers to indices 4 and 1 (zero-based, column-major order). They're called these names because when put into an identity matrix by themselves, they do that operation (translate, scale, or skew), but it gets more complicated when there are multiple values.
On the other hand, this could also be interpreted as a series of operations (e.g. scale by (0.9198, 0.9198, 1), then skew by (-0.3923, 0.3923), then translate by (150, 150, 0)), and then it's a series of matrix multiplications that would ultimately result in a similar-looking, but numerically different matrix. I'll assume you don't mean this for this question. You can read more about it here though.
You can consult the Flutter Matrix4 documentation, which also provides implementation notes for Matrix4.skewX and Matrix4.skewY. The skews are stored in (zero-based) indices 4, and 1, as the tangent of the skewed angle.
Matrix4(
scaleX, skewY, 0, 0, // skewY could also be tan(ySkewAngle)
skewX, scaleY, 0, 0, // skewX could also be tan(xSkewAngle)
0, 0, 1, 0, //
translateX, translateY, 0, 1,
)
Note to those that aren't familiar with Flutter's data structures that values are stored in column-major order which means that each row in the above code is actually a column, so if you were to represent the matrix as a normal transformation matrix, it's transposed.
More information:
Transformation Matrices: https://en.wikipedia.org/wiki/Transformation_matrix
How matrices are used with CSS Transforms: How do I use the matrix transform and other transform CSS properties?

flutter: transform path in CustomPaint with Float64List Matrix4

I was trying to rotate some path and did not find a snippet and matrix4 in general is not well documented. So in case someone else has this problem, this is what I ended up with
First of all, here is a nice read about the math behind it and how to use matrix4.
In my demo I used an arrow tip. Since sequence matters, I paint it at (0,0), then I rotate it around the z-axis and finally I move the tip to the requested spot.
Path _getArrow (Offset offset, double alpha) {
Path a = Path();
a.moveTo(ARROWSIZE, - ARROWSIZE);
a.lineTo(0, 0);
a.lineTo(ARROWSIZE, ARROWSIZE);
final translateM = Float64List.fromList([
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
offset.dx, offset.dy, 0, 1]
);
final rotateM = Float64List.fromList([
cos(alpha), sin(alpha), 0, 0,
-sin(alpha), cos(alpha), 0, 0,
0, 0, 1, 0,
0, 0, 0, 1]
);
final b = a.transform(rotateM);
final c = b.transform(translateM);
return c;
}

How to minimise computation time for a matrix diagonalisation plotting script in matlab?

I am fairly new to matlab and was hoping for some assistance regarding the speeding up of computation and plotting of eigenvalues. I have a 'pentadiagonal' 40x40 matrix, with symbolic k entries.
I wish to compute all of the eigenvalues and plot these as a function of k. So I call eig(H), then I set up a loop which replaces the symbolic k entries with a numerical value. I then simply plot this array, which I have called 'list'.
This routine takes a long time to evaluate, and I do need all of the eigenvalues rather than just the n largest. Does anybody have any advice as to how I can speed up this calculation?
Things I have tried:
1) Preallocating my array. This didn't appear to speed it up much. I believe at this stage, the code still holds the eigenvalues as Root[#1^2+cos(1.0*3)...] objects, and the list is relatively small.
2) Rescaling the arguments of the trig functions cos((sqrt(3)/2)*k) -> cos(k). This also doesn't appear to speed it up a huge amount.
I would be very grateful for any further advice.
a=0.5;
b=0.5;
dq=0.01;
d=0.5;
syms k
H= [(-2)*a - b*d*sin(sqrt(3)*k), 2*a*cos((sqrt(3)/2)*k), b*d*sin((sqrt(3)/2)*k), 0, 0, 0, 0, 0, 0, 0, 0,0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; 2*a*cos((sqrt(3)/2)*k), -1, ...]
list = [];
for s=0:dq:3
list=[list,subs(energies,k,s)];
end
q=0:dq:3;
plot(q,transpose(list),'red')

Formatting CIColorCube data

Recently, I've been trying to set up a CIColorCube on a CIImage to create a custom effect. Here's what I have now:
uint8_t color_cube_data[8*4] = {
0, 0, 0, 1,
255, 0, 0, 1,
0, 255, 0, 1,
255, 255, 0, 1,
0, 0, 255, 1,
255, 0, 255, 1,
0, 255, 255, 1,
255, 255, 255, 1
};
NSData * cube_data =[NSData dataWithBytes:color_cube_data length:8*4*sizeof(uint8_t)];
CIFilter *filter = [CIFilter filterWithName:#"CIColorCube"];
[filter setValue:beginImage forKey:kCIInputImageKey];
[filter setValue:#2 forKey:#"inputCubeDimension"];
[filter setValue:cube_data forKey:#"inputCubeData"];
outputImage = [filter outputImage];
I've checked out the WWDC 2012 Core Image session, and what I have still doesn't work. I've also checked the web, and there are very few resources available on this issue. My code above just returns a black image.
In Apple's developer library, it says:
This filter applies a mapping from RGB space to new color values that are defined in inputCubeData. For each RGBA pixel in inputImage the filter uses the R,G and B values to index into a thee dimensional texture represented by inputCubeData. inputCubeData contains floating point RGBA cells that contain linear premultiplied values. The data is organized into inputCubeDimension number of xy planes, with each plane of size inputCubeDimension by inputCubeDimension. Input pixel components R and G are used to index the data in x and y respectively, and B is used to index in z. In inputCubeData the R component varies fastest, followed by G, then B.
However, this makes no sense to me. How does my inputCubeData need to be formatted?
The accepted answer is incorrect. While the cube data is indeed supposed to be scaled to [0 .. 1], it's supposed to be float, not int.
float color_cube_data[8*4] = {
0.0, 0.0, 0.0, 1.0,
1.0, 0.0, 0.0, 1.0,
0.0, 1.0, 0.0, 1.0,
1.0, 1.0, 0.0, 1.0,
0.0, 0.0, 1.0, 1.0,
1.0, 0.0, 1.0, 1.0,
0.0, 1.0, 1.0, 1.0,
1.0, 1.0, 1.0, 1.0
};
(Technically, you don't have to put the ".0" on each number, the compiler knows how to handle it.)
I found the issue... I have updated my question if anyone has the same problem!
The input float array had to be pre-divided out of 255.
The original used 255:
uint8_t color_cube_data[8*4] = {
0, 0, 0, 1,
255, 0, 0, 1,
0, 255, 0, 1,
255, 255, 0, 1,
0, 0, 255, 1,
255, 0, 255, 1,
0, 255, 255, 1,
255, 255, 255, 1
};
It should look like this instead:
uint8_t color_cube_data[8*4] = {
0, 0, 0, 1,
1, 0, 0, 1,
0, 1, 0, 1,
1, 1, 0, 1,
0, 0, 1, 1,
1, 0, 1, 1,
0, 1, 1, 1,
1, 1, 1, 1
};
Your problem is that you are using value 1(which is next to zero) for alpha channel, max for uint8_t is 255
See example below:
CIFilter *cubeHeatmapLookupFilter = [CIFilter filterWithName:#"CIColorCube"];
int dimension = 4; // Must be power of 2, max of 128
int cubeDataSize = 4 * dimension * dimension * dimension;
unsigned char cubeDataBytes[cubeDataSize];
//cubeDataBytes[cubeDataSize]
unsigned char cubeDataBytes[4*4*4*4] = {
0, 0, 0, 0,
255, 0, 0, 170,
255, 250, 0, 200,
255, 255, 255, 255
};
NSData *cube_data = [NSData dataWithBytes:cubeDataBytes length:(cubeDataSize*sizeof(char))];
//applying
[cubeHeatmapLookupFilter setValue:myImage forKey:#"inputImage"];
[cubeHeatmapLookupFilter setValue:cube_data forKey:#"inputCubeData"];
[cubeHeatmapLookupFilter setValue:#(dimension) forKey:#"inputCubeDimension"];
This is link to full project https://github.com/knerush/heatMap

Batching OpenGL sprites

i have been learning OpenGL and have been able to create a successful 2d drawing system using triangle strips. I wrote a particle generator to test batching the geometry and everything works well, i'm able to render 30k+ vertices at 60 fps on an iPhone 5. I use degenerative triangles to connect the particles and draw them at once. What i am trying to accomplish is batch rendering without using degenerative triangles as that would reduce the amount of data being sent to the GPU by 1/3 the amount which would be huge.
I am attempting to use glDrawElements with triangles to draw 2 sprites with the following code
//the vertices for the square (2d)
GLfloat square[] = {
50, 50, //bottom left
100, 50, //bottom right
50, 100, //top left
100, 100, //top right
150, 200, //bottom left
200, 150, //bottom right
150, 200, //top left
200, 200 //top right
};
//texture coords
GLfloat tex[] = {
0,0,
1,0,
0,1,
1,1,
0,0,
1,0,
0,1,
1,1
};
GLubyte indices[] =
{
0,2,3,
0,3,1,
0,2,3,
0,3,1
};
//actual drawing code
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glVertexAttribPointer(ATTRIB_VERTEX, 2, GL_FLOAT, GL_FALSE, 0, square);
glVertexAttribPointer(ATTRIB_TEX, 2, GL_FLOAT, GL_FALSE, 0, tex);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, image);
glDrawElements(GL_TRIANGLES, 12, GL_UNSIGNED_BYTE, indices);
This code draws the first image without issue, but the second image is distorted. I have been looking online but have been unable to figure out how to make this work correctly.
First of all, you're currently using the same indices for both quads, so the second image shouldn't even be visible at all.
Other than that your vertex data for the second quad is messed, you have the point (150, 200) two times, the first one should probably be (150, 150).