How do I interpolate normals on Catmull-Clark Subdivision Surfaces - graphics

I'm using CCSS to generate smooth surfaces.
I've been using the regular subdivision rules to interpolate the surface/vertex normal, but I think this may be wrong.
Are there different stencils to interpolate normals?

The "normals" from the control mesh are not really normals to begin with. They're just made-up vectors at each vertex, and not something you want to interpolate.
Instead, use the derivative stencils, which yield tangent vectors in two directions. Once you have your tangent vectors, cross them to get a normal. The derivative stencils are:
1 4 1
0 (0) 0
-1 -4 -1
and
-1 0 1
-4 (0) 4
-1 0 1

Related

opengl transformation from model coordinate to world coordinate

I am having trouble to understand the transformation from Model Coordinate to World Coordinate. Here is the slides, my main problem is what is m1, x1, x2, x3, y1, y2, y3, and z1, z2, z3. What kind of value are they representing? and How should I determine it.
They represent a transformation. Specifically, they represent the basis vectors of the transformed coordinate system. To understand what this means, I recommend watching 3Blue1Brown's "Essence of linear algebra", it explains all you need to know about these transformations in an intuitive way.
More practically, what you'll want to do is mainly 3 things: you want to scale your object, you want to rotate your object, and you want to move your object. All of these are transformations. Whenever you see the word "transformation", read it as "matrix". These operations are all matrices.
So for example the scaling matrix is:
sx 0 0 0
0 sy 0 0
0 0 sz 0
0 0 0 1
Where sx is the amount you want to scale in the direction x, and so on.
The rotation matrix will depend on the axis of rotation, for example this is the rotation matrix to rotate the object around the x axis by an angle of t radians, following the right hand rule:
1 0 0 0
0 cos(t) sin(t) 0
0 -sin(t) cos(t) 0
0 0 0 1
You can find the other ones here.
This is the translation matrix used to move the object around:
0 0 0 tx
0 0 0 ty
0 0 0 tz
0 0 0 1
You combine these transformation by multiplying them together. So if your point is (x, y, z), S is your scaling matrix, R is your rotation matrix and T is your translation matrix, you transform the point like this: p = T*R*S*(x,y,z,1). The 1 as the "4th dimension" is used for projection. Tthe GPU divides x, y and z by that value, called w, after it's done processing the vertex. Research projection matrices to know more.

Plotting a heatmap with different bin sizes in Gnuplot

I have a data file that I would like to plot as a heatmap. There are 3 columns: x, y, and the count at point (x,y). The problem is that the bins have different sizes in y (and not in x), for example
-0.3 0 0
-0.3 6.7082 0
-0.3 8.66025 0
-0.3 10.247 0
-0.3 11.619 0
-0.3 12.8452 0
...
But when I plot using for example
set view map
set size ratio -1
set key off
splot "histo.txt" u 1:2:3 w image
I get an image in which the bin sizes in the y direction are the same, thus the picture is distorted.
How can I plot a heatmap with different bin sizes in one direction? I also know exactly where each bin should begin and end in y, the values in the second column of the data file are a weigthed average.
Thank you.
Gnuplot offers basically two plotting styles suitable for heat maps, pm3d and image, which however have very different behaviour:
image:
Draws a pixel image
Always uses a regular grid, no matter what x or y values are used
Each quadrangle (here, the pixel) is centered on one data point
pm3d:
Draws vectorial quadrangles
Can use irregular grids with varying spacings
Draws each quadrangle with four data points as corners. The color is by default given by the mean value of those four points, that can be changed with set pm3d corners2color ...
Can interpolate
Many more features, applicable for 3d etc
So, to summarize: image can be used for heat maps and has its advantages, but in your case you need pm3d, which offers you the flexibility, you need.

Plot vectors only head with gnuplot

I need to plot only the vectors head, but using the following
plot 'plot.txt' u 1:2:($3*factor):($4*factor) w vector lc rgb 'black'
I obtain all the vectors. I only want the head.
so I need to delete a part of a vector mantaining only the head. How can I plot this?
Thank you.
The answer linked by #Christoph indeed contains the key ingredient:
The right command that you need is fixed which allows to plot only the head
However, one should be perhaps slightly more specific here. The keyword fixed per se does not produce "head-only arrows". Its primary purpose is to guarantee that the size of the arrows is independent of the length of the vectors. So in order to produce an arrow with its head only, one might merely shift the starting point of the arrow in the direction of the end point until it is "hidden" inside of the head. That's why the right inner-most arrow in this answer appears to be formed by its head only - the body (line) is just "covered" by the head.
So in order to do this in practice, one might proceed as:
reset
set terminal pngcairo
set output 'fig.png'
$db <<EOF
0.0 0.0 1 1
3.0 0.0 -1 1
3.0 3.0 -1 -1
0.0 3.0 1 -1
EOF
set xr [0:3]
set yr [0:3]
set size square
set xtics 0,1,3 in
set ytics 0,1,3 in
set mxtics 2
set mytics 2
unset key
set style arrow 1 head filled size screen 0.05,45 fixed lc rgb 'royalblue'
set style arrow 2 head filled size screen 0.05,45 fixed lc rgb 'dark-spring-green'
factor=0.5
sigma=0.99
plot \
$db using 1:2:(factor*$3):(factor*$4) with vectors as 2,\
$db using ($1+sigma*$3):($2+sigma*$4):((1-sigma)*$3):((1-sigma)*$4) with vectors as 1
The first part of the plot statement produces arrows (green) scaled with factor 0.5. Since their length is still significant, they appear with head as well as with the body. In the second part, there is the shift factor 0<=sigma<=1 - the statement ($1+sigma*$3):($2+sigma*$4):((1-sigma)*$3):((1-sigma)*$4) then requests an arrow with the same endpoint as before (for example, sum of the first and third columns is independent of sigma), but with shifted origin along the direction of the arrow (sigma=0 recovers original arrow, sigma=1 would produce zero-length arrow). Thus if sigma is sufficiently close to 1, only the arrow heads are visible:

How to label vector in gnuplot

I would like to know how to give a label at the end of a vector in gnuplot. I know it is possible to use "set" in gnuplot to show a certain label at some place, but I have hundreds of vectors to draw, and I want to show the index of each vector at its end, e.g., "Node n". Thus I wonder if it is possible to show the labels with incremental index in "one step" with corresponding vectors.
My OS is Ubuntu 13.04 32bit version. Thanks for any advice!
Imagine you have a file with the following data (which I named "temp"), where the first two coordinates are the origin and the last two coordinates are the x and y components (projections) of your vector:
0 0 1 1
0 0 1 2
0 0 1 3
0 0 1 4
0 0 1 5
Then you can do what you want with the following commands:
set xrange [0:1.2]
set yrange [0:6]
plot "temp" with vectors, "temp" u 3:4:0 with labels left
The first instance in plot is to plot the vectors with the same convention I mentioned above in the data file, the second instance is to place a label with coordinates x = column 3 and y = column 4 (that is, at the end of your vectors), with text = column 0 (which gives the order of your data entries) and flush it to the left from those coordinates. It looks like this:

How to find the tangent to any pixel?

I want to find tangent at each pixel in image.
NOTE: image is having white background and shape border color is block.
What i did is,
Algo
While(true)
take pixel
if pixel color is black
make 3 X 3 matrix => fill the matrix by surrounding pixel color
...means assume white =0 and black=1 then keeping selected pixel
at center for 3 X 3 matrix and finding all other value;
----------------------------here i want to find tangent line to selected pixel;
end if
Move to next pixel.
End while
Please help Exams on head .
What you're looking for is probably a Sobel Operator. It's implemented as a convolution of the neighborhood around a pixel with the matrix:
-1 0 1
-2 0 2
-1 0 1
and again with:
-1 -2 -1
0 0 0
1 2 1
Call the results of the 2 convolutions x and y, respectively. Once you have them, you can get the magnitude of the gradient by taking the square root of the sum of the squares:
mag = sqrt(x * x + y * y);
and the direction of the gradient (which should be tangent to the pixel you're examining) by taking the arctangent of y over x:
tangent = atan2(y / x)

Resources