Hey guys, I'm getting a little trouble here. I have a view that makes a grid display. I mean, I have 9 items and sets to display 3 per line. Resulting in 3 lines. That's OK. What I don't understang, it's why always I get a space between them. Sometimes it comes up and on the middle of the lines. The space is equal to one line height.
Check the code:
NSInteger quantidadeDeVideos = [self.videosURL count];
NSInteger contadorDeVideos = 0;
NSInteger idLinha = 0;
NSInteger linha = 1;
NSInteger itemq = 0;
while (contadorDeVideos < quantidadeDeVideos) {
float f;
float g;
// Set the lines
if (itemq < 3) {
itemq++;
}
else {
itemq = 1;
linha++;
}
// This makes the second line multiplies for 150;
if (linha > 1) {
g = 150;
}
else {
g = 0;
}
// Ignore this, this is foi make 1,2,3. Making space between the itens.
if (idLinha > 2) {
idLinha = 0;
}
NSLog(#"%i", foi);
float e = idLinha*250+15;
f = linha*g;
UIImageView *thumbItem = [[UIImageView alloc] init];
thumbItem.frame = CGRectMake(e, f, 231, 140);
UIColor *bkgColor = [[UIColor alloc] initWithPatternImage:[UIImage imageNamed:#"VideosItemBackground.png"]];
thumbItem.backgroundColor = bkgColor;
thumbItem.opaque = NO;
[self.videosScroll addSubview:thumbItem];
contadorDeVideos++;
idLinha++;
}
This is the result should be:
[][][]
[][][]
[][][]
And this is what I'm getting:
[][][]
[][][]
[][][]
Thanks for all!
When linha is 1, g is 0, making linha * g 0. For the subsequent lines, g is 150, making linha * g == 300 for the second iteration (a jump of 300 over the first), after which it increases by 150 each time. Instead of conditionally setting g each time through, you should just make it a constant 150 and then either use (linha - 1) * g for the value of f or just start linha at 0.
If you want to see how to spot the problem yourself:
Ask yourself, what is going wrong here?
The rectangles are being drawn one row too low
It only happens after the first row
So we look at the line that's responsible for where the rectangles are drawn:
thumbItem.frame = CGRectMake(e, f, 231, 140)
The variable f is the y-coordinate. This has to be what's messed up. Let's see how f is defined:
f = linha*g;
OK, linha is the line number and it's only changed once in the loop without any conditional logic. So the problem is probably g. Let's see how that one is defined:
if (linha > 1) {
g = 150;
}
else {
g = 0;
}
Hey, g changes after the first iteration — precisely when our problem crops up. Let's see what the values of linha*g are:
1 * 0 = 0
2 * 150 = 300 (+300)
3 * 150 = 450 (+150)
4 * 150 = 600 (+150)
Ah-ha — the problem is that setting g to 0 on the first iteration breaks the pattern.
Related
I have an image that has been processed throw:
//UIImage to Mat
cv::Mat originalMat = [self cvMatFromUIImage:inputImage];
//Grayscale
cv::Mat grayMat;
cv::cvtColor(originalMat, grayMat, CV_RGB2GRAY);
//Blur
cv::Mat gaussMat;
cv::GaussianBlur( grayMat , gaussMat, cv::Size(9, 9), 2, 2 );
//Threshold
cv::threshold(grayMat,tMat,100,255,cv::THRESH_BINARY);
than I want to analyze (calculate qty of white and black points) that belows to line. For instance: I have an image 100x120px and I want to check lines where x = 5 and y = from 0 to 119; and vice versa x = 0..99; y = 5;
so I expect that Mat will contains x - Mat.cols and y - Mat.rows but looks it saves data in another way. for example I've tried to change pixels color that belows to lines but didn't get 2 lines:
for( int x = 0; x < tMat.cols; x++ ){
tMat.at<cv::Vec4b>(5,x)[0] = 100;
}
for( int y = 0; y < tMat.rows; y++ ){
tMat.at<cv::Vec4b>(y,5)[0] = 100;
}
return [self UIImageFromCVMat:tMat];
result for white image:
why I did't get 2 lines? Is it possible to draw\check lines in Mat directly? what if I going to check line that calculates via y = kx + b?
You are accessing the pixel values in the wrong way. You are working with image that only has one channel, that's why you should access pixel values like this:
for (int x = 0; x < tMat.cols; x++){
tMat.at<unsigned char>(5, x) = 100;
}
for (int y = 0; y < tMat.rows; y++){
tMat.at<unsigned char>(y, 5) = 100;
}
The Mat element's type is defined by two properties - the number of channels and the underlying type of data. If you do not know the meaning of those terms, I strongly suggest that you read the documentation for methods cv::Mat::type(), cv::Mat::channels() and cv::Mat::depth().
Two more examples:
mat.at<float>(x, y) = 1.0f; // if mat type is CV_32FC1
mat.at<cv::Vec3b>(x, y) = Vec3b(1, 2, 3); // if mat type is CV_8UC3
Probably an issue with your Mat data types. The output of threshold is a single channel image that is 8-bit or 32-bit (http://docs.opencv.org/2.4/modules/imgproc/doc/miscellaneous_transformations.html?highlight=threshold#threshold), so you probably should not be setting values with Mat.at<Vec4b>[0].
Here's a function to return the type of your matrix. Usage is in the commented out part. Copied from How to find out what type of a Mat object is with Mat::type() in OpenCV.
std::string type2str(int type){
//string ty = type2str( comparisonResult.type() );
//printf("Matrix: %s %dx%d \n", ty.c_str(), comparisonResult.cols, comparisonResult.rows );
string r;
uchar depth = type & CV_MAT_DEPTH_MASK;
uchar chans = 1 + (type >> CV_CN_SHIFT);
switch ( depth ) {
case CV_8U: r = "8U"; break;
case CV_8S: r = "8S"; break;
case CV_16U: r = "16U"; break;
case CV_16S: r = "16S"; break;
case CV_32S: r = "32S"; break;
case CV_32F: r = "32F"; break;
case CV_64F: r = "64F"; break;
default: r = "User"; break;
}
r += "C";
r += (chans+'0');
return r;}
As part of a calculator app, I am trying to implement uses with sigma notation. However, the result it prints out is always a decimal, and the rest isn't important. I simply want to change the decimal to a fraction.
I already have the reduce function, the problem I'm having is getting from a decimal like this: '0.96875' to it's fractional value, '31/32'
Thanks!
PS: I've looked into just about everything, and for the life of me, I can't figure this out. All I need at this point is how to take the decimal out of it, and I can then reduce it.
Here is my reduce method:
-(void)reduce {
int u = numerator;
int v = denominator;
int temp;
while (v != 0) {
temp = u % v;
u = v;
v = temp;
}
numerator /= u;
denominator /= u;
}
Found this out myself. What I did was multiply the numerator and denominator by 1000000 (recalling that the decimal looked like .96875/1) so that it looked like 96875/100000.
Then, I used this reduce method to bring it into lowest terms:
-(void)reduce {
int u = numerator;
int v = denominator;
int temp;
while (v != 0) {
temp = u % v;
u = v;
v = temp;
}
numerator /= u;
denominator /= u;
}
And finally,I used a print method to get it into fraction form:
//In the .h
#property int numerator, denominator, mixed;
-(void)print;
//In the .m
#synthesize numerator, denominator, mixed;
-(void)print {
if (numerator > denominator) {
//Turn fraction into mixed number
mixed = numerator/denominator;
numerator -= (mixed * denominator);
NSLog(#"= %i %i/%i", mixed, numerator, denominator);
} else if (denominator != 1) {
//Print fraction normally
NSLog(#"= %i/%i", numerator, denominator);
} else {
//Print as integer if it has a denominator of 1
NSLog(#"= %i", numerator);
}
}
And got my desired output:
31/32
I found a fairly good way of doing this a while back, although I don't recall where from. Anyway, it works recursively like this (this is pseudocode, not C):
function getRational(float n)
let i = floor(n); (the integer component of n)
let j = n - i;
if j < 0.0001 (use abritrary precision threshold here), return i/1
let m/n = getRational(1 / j)
return ((i * m) + n) / m
For example, take 3.142857 as a starting point.
i = 3
j = 0.142857
m/n = getRational(7)
i = 7
j = 0
return 7/1
m/n = 7/1
return ((3*7)+1) / 7 = 22/7
Or a more complicated example, 1.55:
i = 1
j = 0.55
m/n = getRational(1.81818181)
i = 1
j = 0.81818181
m/n = getRational(1.22222222)
i = 1
j = 0.22222222
m/n = getRational(4.5)
i = 4
j = 0.5
m/n = getRational(2)
i = 2
j = 0
return 2/1
m/n = 2/1
return ((4*2)+1)/2 = 9/2
m/n = 9/2
return ((1*9)+2)/9 = 11/9
m/n = 11/9
return ((1*11)+9)/11) = 20/11
m/n = 20/11
return ((1*20)+11)/20 = 31/20
I tried this with PI once. It would have gone on a while, but if you set your threshold to 0.01, it only goes down a few recursions before returning 355/113.
There's a bit of a gotcha that you might end up with integers that are too large if it goes down too deep when it returns; I haven't really looked into a good way of allowing for that, except setting the precision threshold to something fairly lax, such as 0.01.
Try this :
-(NSString *)convertToFraction:(CGFloat)floatValue{
double tolerance = 1.0E-6;
CGFloat h1 = 1;
CGFloat h2 = 0;
CGFloat k1 = 0;
CGFloat k2 = 1;
CGFloat b = floatValue;
do{
CGFloat a = floor(b);
CGFloat aux = h1;
h1 = a*h1+h2;
h2 = aux;
aux = k1;
k1 = a*k1+k2;
k2 = aux;
b = 1/(b-a);
}while (ABS(floatValue-h1/k1) > floatValue*tolerance) ;
return k1 > 1 ? [NSString stringWithFormat:#"%.0f/%.0f",h1,k1] : [NSString stringWithFormat:#"%.0f",h1];
}
I'd like to calculate a non-uniformly distributed random number in the range [0, n - 1]. So the min possible value is zero. The maximum possible value is n-1. I'd like the min-value to occur the most often and the max to occur relatively infrequently with an approximately linear curve between (Gaussian is fine too). How can I do this in Objective-C? (possibly using C-based APIs)
A very rough sketch of my current idea is:
// min value w/ p = 0.7
// some intermediate value w/ p = 0.2
// max value w/ p = 0.1
NSUInteger r = arc4random_uniform(10);
if (r <= 6)
result = 0;
else if (r <= 8)
result = (n - 1) / 2;
else
result = n - 1;
I think you're on basically the right track. There are possible precision or range issues but in general if you wanted to randomly pick, say, 3, 2, 1 or 0 and you wanted the probability of picking 3 to be four times as large as the probability of picking 0 then if it were a paper exercise you might right down a grid filled with:
3 3 3 3
2 2 2
1 1
0
Toss something onto it and read the number it lands on.
The number of options there are for your desired linear scale is:
- 1 if number of options, n, = 1
- 1 + 2 if n = 2
- 1 + 2 + 3 if n = 3
- ... etc ...
It's a simple sum of an arithmetic progression. You end up with n(n+1)/2 possible outcomes. E.g. for n = 1 that's 1 * 2 / 2 = 1. For n = 2 that's 2 * 3 /2 = 3. For n = 3 that's 3 * 4 / 2 = 6.
So you would immediately write something like:
NSUInteger random_linear(NSUInteger range)
{
NSUInteger numberOfOptions = (range * (range + 1)) / 2;
NSUInteger uniformRandom = arc4random_uniform(numberOfOptions);
... something ...
}
At that point you just have to decide which bin uniformRandom falls into. The simplest way is with the most obvious loop:
NSUInteger random_linear(NSUInteger range)
{
NSUInteger numberOfOptions = (range * (range + 1)) / 2;
NSUInteger uniformRandom = arc4random_uniform(numberOfOptions);
NSUInteger index = 0;
NSUInteger optionsToDate = 0;
while(1)
{
if(optionsToDate >= uniformRandom) return index;
index++;
optionsToDate += index;
}
}
Given that you can work out optionsToDate without iterating, an immediately obvious faster solution is a binary search.
An even smarter way to look at it is that uniformRandom is the sum of the boxes underneath a line from (0, 0) to (n, n). So it's the area underneath the graph, and the graph is a simple right-angled triangle. So you can work backwards from the area formula.
Specifically, the area underneath the graph from (0, 0) to (n, n) at position x is (x*x)/2. So you're looking for x, where:
(x-1)*(x-1)/2 <= uniformRandom < x*x/2
=> (x-1)*(x-1) <= uniformRandom*2 < x*x
=> x-1 <= sqrt(uniformRandom*2) < x
In that case you want to take x-1 as the result hadn't progressed to the next discrete column of the number grid. So you can get there with a square root operation simple integer truncation.
So, assuming I haven't muddled my exact inequalities along the way, and assuming all precisions fit:
NSUInteger random_linear(NSUInteger range)
{
NSUInteger numberOfOptions = (range * (range + 1)) / 2;
NSUInteger uniformRandom = arc4random_uniform(numberOfOptions);
return (NSUInteger)sqrtf((float)uniformRandom * 2.0f);
}
What if you try squaring the return value of arc4random_uniform() (or multiplying two of them)?
int rand_nonuniform(int max)
{
int r = arc4random_uniform(max) * arc4random_uniform(max + 1);
return r / max;
}
I've quickly written a sample program for testing it and it looks promising:
int main(int argc, char *argv[])
{
int arr[10] = { 0 };
int i;
for (i = 0; i < 10000; i++) {
arr[rand_nonuniform(10)]++;
}
for (i = 0; i < 10; i++) {
printf("%2d. = %2d\n", i, arr[i]);
}
return 0;
}
Result:
0. = 3656
1. = 1925
2. = 1273
3. = 909
4. = 728
5. = 574
6. = 359
7. = 276
8. = 187
9. = 113
I have the following code, but in this line of code I have warning x[i] = (rhs[i] - x[i - 1]) / b;, compiler is telling me that rhs[i] is a garbage value. Why it's happend? And how to remove this warning?
double* getFirstControlPoints(double* rhs, const int n) {
double *x;
x = (double*)malloc(n * sizeof(double));
double *tmp; // Temp workspace.
tmp = (double*)malloc(n * sizeof(double));
double b = 2.0;
x[0] = rhs[0] / b;
for (int i = 1; i < n; i++) // Decomposition and forward substitution.
{
tmp[i] = 1 / b;
b = (i < n - 1 ? 4.0 : 3.5) - tmp[i];
x[i] = (rhs[i] - x[i - 1]) / b; //The left operand of '-' is a garbage value
}
for (int i = 1; i < n; i++) {
x[n - i - 1] -= tmp[n - i] * x[n - i]; // Backsubstitution.
}
free(tmp);
return x;
}
All compiler warnings and calling getFirstControlPoints you may see on screenshots.
You need a check to make sure you have at least 4 points in the points array because this loop (line 333):
for (NSInteger i = 1 ; i < n - 1 ; ++i) {
// initialisation stuff
}
will not execute at all for n = 0, 1, 2.
Assume that points has 3 objects in it, At line 311 you set n to the count - 1 i.e. n == 2
Then the loop condition is i < 2 - 1 i.e. i < 1.
I think you need the loop condition to be i < n
if points.count is 0 or 1 you are facing some problems, because then, n is -1 or 0, and you access rhs[n-1]; and you malloc n* bytes;
maybe that can be the problem. that you put some rangechecks int o the code?
How do you convert an integer to a usable color (for PictureBox.CreateGraphics)?
The color should start at red, cycle to orange, yellow, etc. and come all the way back around to red again.
This is in vb.net. If I cannot do this, how do I use PictureBox.CreateGraphics with a hex code instead of a pen?
Thanks for the help!
You can use HSB (Hue, Saturation, Brightness) color instead of RGB color. .Net can convert RGB colors to HSB automatically (with the Color.GetHue, .GetSaturation and .GetBrightness methods) but doesn't go in the other direction. Here is a code sample that handles converting HSB colors to RGB:
http://splinter.com.au/blog/?p=29
(this code sample uses "V" instead of "B", probably for "value" instead of "brightness").
The advantage of using HSB color is that the Hue parameter ranges from 0 to 360, and can be interpreted as position on the color wheel, so the values wrap around nicely from 360 back to 0. For your purposes, you could create colors by setting the Saturation and Brightness values to 1.0 (their maximums) and then varying the Hue value to create the different colors of the spectrum.
In regards to your specific question (and to elaborate on Rubens' answer), you can create a Color from any int32 value like this:
int i = 4837429;
Color color = Color.FromArgb(i);
However, this won't achieve the wrap-around color effect that you describe in your question, and in fact much of the variation in your int32 values (assuming you range from the MinValue to the MaxValue) will apply to the alpha channel, or the opacity, which doesn't sound like what you want.
Update: here's something that should do what you need:
private const double ONE_SIXTH =
0.16666666666666666666666666666667;
private const double ONE_THIRD =
0.33333333333333333333333333333333;
private const double TWO_THIRDS =
0.66666666666666666666666666666667;
private const double FIVE_SIXTHS =
0.83333333333333333333333333333333;
public Color WheelColor(double d)
{
if ((d < 0.0) || (d > 1.0))
{
throw new ArgumentOutOfRangeException("d",
d, "d must be between 0.0 and 1.0, inclusive");
}
double R = 1;
double G = 1;
double B = 1;
if (d < ONE_SIXTH)
{
G = d / ONE_SIXTH;
B = 0;
}
else if (d < ONE_THIRD)
{
R = 1 - ((d - ONE_SIXTH) / ONE_SIXTH);
B = 0;
}
else if (d < 0.5)
{
R = 0;
B = (d - ONE_THIRD) / ONE_SIXTH;
}
else if (d < TWO_THIRDS)
{
R = 0;
G = 1 - ((d - 0.5) / ONE_SIXTH);
}
else if (d < FIVE_SIXTHS)
{
R = (d - TWO_THIRDS) / ONE_SIXTH;
G = 0;
}
else
{
B = 1 - ((d - FIVE_SIXTHS) / ONE_SIXTH);
G = 0;
}
return Color.FromArgb((int)(R * 255),
(int)(G * 255), (int)(B * 255));
}
The d parameter in WheelColor is meant to go from 0.0 to 1.0, and will cycle through the color wheel (sort of), starting at red when d = 0.0 and coming back to red when d = 1.0.
How about using System.Drawing.Color.FromArgb() method ?