How to make SASS ignore math operation? - css

I have this SASS line:
{ grid-area: 3 / 10 / 4 / 11; }
I'm trying to make the grid area change based on the number of grid columns:
{ grid-area: 3 / 10 / 4 / $grid-columns + 1; }
But when I do this, SASS interprets the / characters as a division, generating this as a result:
{ grid-area: 0.64932 }
Is there anyway to make SASS ignore the / characters and only do the $grid-columns + 1 operation, so this would be the final code:
$grid-columns = 10
{ grid-area: 3 / 10 / 4 / $grid-columns + 1; }
{ grid-area: 3 / 10 / 4 / 11; }

You have to declare it as a number
{ grid-area: 3 / 10 / 4 / #{$grid-columns + 1}; }

Related

Undefined SASS operation

I get and error when trying to execute this in a #for loop.
That's the error:
Undefined operation "1 * calc(400px + 6%)".
And this is the line where the error comes from:
top: ($i + 1) % 3 * calc(400px + 6%);
And this is the #for loop:
#for $i from 0 through 9 {
$card: "card-" + $i;
.card-#{$i} {
left: ($i + 1) % 3 * calc(20% + 6.66% * 2);
top: ($i + 1) % 3 * calc(400px + 6%);
}
}
For the left prop it works perfectly, just as I expected it to work, but I don't get what the error is about when comes to top.
Put everything inside calc
#for $i from 0 through 9 {
$card: "card-" + $i;
.card-#{$i} {
left: calc(#{($i + 1) % 3}*(20% + 6.66% * 2));
top: calc(#{($i + 1) % 3}*(400px + 6%));
}
}

What is an algorithm to generate the following sequence?

I want to find out the function to generate the sequence with the following pattern.
1 2 3 1 1 2 2 3 3 1 1 1 1 2 2 2 2 3 3 3 3 ....
Where the lower bound number is 1 upper number bound number is 3. Each time numbers start from 1 and each number repeats 2 ^ n times, with n starting with 0.
Here it goes, I hope it will help.
#include <iostream>
#include <math.h>
int main(){
for(int n = 0; n < 5;n++){
for(int i = 1; i < 4;i++){
for(int j = 0;j < pow(2,n) ;j++){
std::cout << i;
}
}
}
return 0;
}
Here is a code in C++:
#include <iostream>
#include <cmath>
int main()
{
// These are the loop control variables
int n, m, i, j, k;
// Read the limit
cin >> n;
// Outermost loop to execute the pattern {1..., 2..., 3...} n times
for (i = 0; i < n; ++i)
{
// This loop generates the required numbers 1, 2, and 3
for (j = 1; j <= 3; ++j)
{
// Display the generated number 2^i times
m = pow(2, i);
for (k = 0; k < m; ++k)
{
std::cout << j << ' ';
}
}
}
}
You can use the same logic in any language you choose to implement it.

How to generate grid in sass like stylus?

I can generate grid in stylus:
generate-grid(mod)
total = 0
for n, x in 0..11
total = round(8.3333333% * (x + 1))
.{mod}-{x + 1}
flex 0 0 total
.offset-{mod}-{x + 1}
margin-left total
But if I do this in sass then I'll get a bunch of mistakes. How to do it correctly?
#function generate-grid() {
#for $i from 1 through 12 {
.col-{$i} {
width: 8.3333333% * $i;
}
.offset-{$i} {
margin-right: 8.3333333% * $i;
}
}
}
interpolation is different than stylus in sass, it use #{}:
http://sass-lang.com/documentation/file.SASS_REFERENCE.html#Interpolation_____

Less: Dividing variables?

Is it possible to divide two variables in Less?
Like #varA = #varB / #varC;?
I already tried it with escaping, but the output is not what I need.
All operations should be placed within parentheses
#varB = 1;
#varC = 2;
#varA = (#varB / #varC); /* #varA == 0.5 */
Yes.
#var1: 100;
#var2: 10;
#var3: #var1 / #var2;
h1 {
font-size: #var3*1px;
}

Why is my image rotation algorithm not working?

Attempts 1 & 2:
Note: Removed first attempts to cut down on question size. See community wiki for previous attempts.
Attempt 3:
As per fuzzy-waffle's example, I have implemented the following, which doesn't appear to work correctly. Any ideas what I could be doing wrong?
ImageMatrix ImageMatrix::GetRotatedCopy(VDouble angle)
{
// Copy the specifications of the original.
ImageMatrix &source = *this;
ImageMatrix &target = CreateEmptyCopy();
double centerX = ((double)(source.GetColumnCount()-1)) / 2;
double centerY = ((double)(source.GetRowCount()-1)) / 2;
// Remember: row = y, column = x
for (VUInt32 y = 0; y < source.GetRowCount(); y++)
{
for (VUInt32 x = 0; x < source.GetColumnCount(); x++)
{
double dx = ((double)x) - centerX;
double dy = ((double)y) - centerY;
double newX = cos(angle) * dx - sin(angle) * dy + centerX;
double newY = cos(angle) * dy + sin(angle) * dx + centerY;
int ix = (int)round(newX);
int iy = (int)round(newY);
target[x][y][0] = source[ix][iy][0];
}
}
return target;
}
With this prototype matrix...
1 2 1
0 0 0
-1 -2 -1
... prototype.GetRotatedCopy(0) (which is correct) ...
1 2 1
0 0 0
-1 -2 -1
... prototype.GetRotatedCopy(90) (incorrect) ...
-2 0 0
-2 0 2
0 0 2
... prototype.GetRotatedCopy(180) (incorrect - but sort of logical?) ...
0 -1 -2
1 0 -1
2 1 0
... prototype.GetRotatedCopy(270) (incorrect - why is this the same as 0 rotation?) ...
1 2 1
0 0 0
-1 -2 -1
Solution:
As pointed out by Mark Ransom, I should be using radians, not degrees; I have adjusted my code as follows:
ImageMatrix ImageMatrix::GetRotatedCopy(VDouble degrees)
{
// Copy the specifications of the original.
ImageMatrix &source = *this;
ImageMatrix &target = CreateEmptyCopy();
// Convert degree measurement to radians.
double angle = degrees / 57.3;
// ... rest of code as in attempt #3 ...
Thanks for all your help guys!
1 2 1
0 0 0
-1 -2 -1
1 2 1
0 0 0
-1 -2 -1
-1 0 1
-2 0 2
-1 0 1
-1 -2 -1
0 0 0
1 2 1
1 0 -1
2 0 -2
1 0 -1
The algorithm, unless I read it wrong, seems to rotate around the point 0,0 which is not what you want. Maybe you need to add height/2 and width/2 to your row and column values before you plug them in.
for (int y = 0; y < 10; y++) {
for (int x = 0; x < 10; x++) {
VUInt32 newX = (cos(angle) * (x-5)) - (sin(angle) * (y-5));
VUInt32 newY = (sin(angle) * (x-5)) + (cos(angle) * (y-5));
target[newY][newX][0] = source[y][x][0];
}
}
This basically adjusts the rotation center from the upper left corner to the center of the image.
Here is a complete example I hacked up:
I think among other things you may have not been using radians (which we all should use and love). I keep the new coordinates in doubles which seemed to make it less finicky. Note that I am not doing bounds checking which I should but I was lazy.
If you need a faster rotation you can always use shearing like this example.
#include <math.h>
#include <stdio.h>
#define SIZEX 3
#define SIZEY 3
int source[SIZEX][SIZEY] = {
{ 1, 0, 0 },
{ 0, 1, 0 },
{ 0, 0, 1 }
};
int target[SIZEX][SIZEY];
int main () {
double angle = M_PI/2.0;
memset(target,0,sizeof(int)*SIZEX*SIZEY);
double centerX = ((double)(SIZEX-1))/2.0;
double centerY = ((double)(SIZEY-1))/2.0;
for (int y = 0; y < SIZEY; y++) {
for (int x = 0; x < SIZEX; x++) {
double dx = ((double)x)-centerX;
double dy = ((double)y)-centerY;
double newX = cos(angle)*dx-sin(angle)*dy+centerX;
double newY = cos(angle)*dy+sin(angle)*dx+centerY;
int ix = (int) round(newX);
int iy = (int) round(newY);
target[x][y] = source[ix][iy];
}
}
for (int i=0;i<SIZEY;i++) {
for (int j=0;j<SIZEX;j++) {
printf("%d ", target[j][i]);
}
printf("\n");
}
}
short answer: you're doing it wrong.
This is essentially a problem in interpolation, and the way you've approached it introduces discontinuities. Fundamentally this is because rotating a lattice (the regular grid your image is laid out on) does not result in another sampling on the same lattice except for very special cases.
There is no single correct way to do this, by the way, but there are various trade offs with respect to speed and accuracy and also what can be assumed about the original signal (image).
So what are your design parameters? Do you need this to be very fast or very accurate? How do you want to handle aliasing?
your formulas for newRow and newColumn are switched. Remember that row = y and column = x.
Rotation
The problem is that your memory accesses are out of bounds.
After rotation your NewRow and NewColumn may be larger than the original width/height of the image. They may even be negative. If you don't take care about that fact, you'll end up with garbage data (best case) or crashes.
The most common way to deal with this is to just ignore all such pixels. You could also clamp or wrap around the valid intervals. This get's a padding or tiling effect.
Here it's shown with ignoring outside pixels.
int width = 10;
int height = 10;
for (int row = 0; row < height; row++)
{
for (int column = 0; column < width; column++)
{
int newRow = (cos(angle) * row) - (sin(angle) * column);
int newColumn = (sin(angle) * row) + (cos(angle) * column);
if ((newRow >=0) && (newRow < width) &&
(newColumn >=0) && (newColumn < height))
{
target[row][column][0] = source[newRow][newColumn][0];
}
}
}

Resources