Using Semaphores to ensure order - semaphore

Suppose that there is a game where three players move, and each player is given a color (R,G,B). Is there a way to ensure that the players move in the order R then G then B using only semaphores, if three routines must be made (one for each player's move)? (Assuming that R will always start).
This question is not supposed to take into account any special type of semaphores that might be found in a particular programming language, instead it should just be a textbook semaphore.
My proposed solution was (in pseudo code):
Red {
wait(R)
wait(B)
wait(G)
Move Red
signal(G)
signal(B)
signal(R)
}
Blue {
wait(R)
wait(B)
wait(G)
Move Blue
signal(G)
signal(B)
signal(R)
}
Green {
wait(R)
wait(B)
wait(G)
Move Green
signal(G)
signal(B)
signal(R)
}
But I don't think this works because while Red is guaranteed to go first, then we don't know that Blue is going to get the B semaphore before Green gets it; or even that Blue will get the R semaphore before Green gets it.
Is there another way to do this? Am I missing something?

If you look at your code, the fact that all three 'tasks' (Red, Green, and Blue) all have the same structure is a danger sign that something might be wrong.
Consider the 2 color case first - it might help you think about the problem.
If we want just want red to go before blue, we can write
Red
{
Move Red
signal(R)
wait(B)
}
Blue
{
wait(R)
Move Blue
signal(B)
}
If we want the 3 color case, we can extend that
Red
{
Move Red
signal(R)
wait(B)
}
Green
{
wait(R)
Move Green
signal(G)
}
Blue
{
wait(G)
Move Blue
signal(B)
}
The Red player doesn't have to wait until after he's moved. After he moves, he signals that he's moved and waits for Blue's signal.
The Green player initially waits for Red's signal. When he gets it, he moves and then signals. When we next enter the Green 'function', he will wait for Red's signal again.
The Blue player does the same thing as the Green player, except he's waiting on Green's signal instead of Red's.
You can see that this can be generalized for any positive integer number of colors.

I think you can achieve this with a circular signaling.
For a starting the game you need to signal the Player 1 directly.
Then sequence would follow as:
- Wait on red. Move red. Signal blue.
- Wait on blue. Move blue. Signal green.
- Wait on green. Move green. Signal red.

Related

How to do a batch rendering?

I have 4 - 5 targets. I draw several triangles for each of them.
while !window.should_close() {
for target in targets.iter() {
// Update uniform (target.color_value [red, blue, green, yellow] )
// BindVertexArray
// DrawElements
}
}
Everything works and my triangles are drawn on the screen in different colors.
Can I have one buffer that I bind once and run the draw command once? Something like
while !window.should_close() {
for target in targets.iter() {
// Update uniform (target.color_value [red, blue, green, yellow] )
}
// BindVertexArray
// DrawElements
}
I tried, but everything is drawn in yellow, as I expected.
I found How to draw multiple objects by using uniform buffer objects and instanced rendering? as well as glMultiDrawArraysIndirect and glDrawArraysInstanced.
I'm confused about how to organize my code.
You can specify only one uniform value for all vertexes per draw call.
You can provide additional attribute with color value for each vertex. It'll work the same way how you provide coordinate attribute for triangle vertexes.

How to tell if a color is imaginary/impossible?

Short version
How can I tell if a color (e.g. XYZ) is impossible? (Wikipedia: Imposible color)
For example, this color is impossible:
XYZ: (15.96, 84.04, 0)
xyY: (0.1595, 0.8404, 0.8404)
Lab: (93, -196, 161) (D65 whitepoint)
It's impossible because it lies outside of the chromacity diagram:
How can I know that?
Incorrect code
The goal is for someone to fill in the function:
Boolean IsImaginaryColor(Single X, Single Y, Single Z)
{
//...TODO: Get someone to answer the question.
}
Right now we know that if any of the components of a corresponding LMS color are negative, then the color is imaginary.
That is a necessary, but not sufficient, condition for a color to be real. You can have all three components of LMS be positive, but it still be an imaginary color.
Boolean IsImaginaryColor(Single X, Single Y, Single Z)
{
//If any component of LMS color is negative,
//then the color is definitely imaginary.
LMSColor lms = XYZtoLMS(X, Y, Z);
if ((lms.L < 0) or (lms.M < 0) or (lms.S < 0))
return true;
//The color may still be imaginary,
//but i don't know how to solve that problem
//So as a first approximation i'll say it's real
return false;
}
LMSColor XYZtoLMS(Single X, Single Y, Single Z)
{
//perform Matrix multiplication:
//
// LMS = M * XYZ
//
// Where M is the M_CAT02 transformation matrix from CIECAM02
//
// 0.7328, 0.4296, -0.1624
// -0.7036, 1.6975, 0.0061
// 0.0030, 0.0136, 0.9834
LMSColor result;
result.L = 0.7328*X + 0.4296*Y + -0.1624*Z
result.M = -0.7036*X + 1.6975*Y + 0.0061*Z
result.S = 0.0030*X + 0.0136*Y + 0.9834*Z
}
In the xy color plane, this gives a good first-approximation (and nice visual indication) of impossible colors:
But the calculation still gives colors outside the chromacity diagram *(technically they're outside the "spectral locus"). So obviously only checking for negative components in LMS is incomplete.
Long Version
I am rendering a color picker. For example:
to pick an Lab color
you pick an ab color
for a given L plane
This is similar to what you can already do in Photoshop:
So in this case I've picked the color:
Lab: (72, -58, 119)
That color (assuming the D65 whitepoint) corresponds to the XYZ color:
Lab: (72, -58, 119)
XYZ: (25.22, 43.66, 0.36)
You can tell if a real color is outside the sRGB color gamut if one of its components is either:
less than 0
greater than 255
This XYZ color lies outside of the sRGB color space because one of it's components is negative:
XYZ: (25.22, 43.66, 0.36)
Lab: (72, -58, 119) (D65)
RGB: (106.1, 199.6, -234.7) (sRGB)
Photoshop already knows if a color is outside the sRGB color gamut, and will display a gumut warning:
But I'd like to go one step further
I can already know if a color is outside the sRGB color gamut.
But now i want to know if a color is imaginary, so i can continue to show the gamut, but hide completely impossible colors. A conceptual mockup might be:
Warning: I have no idea which of those colors actually are impossible. This is only the idea of the concept.
So what I need to know is if a color is impossible.
Background Theory - What is an example of an impossible color?
The Wikipedia page on Impossible colors notes that while the primaries for the sRGB color space all lie inside the spectral locus - and so are all real colors:
The ProPhotoRGB color space does use some primaries that are impossible:
The ProPhoto RGB color space uses imaginary green and blue primaries to obtain a larger gamut (space inside the triangle) than would be possible with three real primaries. However, some real colors are still irreproducible.
So now I have a concrete example of an impossible color: the green primary of the ProPhoto RGB color space:
| Color | CIE x | CIE y |
|-------|--------|--------|
| red | 0.7347 | 0.2653 |
| green | 0.1596 | 0.8404 | <--- this one
| blue | 0.0366 | 0.0001 |
| white | 0.3457 | 0.3585 |
This impossible color, given different color spaces, is:
xyY: (0.1596, 0.8404, 0.8404)
XYZ: (15.96, 84.04, 0)
LMS: (47.80, 131.43, 1.19)
Lab: (93.4679, -195.9973, 161.1515)
LCHab: (93.4679, 253.7415, 140.5725)
How can I tell that this color is impossible?
Given an XYZ color, how can I tell that it is impossible? E.g.:
XYZ: 15.96, 84.04, 0
Bonus Chatter
It's important to note the difference between
colors existing outside some gamut
and imaginary colors
A quick single-image primer would be:
Gamut: a color may not be displayable on your monitor, or printer, or phone, but it is still a real color - you could get a combination of Electromagnetic Waves of various wavelengths and intensities to generate the color
Imaginary: No combination of EM waves, of any intensities, of any wavelengths, can generate that response in the Long, Medium, and Short human cones
I already know how to tell if a color exists outside a particular color gamut.
I want to know if a color also exists outside the spectral locus.
In other words: i want to know if it is imaginary.
Bruce Lindbloom has a nice graphic that raises the issues of colors outside the Lab color space when you arbitrary choose to arbitrarily limit the a and b component values to +- 128:
Bonus Reading
https://physics.stackexchange.com/q/94375/
Determine that a Luv Color is non-imaginary
https://physics.stackexchange.com/questions/420614
This is a duplicate of the answer I gave here: Determine that a Luv Color is non-imaginary which relate to https://stackoverflow.com/a/48396021/931625
I think the safe way is to compute the XYZ volume boundaries and check if you are within or outside.

Angle calculation resulting in strange behavior

So, I found some code to essentially have a rectangle follow the mouse around my player object at a set distance. On a 2D plane, I have the character, and when the player clicks the mouse button, a shield will appear between the mouse and the character. This part works, and here is the code:
var angle;
var track_radius = 10;
// find the angle to the mouse
angle = point_direction(self.x, self.y, mouse_x, mouse_y);
// turn the shield to look at the mouse
image_angle = angle;
// convert to radians for the math functions
angle = degtorad(angle);
// place the shield on a circular track about the player
// . track_radius is set in the create event
x = global.playerX + 50 * cos(angle);
y = global.playerY - 50 * sin(angle); // minus
So, the problem comes in when the mouse comes close to the shield. The shield splits into two, mirrored across the mouse pointer, flickering back and forth. The problem continues basically anytime the mouse is near or within the radius where the shield exists. It's also probably worth noting that the shield is created AT the position of the player when the mouse is clicked, and then moved using the above code. Thoughts?
angle = point_direction(self.x, self.y, mouse_x, mouse_y);
This code is calculating the angle from the shield to the mouse pointer, because self currently refers to the shield.
x = global.playerX + 50 * cos(angle);
y = global.playerY - 50 * sin(angle); // minus
Here you set the position of the shield relative to the player, so that the angle from the player to the shield equals the angle that you calculated above.
Now consider the situation where the mouse is close to the shield, and the direction from the shield to the mouse is different than the direction from the player to the mouse. In the bad ASCII graphic below, imagine the O is the player, the ) is the shield and the ^ is the mouse cursor.
O ------ )
^
The shield is directly to the right of the player (0°), but the mouse is directly below the shield (270°). Therefore your code will place the shield directly below the player (remember, angle in your code is the direction from the shield to the mouse)
O
| ^
|
|
)
In the next step, the code again takes the direction from the shield to the mouse. This time it's more like 45° above the shield, so the shield will be placed 45° above and to the right of the player.
This jumping back and forth happens a few times with changing positions, until the shield "settles" in two alternating positions around the mouse cursor.
To come to the solution, you want to use the direction from the player to the mouse cursor to determine your shield position, not the direction from the shield to the mouse cursor. But I have to say that the dynamics of the system you accidentally created are somewhat interesting :)

OpenCV specific object detection

After doing some research and reading information about OpenCV object detection, I am still not sure on how can I detect a stick in a video frame. What would be the best way so i can detect even if the user moves it around. I'll be using the stick as a sword and make a lightsaber out of it. Any points on where I can start? Thanks!
The go-to answer for this would usually be the Hough line transform. The Hough transform is designed to find straight lines (or other contours) in the scene, and OpenCV can parameterize these lines so you get the endpoints coordinates. But, word to the wise, if you are doing lightsaber effects, you don't need to go that far - just paint the stick orange and do a chroma key. Standard feature of Adobe Premiere, Final Cut Pro, Sony Vegas, etc. The OpenCV version of this is to convert your frame to HSV color mode, and isolate regions of the picture that lie in your desired hue and saturation region.
http://opencv.itseez.com/doc/tutorials/imgproc/imgtrans/hough_lines/hough_lines.html?highlight=hough
Here is an old routine I wrote as an example:
//Photoshop-style color range selection with hue and saturation parameters.
//Expects input image to be in Hue-Lightness-Saturation colorspace.
//Returns a binary mask image. Hue and saturation bounds expect values from 0 to 255.
IplImage* selectColorRange(IplImage *image, double lowerHueBound, double upperHueBound,
double lowerSaturationBound, double upperSaturationBound) {
cvSetImageCOI(image, 1); //select hue channel
IplImage* hue1 = cvCreateImage(cvSize(image->width, image->height), IPL_DEPTH_8U, 1);
cvCopy(image, hue1); //copy hue channel to hue1
cvFlip(hue1, hue1); //vertical-flip
IplImage* hue2 = cvCloneImage(hue1); //clone hue image
cvThreshold(hue1, hue1, lowerHueBound, 255, CV_THRESH_BINARY); //threshold lower bound
cvThreshold(hue2, hue2, upperHueBound, 255, CV_THRESH_BINARY_INV); //threshold inverse upper bound
cvAnd(hue1, hue2, hue1); //intersect the threshold pair, save into hue1
cvSetImageCOI(image, 3); //select saturation channel
IplImage* saturation1 = cvCreateImage(cvSize(image->width, image->height), IPL_DEPTH_8U, 1);
cvCopy(image, saturation1); //copy saturation channel to saturation1
cvFlip(saturation1, saturation1); //vertical-flip
IplImage* saturation2 = cvCloneImage(saturation1); //clone saturation image
cvThreshold(saturation1, saturation1, lowerSaturationBound, 255, CV_THRESH_BINARY); //threshold lower bound
cvThreshold(saturation2, saturation2, upperSaturationBound, 255, CV_THRESH_BINARY_INV); //threshold inverse upper bound
cvAnd(saturation1, saturation2, saturation1); //intersect the threshold pair, save into saturation1
cvAnd(saturation1, hue1, hue1); //intersect the matched hue and matched saturation regions
cvReleaseImage(&saturation1);
cvReleaseImage(&saturation2);
cvReleaseImage(&hue2);
return hue1;
}
A little verbose, but you get the idea!
My old professor always said that the first law of computer vision is to do whatever you can to the image to make your job easier.
If you have control over the stick's appearance, then you might have the best luck painting the stick a very specific color --- neon pink or something that isn't likely to appear in the background --- and then using color segmentation combined with connected component labeling. That would be very fast.
You can start by following the face-recognition (training & detection) techniques written for OpenCV.
If you are looking for specific steps, let me know.

RGB range for cold and warm colors?

What are ranges of cold and warm colors (http://www.diy-bathroom-remodel.com/images/color_wheel.gif) in RGB?
Taking the image you linked to as a reference of what is "warm" and "cold", we get the following.
The hottest colour is completely red (R=255, G=0, B=0).
The coldest colour is completely blue (R=0, G=0, B=255).
So the more R you have, the warmer the colour, and the more B you have, the cooler the colour. The G takes you through shades of turquoise, green, and yellow, each being increasingly warmer. When G is zero, you move in the lower left diagonal of the circle when R and B change. As G approaches 255, you cross over the upper right diagonal when R and B change.
However, the adjacent warm and cool colours have a different amount of green in them. The red immediately below the diagonal line has less green than the red immediately above it. The blue immediately below the diagonal line has less green than the blue immediately above it. This colour wheel looks like it doesn't represent the RGB space all that well especially in the blue end of the spectrum.
Ultimately, what you perceive as warm and cold depends on your monitor settings and light conditions. A lot of it is also your perception and cognition – what you think is warm or cold. In an image, the colour contrasts will affect your judgement. An "in-between" colour next to a clearly cool colour will look warm, but if the same colour is next to a clearly warm colour, it will look cool. Take a look at this colour wheel:
Here, every single 24-bit colour is shown (8 bits for each of R, G, and B), and the RGB values for the top, right, bottom, and left colours are shown. To my eye, there are more "cool" colours than "warm". Hope this helps you decide what the RGB values are for what you perceive as cool and warm colours.
Bonus: In the image above, you can also see the colours expressed in the hue, saturation, and value (HSV) colour model. Hue basically encodes the colour. Saturation encodes how "full" the colour is – less saturation makes it more "bleak", ie. white. Value encodes how dark it is – less value makes it more black, and also makes the white of the saturation more grey. Hue goes from 0 to 360 and corresponds to the angle of a circle, with 0 being totally red, 90 being a sort of neon green, 180 being bright blue, 270 being bluish purple, and 360 going back to red again. S and V go from 0 to 100 and will influence the exact shade – these examples are with S=V=100.
To my eye, H values in the ranges 0-80 and 330-360 are warm while H>80 and H<330 are cold (approximately).
You may want to open the colour selector in your favourite paint program. They can usually show HSV and RGB side by side and let you play with a colour wheel and see the effects on the HSV and RGB numbers. If you don't already have one, I would suggest GIMP. It has the colour wheel I've been using to get the numbers for this answer.
Bonus 2: All of the above assumes a subjective assessment of what is warm and what is cool. I think the only way to make an objective measurement of colour temperature is to measure it and express it on a temperature scale. Often Kelvin seems to be used. This measure takes into account not only shade of the colour, but its brightness (or how much light it emits) too. If you have a modern monitor, it probably has a temperature setting with some Kelvin values to choose from. It is possible to calculate the temperature of each RGB colour on your display, as long as you know the temperature of your white (the white balance). However, this calculation is very complex and I don't know how to do it. You may find Bruce Lindbloom a good source for further information, or any book on colour science. But I guess this is more than you bargained for with your question... ;-)
Looks to me like
if (B>R) {
color=cool
} else {
color=warm
}
is a pretty good approximation. You can check this out on your color wheel using:
http://www.colorzilla.com/firefox/
already answered but need to add this:
If you are interested in physical temperature and color dependencies then this is the scale you are looking for:
It is the color of light emitting from blackbody of given temperature. In astronomy is this used for star color classification (like BV color index).
It also can be used for indirect temperature measurements.
I've found these parameters satisfactory
For Warm color :
R from 128 to 255
G from 0 to 128
B from 0 to R
For Cold color :
R from 0 to B
G from 0 to 255
B from 128 to 255
Note that high green makes the color more cold (in my view but that's debatable ^^), that's why it's restricted for warm colors but not for cold ones.
Warm colors have more red,
and cool colors have more blue.
In RGB:
red = 0
blue = 0
if (red > blue) {
isWarmColor = true
isCoolColor = false
}
else if (red < blue) {
isWarmColor = false
isCoolColor = true
}
else {
isWarmColor = false
isCoolColor = false
}
In HSL:
hueAngle = 0
if (hueAngle < 0 || hueAngle > 360 || hueAngle == 90 || hueAngle == 270) {
isWarmColor = false
isCoolColor = false
}
else if (hueAngle > 90 && hueAngle < 270) {
isWarmColor = false
isCoolColor = true
}
else if (hueAngle < 90 && hueAngle > 270) {
isWarmColor = true
isCoolColor = false
}
Simple and accurate:
def is_hot(a):
return (a[..., 'RED'] > 128)
where 'RED' stands for the index of the red channel in the array a.
This works -- you can see for yourself by: (a) looking at the second wheel by Fabian Fagerholm and/or (b) go to the following link and move the bar up and down towards the two warm ends.
https://www.colorspire.com/rgb-color-wheel/
For me below calculation, with the inclusion of saturation, gives a better result. Since fully desaturated colors like Black, White and Gray are considered neutral colors.
if (hueAngle == 90 || hueAngle == 270 || (hueAngle == 0 && saturation == 0))
{
isWarmColor = false;
isCoolColor = false;
}
else if (hueAngle > 90 && hueAngle < 270)
{
isWarmColor = false;
isCoolColor = true;
}
else
{
isWarmColor = true;
isCoolColor = false;
}

Resources