Original Question
When I made the game in C++, the window and buffer size was 120 x 40 and the screen(array of wchar_t) was the same hence each character would take up equal space such that the whole array would make the screen and later redrawing it on the console
I am trying to make the basic console to work with the canvas but not every character has equal amount of space and not all would fit into it
//Display map
for (nx = 0; nx < MAP_WIDTH; nx++)
{
for (ny = 0; ny < MAP_HEIGHT; ny++)
{
Screen[(ny + 1) * SCREEN_WIDTH + nx] = MAP[ny * MAP_WIDTH + nx] //returns a character '#' or '.';
}
}
this is the sample of how I fill the array
`Screen = Array(SCREEN_WIDTH * SCREEEN_HEIGHT);`
this is the initialization of array
now how would I draw that screen buffer to the canvas
in C++ it would be like this
//finally printing the screen
screen[ScreenWidth * ScreenHeight - 1] = '\0';
WriteConsoleOutputCharacter(hConsole, screen, ScreenWidth * ScreenHeight, { 0, 0 }, &dwBytesWritten);
I just ditched the canvas and just printed my text inside a para tag with such
let line = "";
for (let y = 0; y < SCREEN_HEIGHT; y++)
{
for (let x = 0; x < SCREEN_WIDTH; x++)
{
line += screen[y * SCREEN_WIDTH + x];
}
line += "\n";
}
document.getElementById("consoletext").innerText = line;
I'm trying to create a pattern script in Photoshop that duplicates an image horizontally and vertically over the whole canvas. But the issue is that across the x-axis it doubles its value every loop. If I remove the "j" loop, it works fine.
This pic will show you the issue I'm referring to https://imgur.com/a/0x9HhCS
var offset = parseInt(prompt("Type in the offset (spacing between pics) value here.\nDefault is 0px.", "0"));
for (var i = 0; i < width / (layerWidth + offset); i++) {
for (var j = 0; j < 3; j++) {
app.activeDocument.layers[i, j].duplicate()
app.activeDocument.layers[i, j].translate(i * (layerWidth + offset), j * (layerHeight + offset));
}
}
As volcanic mentioned, layers[i, j] isn't a valid way of accessing your layers. I'm not even sure why this works. You're supposed to select you original layer, make a copy and translate it. Something like this:
var width = activeDocument.width.as("px");
var height = activeDocument.height.as("px");
var layer = app.activeDocument.activeLayer;
var layerWidth = layer.bounds[2] - layer.bounds[0];
var layerHeight = layer.bounds[3] - layer.bounds[1];
var copy, i, j;
var offset = parseInt(prompt("Type in the offset (spacing between pics) value here.\nDefault is 0px.", "0"));
for (i = 0; i < width / (layerWidth + offset); i++)
{
for (j = 0; j < height / (layerHeight + offset); j++)
{
// in the each loop we select the original layer, make a copy and offset it to calculated values
app.activeDocument.activeLayer = layer;
copy = layer.duplicate();
copy.translate(i * (layerWidth + offset), j * (layerHeight + offset));
}
}
layer.remove(); // remove the original layer
Result:
the issue is related in how do you use offset:
Translate refers to the bounding rect of the layer.
If you have a 50px width image translated by 50px, the resulting layer width will be 100px.
Try to use only the offset, each iteration.
I want to write a program that draws a surface (X * Y) evenly.I already have an approach for this at the moment, but it doesn't quite work yet and is also very slow. Since this approach is far too slow, I do not want to pursue it much further.
At the beginning there is always the first point and the last one - so with an area of 10 x 10 the pixel at position 0 and the pixel at position 99.
Then the next best pixel must be found, i.e. the one with the largest distance. This is relatively easy with only two points - (99 - 0 / 2) so 49 or 48.
Now you have to look for the next best one again. So (49 - 0) / 2 or if 48 was taken before (99 - 48) / 2 so 24/25 or 74/75.
This process must be repeated until the correct sequence is found.
0,99,49,74,24,36,61,86,12,42,67,92,6,18,30,55,80,45,70,95,3,9,15,21,27,33,39,52,58,64,77,83,89,47,72,97,1,4,7,10,13,16,19,22,25,28,31,34,37,40,43,50,53,56,59,62,65,68,75,78,81,84,87,90,93,2,5,8,11,14,17,20,23,26,29,32,35,38,41,44,46,48,51,54,57,60,63,66,69,71,73,76,79,82,85,88,91,94,96,98
I also added a small example here, which shows how it should work. The function getElementOrder should be replaced by a mathematical expression to get the fastest possible solution.
// define variables
const width = 20; // this will be > 2100
const height = 20; // this will be > 1600
const size = 20;
let elements = {};
// create all cells
for (let x = 0; x < width; x++) {
for (let y = 0; y < height; y++) {
let id = x + y * height;
let div = document.createElement("div");
div.style.border = "solid 1px black";
div.style.width = size + "px";
div.style.height = size + "px";
div.style.position = "absolute";
div.style.left = x * size + "px";
div.style.top = y * size + "px";
div.style.backgroundColor = "#F0F0F0";
let textDiv = document.createElement("div");
textDiv.innerHTML = id;
textDiv.style.position = "absolute";
textDiv.style.fontSize = "6pt";
textDiv.style.top = "1px";
textDiv.style.right = "1px";
div.appendChild(textDiv);
document.body.appendChild(div);
elements[id] = div;
}
}
function getElementOrder(width, height) {
/* BAD SLOW CODE START - This sould be better: */
const length = width * height;
const order = [0, length -1];
const result = [0, length -1];
while (order.length !== length) {
let index = 0;
let diff = 0;
for (let i = 0, m = order.length - 1; i < m; i++) {
let localDiff = order[i+1] - order[i];
if (localDiff > diff) {
index = i;
diff = localDiff;
}
}
let offset = Math.floor(diff/2);
let value = order[index] + offset;
order.splice(index + 1, 0, value);
result.push(value);
}
return result;
/* BAD SLOW CODE END */
}
// get the draw order
let order = getElementOrder(width, height);
// change color of each pixel in draw order
let interval = setInterval(() => {
if (order.length === 0) {
clearInterval(interval);
return;
}
const value = order.shift();
elements[value].style.backgroundColor = "#00abab";
}, 10);
Are there any mathematical approaches to solve this problem?
You are welcome to post better solutions, approaches or links to mathematical formulas for this problem here.
I think I get what you're trying to accomplish, and what the underlying routine is. The way I see it, you're probably overcomplicating the question of "finding the biggest distance", since from what I can see, what you're basically doing is halving increasingly fine intervals.
So, here's my version:
function getElementOrder(width, height) {
const length = width * height;
const order = [ 0 ];
for (let denominator = 2; order.length < length; denominator *= 2) {
for (let enumerator = 1; enumerator < denominator; enumerator += 2) {
order.push(Math.round(length * enumerator / denominator));
}
}
return order;
}
I'm using very long and clunky variable names to make the principle behind it clearer: if you project the entire interval of [0, width*height] to the interval of [0, 1] then what you're doing is adding 1/2, then 1/4 and 3/4, then 1/8 and 3/8 and 5/8 and 7/8, and so on; each time you multiply the denominator by 2, and take all the odd-numbered multiples.
(Addendum: you can probably squeeze even better performance out of it by using a fixed-length TypedArray for the results, and adding elements by index instead of using .push(). I just didn't want to obscure the gist of the solution with the additional loop variable and such.)
I've got a 2x3 table that I'm adding to EaselJS...currently I'm building it like this:
for (var i = 0; i < 6; i++) {
if(i == 1 || i == 3 || i == 5) {
var xPos = playersBoxW;
} else {
var xPos = 0;
}
if(i == 2 || i == 3) {
var yPos = playersBoxH;
} else if (i == 4|| i == 5) {
var yPos = playersBoxH*2;
} else {
var yPos = 0;
}
playerBox[i] = new createjs.Container().set({x: xPos, y: yPos});
}
It just seems a very inefficient way of doing it and not useful if the table grows. Anyone else have an idea to simplify this?
If you are just trying to do row/column math, there is an easier way.
Here is your original example (with some code to make it work) http://jsfiddle.net/u3ds24y5/
You can just derive the column and row with a simple equation. This lets you change the number of columns and total count easily.
var column = i % num_columns;
var row = Math.floor(i / num_columns);
var x = column * column_width;
var y = row * row_height;
Here is an updated fiddle: http://jsfiddle.net/u3ds24y5/1/
Simplified code:
var cols = 2, total = 6; // Change these
for (var i = 0; i < total; i++) {
var xPos = i % cols * playersBoxW,
yPos = Math.floor(i/cols) * playersBoxH;
// Create container, etc
}
Looking at your code I think this algorithm is essentially what it boils down to:
xPos seems to be equal to the integer division of i (by table width) times playersBoxW. e.g if i = 3 and width is 2, then xPos is equal to playersBoxW times int division of 3/2 which is 1.
yPos seems to be equal to the integer division of i (by table height) times playersBoxH. e.g if i = 4 and height = 3, then yPos is equal to playersBoxH times int division of 4/3 which is 1.
function integerDivision(a, b) {
return Math.floor(a / b);
}
function makeTable(width, height, player, arr) {
var xPos, yPos, size = width*height;
for (var i = 0; i < size; i++) {
xPos = player.boxW * integerDivision(i, width);
yPos = player.boxH * integerDivision(i, height);
arr[i] = new createjs.Container().set({x: xPos, y: yPos});
}
return arr;
}
Integer division is like regular division but you throw the remainder away. So in this case we round the number down:
3/2 = 1.5 => floor the result (round down) => 1
Side node: EaslJS containers can be expensive sometimes so be careful with them.
Containers have some overhead, so you generally shouldn't create a Container to hold a single child. [easljs doc]
I'm a JS amateur. I'm looking to randomly set the width and opacity of a bunch of span elements to create an animation effect.
At the moment, the width is set and re-set using setInterval every second which is almost working fine...
$(function () {
setInterval(function () {
// Variables for background colour
var minFloat = 0.3,
maxFloat = 0.9,
randFloat = Math.floor(Math.random() * (maxFloat - minFloat + 1)) + minFloat;
// Set random width
$('.footerbars span').css('width', Math.random() * 10 + '%');
// Set random alpha
$('.footerbars span').css('background-color', 'rgba(58,130,255,' + randFloat + ')');
}, 1000);
});
What I need is:
the widths of the spans to be each be a different percentage, and for all of those percentages to always total 100%.
and the background alpha channel to be random for each span
Any help is awesome!! Thanks in advance
The first problem is that all widths and backgrounds will be set to be the same as the random numbers are only generated once. You need something like:
$('.footerbars span').each(function(i, e) {
$(e).css('width', (Math.random() * 10) + '%')
.css('background-color', 'rgba('58,130,255,' + ((Math.random() * 0.6) + 0.3) +')');
});
The problem with this is that the widths may not all add up to 100%. To solve this we need to first generate the set of random numbers, then scale them so they add up to 100, and then apply them to the spans.
var numSpans = $('.footerbars span').length;
var widths = [];
var total = 0;
for(var i = 0; i < numSpans; i++) {
widths[i] = Math.random()+1; // generate a new random width for this span - and make it definitely not zero
total += widths[i]; // and update the total width so far;
}
// Now we know what the total random number is (something between numSpans and 2*numSpans)
// we can scale these so the sum actually is 100
for(var i = 0; i < numSpans; i++)
widths[i] = Math.floor(widths[i] * (100 / total));
Now widths[i] contains the % width of the ith span in .footerbars, so amend the second line of the first bit of code to be:
$(e).css('width', widths[i])
Full code:
var numSpans = $('.footerbars span').length;
var widths = [];
var total = 0;
for(var i = 0; i < numSpans; i++) {
widths[i] = Math.random()+1; // generate a new random width for this span - and make it definitely not zero
total += widths[i]; // and update the total width so far;
}
// Now we know what the total random number is (something between numSpans and 2*numSpans)
// we can scale these so the sum actually is 100
for(var i = 0; i < numSpans; i++)
widths[i] = Math.floor(widths[i] * (100 / total));
$('.footerbars span').each(function(i, e) {
$(e).css('width', widths[i])
.css('background-color', 'rgba('58,130,255,' + ((Math.random() * 0.6) + 0.3) +')');
});