Changing the opacity of a CCSprite in a CCSpriteBatchNode - cocos2d-iphone

Can the opacity of a CCSprite in a CCSpriteBatchNode be modified?
The following doesn't seem to work:
((CCSprite *)[batchNode getChildByTag:myTag]).opacity = 0.5;
The sprite just disappears instead of showing up with modified opacity.

This is why it's a good idea to look at the types. opacity property of CCSprite is GLubyte. Looking at GLubyte's typedef, we see that it's actually unsigned char, which means that it takes integer values from 0 to 255. With sprite.opacity = 0.5 you implicitly convert floating point value to unsigned char, fractional part of 0.5 is truncated, and sprite.opacity becomes 0.

Related

How do I end up with a negative value in this chain of transformations?

I am displaying pressure values in the range of 0 - 5, with two decimal places. However recently I got a negative value -0.05 shown.
Can someone explain how this tranformation chain can end up with a negative value? The only idea I have right now is an unreasonably high input value, but maybe I am not seeing something.
(Copied together from various source files)
double value = <the input value in bar>;
value -= 1; //subtract atmospheric pressure
value *= 100; // preserve decimal places
unsigned int ui_value = static_cast<unsigned int>(value);
int intValue = ui_value; // uint value is input into a function taking int as argument
double v = ((double)intValue) / std::pow(10.0f, 2); // scale back
std::stringstream tmp;
tmp << std::fixed << std::setprecision(2) << v;
Somehow this ended up giving me -0.05. I have no idea what the input was, but if everything was functioning correctly, then it should have been a bar value around 2.5 - 3.5.
What happened here that could have resulted in a negative value?? Note that there were 4 pressure sensors all giving the same wonky result, so I somewhat doubt it was a hardware issue, but at the same time I don't see how a "normal" input value could have resulted in a negative value here. Even with a negative input I would expect the conversion to uint to get rid of the sign and give a wrong but positive result.
In case this is somehow compiler dependent, I am using Embarcadero C++ Builder 10.1 Berlin.
The conversion from double type to unsigned is undefined, when unsigned can't "represent" the value of double, for example the double value is negative. From cppreference implicit conversion emphasis mine:
A prvalue of floating-point type can be converted to a prvalue of any integer type. The fractional part is truncated, that is, the fractional part is discarded. If the value cannot fit into the destination type, the behavior is undefined (even when the destination type is unsigned, modulo arithmetic does not apply).
To remove the sign, just use std::abs ("abs" is short for absolute value). Do:
double v = std::abs(value) / 100.0f;

Why is that type double instead of float?

Problem: In a homework problem (it is to be done on paper with a pen so no coding) I must determine the type and value of an addition performed in C++.
1 + 0.5
What I've answered is:
Type float (because I thought that integer + float = float)
Value 1.5 (As far as I know when two different datatypes are added,
the result of the addition is going to be converted to the datatype that does not loose any information.)
Solution says:
Type: double
Value: 1.5
My Question: Why is 0.5 a double and not a float? How can I distingish between a float and a double? I mean, 0.5 looks to me like a float and a double.
First of all, yes. integer + float = float. You are correct about that part.
The issue is not with that, but rather your assumption that 0.5 is a float. It is not. In C++, float literals are followed by an f meaning that 0.5f is a float. However, 0.5 is actually a double. That means that your equation is now:
integer + double = double
As you can see, this result is a double. That is why the correct answer to your question is that the resulting type is a double.
By the way, to clear the record, technically what's going on here isn't integer + double = double. What is happening is that the 1 is falling subject to implicit conversion. Essentially, the 1 is converted to a double, since the other side of the operation is a double as well. This way, the computer is adding the same types and not different ones. That means that the actual addition taking place here is more like:
double + double = double
In C++, floating point literals without a type suffix are double by default. If you want it to be float, you need to specify the f suffix, like 0.5f.

The best access pixel value method to an Mat binary image?

I want to ask a question: I have to check the value time by time of a pixel (X,Y) in a binary thresholded OpenCV Mat image.
I have to check if the pixel at the X,Y that I want to verify is black or white (0 or 255)...how is the best method to do this thing?
I have searched and read about direct method (Get2D) or with pointers..but it isn't so clear for me...Image are binary, thresholded and eroded/dilated before...
Can someone post me an example of code of function that I've to use to do this thing?
If you check the same pixel all the time, do it as #Xale says:
mat.at<unsigned char>(x,y) // assuming your type is CV_8U
If you have to do it for several pixels, get the offset of the row first and access the column later:
unsigned char *row = mat.ptr<unsigned char>(y);
// access now row[x1], row[x2]...
There is one more option that is only valid if you only want a single pixel and if all the operations on the image are done on the same allocated memory (it depends on your code and the opencv functions you call). In that case, you can get the pointer to that pixel once, and access it when you need:
unsigned char *px = mat.ptr<unsigned char>(y) + x;
...
unsigned char current_value = *px;
You have to refer to this nice tutorial for accessing cv::Mat elements:
http://docs.opencv.org/doc/tutorials/core/mat_the_basic_image_container/mat_the_basic_image_container.html
There are different ways to achieve it. The main problem when you access the element is to understand the data type of the matrix/image. In you case, if the mat is a binary black and white probab it is of the type CV_8U, and my advice is always check for the type to be sure. Plus, playing with types get you more control on the knowledge of what you're dealing with.
One of the easiest method for accessing pixels is cv::Mat::at that is a template method, and it needs to specify the type, that, if your mati is CV_8U is uchar.
the easy way:
int n = cv::countNonZero(binary_mat);
the hard way:
for ( int i=0; i<mat.rows; i++ )
{
for ( int j=0; j<mat.cols; j++ )
{
uchar pix = mat.at<uchar>(i,j);
...
Hers is a link to another stackoverflow answer. Anyway short answer is
mat.at<Type>(x,y)
where Typeis the type of data stored in the matrixelements. In your case unsigned char

How to build a QImage from known pixel values

I know the height and width, as well as each pixel value (from x,y location) that I want a QImage to be. How can I build a QImage knowing these values?
The second argument to setPixel() is a 24bit RGB value in a single int you can use the QRgb macros to construct it or just (red<<16) + (green << 8) + blue
But unless it's a very small image it will take a long time to call setPixel().
If you have the data I would call Qimage::bits() to get an unsigned pointer to the QImage data and just set the R,G,B values directly for each pixel or use memcpy()
You simply create the object (eg, new QImage(640, 480);) and then use setPixel to change each pixel in the image to the value you want it to be.

C++, Variables reverting to initial values

I have a C++ class, shapeObject, that is somewhat complicated but this question is only regarding two particular fields of the class, dX and dY.
header:
class shapeObject{
public:
shapeObject();
...
private:
float dX, dY;
...
};
cpp file:
shapeObject::shapeObject(){
...
dX = 0;
dY = 0;
...
}
These fields are only modified by one function, which adds or subtracts a small float value to dX or dY. However, the next time the value of dX or dY is read, they have reverted back to their original value of 0.0 .
Since the fields are not being modified anywhere but that one function, and that function is never setting the values to 0.0, I'm not sure why they are reverting to the original value. Any ideas of why this could be happening?
My psychic debugging skills indicate some possibilities:
You're shadowing the members when you assign them float dX = small_float_value; instead of dX = small_float_value;
You're working with different copies of shapeObject and the modified one gets thrown away by accident (or its copy constructor doesn't do the obvious thing).
The values only appear to still be zero in printing but are in fact the small float value you want.
Somehow the small float value gets truncated to zero.
When adding or subtracting a small value try using cast by float like dx=dx+(float)0.001;
Better try using double instead of float.Float has some precision problem.
Perhaps somewhere the small float value is being cast to an int before being added/subtracted so the resulting change is zero?
Need to see more code to do anything more than stab in the dark.