Multiple colors drawn for NSBezierPath in cycle - draw

I have following code in func draw(_ dirtyRect: NSRect) method but all the lines are drawn with the same color even if it should be randomized. I read that it may has something to do with fps but is there any way how to draw it multicolored?
Thanks for any hint.
for y in 1...3 {
for x in 1...20 {
switch arc4random_uniform(5) {
case 0:
color = NSColor.red
case 1:
color = NSColor.purple
case 2:
color = NSColor.green
case 3:
color = NSColor.blue
case 4:
color = NSColor.yellow
default:
color = NSColor.yellow
}
point.move(to: NSPoint(x: x*10, y: y))
point.line(to: NSPoint(x: x*10, y: y+100))
color.setStroke()
point.stroke()
}
}

Finally I found the solution or at least workaround - I put declaration of
let point = NSBezierPath()
into inner "x" loop and it works as expected. Not sure if it`s the mos efficient and proper solution so any further suggestions are welcome.

Related

Unable to setRotation to PhysicsBody::createBox in cocos2dx

I'm able to rotate the sprite 90-degree angle but unable to change the angle of the physics body. My purpose is to connect multiple sprites with createBlock() to make a breakable tower object. I want to add setRotation() to PhysicsBody::createBox but error showed up and was unable to implement what I want to do. I googled for some solutions but wasn't able to find a helpful solution to my problem. I would love to hear some tips or examples from you!
Here is the function to create a Block sprite. Added 90 so that the sprite will be rotated to 90 degrees.
createBlock(BlockType::Block1, Point(586, 150), 90);
↓
void GameLayer::createBlock(BlockType type, Point position, float angle)
{
std::string fileName;
switch (type)
{
case BlockType::Block1:
fileName = "block1.png";
break;
case BlockType::Block2:
fileName = "block2.png";
break;
case BlockType::Roof:
fileName = "roof.png";
break;
default:
fileName = "stone.png";
break;
}
auto block = Sprite::create(fileName.c_str());
block->setPosition(position);
block->setRotation(angle);
block->setTag(T_Block);
PhysicsBody* body;
switch (type)
{
case BlockType::Block1:
case BlockType::Block2:
{
body = PhysicsBody::createBox(block->getContentSize(), PhysicsMaterial(0.5, 0.5, 0.3));
body->setDynamic(true);
body->setContactTestBitmask(0x01);
break;
}
case BlockType::Roof:
{
Point points[3] = {Point(-50, -25), Point(0, 25), Point(50, -25)};
body = PhysicsBody::createPolygon(points, 3, PhysicsMaterial(0.5, 0.5, 0.3));
body->setDynamic(true);
body->setContactTestBitmask(0x01);
break;
}
default:
{
body = PhysicsBody::createBox(block->getContentSize(), PhysicsMaterial(0.5, 0.5, 0.3));
body->setDynamic(false);
break;
}
}
block->setPhysicsBody(body);
addChild(block, Z_Block);
}
If you want to rotate not only the sprite but also physics, we must call setRotation(angle) after calling block->setPhysicsBody(body).
So, please fix code like below...
1st: block->setPhysicsBody(body);
next: block->setRotation(angle);
last: addChild(block, Z_Block);
I know your code and have experienced same problem before! I have this text book, too.(^ ^)

Color based on distance

This question already has a working answer at : Weird graphical bug in > AS3?
I'm trying to make a simple tile lighting system in AS3 and the problem I've come across is that I have no idea how to change the color based on distance using hexadecimal color codes
heres the code for the color changing part:
for (var i:int = 0; i < buttons.length; i++) {
lightFact = getDistance(lightSource, buttons[i])
colorTransform2.color = 0x000000
DisplayObject(buttons[i]).transform.colorTransform = colorTransform2;
}
lightFact being the distance from the lightSource, if you can't figure that out from the function name.
I'm not sure what the final objective is for this code but here we go.
getDistance() should return a numeric value. Next step is to create a function or algorithm that codify a number into a color. This could be just setting the R of the RGB color equals to the distance (setting a cap in 255) or many if-else statements like:
if(lightFact < XValue)
{
colorTransform2.color = 0xFF0000;
}
else if(lightFact < YValue)
{
colorTransform2.color = 0x00FF00;
}
else
{
colorTransform2.color = 0x0000FF;
}
or any other more complex codification you might like. Any codification you choose will, either way, need some kind of logic that checks lightFact's value and based on it (and any other variables you may have) makes a calculation or decision to set a different value to colorTransform2.color. Otherwise colorTransform.color will always be 0x000000 (black/turned off).

html5 canvas: clipping by color

is there any way to choose an area on the canvas by color and clip it?
I want to be able to clip an undefined aread that the only thing in common between all the pixels is that they all have the same color.
thanks
Live Demo
Below is a way to select a color.. and do whatever you want with it. I pass a color I want to find iterate over every pixel and remove the color that matches, since Im not sure what you meant by clipping I assumed you mean remove. However please note on large images this method will be slow.
// Takes an array with 3 color components, rgb
function removeColor(color){
var canvasData = ctx.getImageData(0, 0, 256, 256),
pix = canvasData.data;
for (var i = 0, n = pix.length; i <n; i += 4) {
if(pix[i] === color[0] && pix[i+1] === color[1] && pix[i+2] === color[2]){
pix[i+3] = 0;
}
}
ctx.putImageData(canvasData, 0, 0);
}
removeColor([0,0,255]); // Removes blue.
And like Simon pointed out the code above will get the exact color. Below will grab the approximate color, which is good if you have colors overlapping or very close to each other.
Demo 2 with approximation

What does the mask parameter do in the threshold method of the BitmapData class?

I'm trying to replace a color and colors near it in a bitmap.
threshold() seems to work but it seems to be that you have to specify the exact color "==" or all colors before or after the exact color "<" & ">" plus "<=" and ">=". I am hoping that the mask parameter will help me find a way to find a color and a dynamic range of colors before and after it to be replaced. What is its intended usage?
Per the comment below Example 1 and 2:
bit.threshold(bit, bit.rect, point, ">", 0xff000000, 0xffff0000, 0x00FF0000);
bit.threshold(bit, bit.rect, point, ">", 0xff000000, 0xffff0000, 0x00EE0000);
If you're trying to do a flood fill, I don't think the mask parameter will help you. The mask parameter lets you ignore parts of the color in the test. In your case, you want to take into account all the channels of the color, you just want the matching to be fuzzy.
e.g. If you want to replace all pixels where the red component is 0, you can set mask to 0x00FF0000, so it will ignore the other channels.
The implementation pseudo-code probably looks something like this:
input = readPixel()
value = input & mask
if(value operation threshold)
{
writePixel(color)
}
Neither of your samples will produce anything because the mask limits the values to be between 0x00000000 and 0x00FF0000, then tests if they're greater than 0xFF000000.
I have also done this and eventually, I have found it best to create my own threshold-method. You can find it below. Everything is explained in comment.
//_snapshot is a bitmapData-object
for(var i:int = 0; i <= _snapshot.width; i++)
{
for(var j:int = 0; j <= _snapshot.height; j++)
{
//We get the color of the current pixel.
var _color:uint = _snapshot.getPixel(i, j);
//If the color of the selected pixel is between certain values set by the user,
//set the filtered pixel data to green.
//Threshold is a number (can be quite high, up to 50000) to look for adjacent colors in the colorspace.
//_colorToCompare is the color you want to look for.
if((_colorToCompare - (100 * _threshold)) <= _color && _color <= (_colorToCompare + (100 * _threshold)))
{
//This sets the pixel value.
_snapshot.setPixel(i, j, 0x00ff00);
}
else
{
//If the pixel color is not within the desired range, set it's value to black.
_snapshot.setPixel(i, j, 0x000000);
}
}
}

Limiting custom BlendMode made with PixelBender - how to merge images

i need to mix two images one photo and a placeholder. The idea is that we see the placeholder except where the palceholder has a particular color, in that case the user sees the photo. Something like chroma key.
For this purpose i wrote a Pixel Bender shader that acts as a BlendMode. If the background is in the right color output the pixel image otherwhise output the pixel from the placeholder.
<languageVersion : 1.0;>
kernel Crossfade
< namespace : "mynamesp";
vendor : "Artbits snc";
version : 1;
description : "description ... "; >
{
input image4 placeHolder;
input image4 myImage;
output pixel4 dst;
const float3 SPECIAL_COLOR = float3(159.0, 160.0, 161.0);
void evaluatePixel()
{
float4 imgPixel = sample(myImagee, outCoord());
float4 placeHolderPixel = sample(placeHolder, outCoord());
dst = placeHolderPixel;
if(placeHolderPixel.r == (SPECIAL_COLOR.r / 255.0) && placeHolderPixel.g == (SPECIAL_COLOR.g / 255.0) && placeHolderPixel.b == (SPECIAL_COLOR.b / 255.0)){
dst = imgPixel;
}
}
}
Everything works fine except for the fact that i had multiple placeholder, one over the other and my shader don't check the color of its own placeholder but the color of everything under the photo.
Is there a way to force BlendMode to consider only a layer or a specific background color ?
Is there a smarter way to obtain the same result ?
Thanks for your help! i know that this is quite a long and complex question, especially for my english :-)
I assume that you are using this BlendMode on generic DisplayObjects and not directly on BitmapData. In this case PixelBender can only work with the data that gets passed in from the drawing API, so you have to make sure that only those layers are used. They way to do it is to add only the placeholder object and the image object to one holder Sprite.