Find three largest contour(achieve two now) - c

friends, I am coding using opencv. I want to find three largest contour in picture/video, I have write code that can find two largest contour, I have difficulty in finding third largest, so I need your suggestions,Merry Christmas!
Here is my core code, how to change.
CvSeq *cont = 0
cvFindContours( tempImg, storage, &cont, sizeof(CvContour),
CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, cvPoint(0,0) );
CvSeq *contmax = 0;
CvSeq *contmax2 = contmax;
for(;cont;cont = cont->h_next) //get the two max area, and mark
{
area = fabs(cvContourArea( cont, CV_WHOLE_SEQ ));
printf("area == %lf\n", area);
if(area > maxArea)
{
contmax2 = contmax;
max2Area = maxArea;
contmax = cont;
maxArea = area;
}
else if(area > max2Area && area < maxArea)
{
contmax2 = cont;
max2Area = area;
}
}
CvRect aRect = cvBoundingRect( contmax, 0 );
CvRect bRect = cvBoundingRect( contmax2, 0 );

What about this?:
#define N 3
double maxArea[N] = {0};
CvSeq *countours[N], *tmp_cont;
double tmp_area;
for(;cont;cont = cont->h_next)
{
area = fabs(cvContourArea(cont, CV_WHOLE_SEQ));
printf("area == %lf\n", area);
for(int i = N-1; i >= 0; --i)
{
if(area > maxArea[i])
{
maxArea[i] = area;
countours[i] = cont;
for(int j = (i-1); j >= 0; --j)
{
if(maxArea[j] < maxArea[j+1])
{
tmp_area = maxArea[j+1];
tmp_cont = contours[j+1];
maxArea[j+1] = maxArea[j];
contours[j+1] = contours[j];
maxArea[j] = tmp_area;
contours[j] = tmp_cont;
}
}
break;
}
}
}

Related

My code cant blur a whole image but it can blur a single pixel in any part of the image

I've been doing the cs50x course but I'm stuck in the problem set 4, more precisely in the blur function, where I got to create a function that blurs a .bmp image. To blur it I need to do the average of each pixel that surrounds the pixel I'm blurring (him included).
My code works fine in the edge, corner, and middle pixels, but it doesn't work right for a whole 3x3 or 4x4 picture I've been trying everything but nothing seems to fix it.
This is what I got when I run check50: https://submit.cs50.io/check50/011dfd20a431c4e972f8789c677ed60438c5b133
void blur(int height, int width, RGBTRIPLE image[height][width])
{
//temporary variable to store the colour values
RGBTRIPLE copy[height][width];
//loop through each pixel and get the average value for each colour
for (int i=0;i<height;i++)
{
for (int j=0;j<width;j++)
{
float sumRed = 0, sumBlue = 0, sumGreen = 0;
int averageRed = 0, averageBlue = 0, averageGreen = 0, pixels=0, begginingheight =
i-1, endheight = i+1, begginingwidth = j-1, endwidth = j+1;
//height to take the average of the blur in each pixel
if (begginingheight < 0)
{
begginingheight = 0;
endheight = 1;
}
else if(begginingheight == height-1)
{
begginingheight = height-2;
endheight = height-1;
}
else
{
begginingheight = i-1;
endheight = i+1;
}
//width to take the average of the blur in each pixel
if(begginingwidth < 0)
{
begginingwidth = 0;
endwidth = 1;
}
else if(begginingwidth == width-1)
{
begginingwidth = width-2;
endwidth =width-1;
}
else
{
begginingwidth = j-1;
endwidth = j+1;
}
//get the sum of the box that he forms
for (int k = begginingheight; k <= endheight; k++)
{
for (int z = begginingwidth; z <= endwidth; z++)
{
sumRed += image[k][z].rgbtRed;
sumBlue += image[k][z].rgbtBlue;
sumGreen += image[k][z].rgbtGreen;
pixels+=1;
}
}
//calculate their average
averageRed = round(sumRed/pixels);
averageBlue = round(sumBlue/pixels);
averageGreen = round(sumGreen/pixels);
//use the copy to store the colour value
copy[i][j].rgbtRed = averageRed;
copy[i][j].rgbtBlue = averageBlue;
copy[i][j].rgbtGreen = averageGreen;
}
}
for (int i=0;i<height;i++)
{
for(int j=0;j<width;j++)
{
//copy the 2d copy into the true image
image[i][j].rgbtRed = copy[i][j].rgbtRed;
image[i][j].rgbtBlue = copy[i][j].rgbtBlue;
image[i][j].rgbtGreen = copy[i][j].rgbtGreen;
}
}
return;
}

problem met when checking collision between circle and polygon using SAT

I try to use SAT to check collision between circle and polygon, it works well when the circle is near the edges (of polygon), however when circle is closet to the corners (of polygon), it is push inside, and outside after that.
under this it failed
but under such cases it works well
How to solve this?
the algorithm looks like this:
double mtv = DBL_MAX; // minimum translation vector
Vector2 minAxis;
foreach(Edge e in p.Edges)
{
var axis = e.normal;
var circleInterval = ProjectInterval(c, axis);
var polygonInterval = ProjectInterval(p, axis);
float overlap = OverlapIntervals(circleInterval, polygonInterval);
if(overlap < 0)
{
//the intervals overlap if it returns a positive number
return -1.0f;
}
if(overlap < mtv)
{
mtv = overlap;
minAxis = e.normal;
}
}
and my code is here:
static AS_UNUSED inline AS_Bool AS_SAT_test_polygon_circle(AS_Polygon *poly, AS_Circle *circle, AS_Result *result) {
AS_Vector *axis_normed = AS_vector_create(0, 0);
if (result) {
result->is_overlapping = AS_TRUE;
result->shape_a = poly;
result->shape_b = circle;
result->type_a = AS_POLYGON;
result->type_b = AS_CIRCLE;
}
for (int i = 0; i < array_len(poly->coords); i++) {
AS_Vector *coord1 =poly->coords[i];
AS_Vector *coord2 = poly->coords[i + 1 >= array_len(poly->coords) ? 0 : i + 1];
axis_normed->x = coord1->x - coord2->x;
axis_normed->y = coord1->y - coord2->y;
AS_vector_perp(axis_normed);
AS_vector_norm(axis_normed);
double min1 = DBL_MAX, max1 = -DBL_MAX;
double dot_product;
for (int j = 0; j < array_len(poly->coords); j++) {
dot_product = AS_vector_dot(poly->coords[j], axis_normed);
if (dot_product > max1) max1 = dot_product;
if (dot_product < min1) min1 = dot_product;
}
double b = AS_vector_dot(circle->position, axis_normed);
double a = b - circle->radius, c = b + circle->radius;
double min2, max2;
min2 = a < b ? a : b;
min2 = min2 < c ? min2 : c;
max2 = a > b ? a : b;
max2 = max2 > c ? max2 : c;
if (result) {
double overlap;
if (min1 < min2) {
result->a_in_b = AS_FALSE;
if (max1 < min2) {
result->is_overlapping = AS_FALSE;
return AS_FALSE;
} else if (max1 < max2) {
overlap = max1 - min2;
} else {
double option1 = max1 - min2;
double option2 = max2 - min1;
overlap = option1 < option2 ? option1 : option2;
}
} else {
result->b_in_a = AS_FALSE;
if (max2 < min1) {
result->is_overlapping = AS_FALSE;
return AS_FALSE;
} else if (max2 < max1) {
overlap = max2 - min1;
} else {
double option1 = max2 - min1;
double option2 = max1 - min2;
overlap = option1 < option2 ? option1 : option2;
}
}
if (overlap < result->overlap) {
result->overlap = overlap;
result->overlap_x = axis_normed->x;
result->overlap_y = axis_normed->y;
}
} else {
if (min1 > max2 || min2 > max1) {
return AS_FALSE;
}
}
}
return AS_TRUE;
}
Simply add add a check about closest point of the polygon, that will be okay.

cell overlap removal in vlsi placement

Below code is to remove overlap among cells residing inside grids.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#define TRUE 1
#define FALSE 0
//coordinate representation
struct Point
{
double x;
double y;
};
//block representation with 4 coordinates
struct Block
{
unsigned int id;
struct Point bottomLeft, topLeft, bottomRight, topRight;
double width, height;
double whitespace;
};
struct Overlap
{
double overlapLength;
struct Block *b1, *b2;
} OL[1000];
struct Block *b;
struct Block ROW1, ROW2, ROW3;
int comparator(const void *p, const void *q)
{
return (((struct Overlap *)p)->overlapLength -
(((struct Overlap *)q)->overlapLength));
}
//intialise Blocks using bottom left x,y coordinate
void intialiseBlock(struct Block *B)
{
B->topLeft.x = B->bottomLeft.x;
B->topLeft.y = B->height + B->bottomLeft.y;
B->bottomRight.x = B->width + B->bottomLeft.x;
B->bottomRight.y = B->bottomLeft.y;
B->topRight.x = B->width + B->bottomLeft.x;
B->topRight.y = B->height + B->bottomLeft.y;
}
//update coordinate
void move(double xDelta, double yDelta, struct Point *p)
{
// Parameter values are increments to the current coordinates
p->x += xDelta;
p->y += yDelta;
}
//calculate and return distance between 2 points
double distance(const struct Point aPoint, const struct Point bPoint)
{
return sqrt((aPoint.x - bPoint.x) * (aPoint.x - bPoint.x) +
(aPoint.y - bPoint.y) * (aPoint.y - bPoint.y));
}
//generate width of cell using number of cells
double computeCellWidth(int ncell)
{
double width = (0.8 * 400) / ncell;
return width;
}
//create a
unsigned int rand_interval(unsigned int min, unsigned int max)
{
int r;
const unsigned int range = 1 + max - min;
const unsigned int buckets = RAND_MAX / range;
const unsigned int limit = buckets * range;
/* Create equal size buckets all in a row, then fire randomly towards
* the buckets until you land in one of them. All buckets are equally
* likely. If you land off the end of the line of buckets, try again. */
do
{
r = rand();
} while (r >= limit);
return min + (r / buckets);
}
//place blocks in appropriate rows
void placeVertical(struct Block *b, int n, struct Block ROW1, struct Block ROW2,
struct Block ROW3)
{
for (int i = 0; i < n; i++)
{
double distanceFromBottom = 0.0;
double distanceFromTop = 0.0;
// check if Inside Row1 and Row2
if ((b[i].bottomLeft.y < ROW1.topLeft.y) && (b[i].topLeft.y > ROW1.topLeft.y))
{
//printf("ROW1 and ROW2 Executed\n");
distanceFromBottom = ROW1.topLeft.y - b[i].bottomLeft.y;
distanceFromTop = b[i].height - distanceFromBottom;
if (distanceFromBottom > distanceFromTop)
{
move(0, -distanceFromTop, &b[i].bottomLeft);
move(0, -distanceFromTop, &b[i].topLeft);
move(0, -distanceFromTop, &b[i].bottomRight);
move(0, -distanceFromTop, &b[i].topRight);
}
else
{
move(0, distanceFromBottom, &b[i].bottomLeft);
move(0, distanceFromBottom, &b[i].topLeft);
move(0, distanceFromBottom, &b[i].bottomRight);
move(0, distanceFromBottom, &b[i].topRight);
}
}
// check if Inside Row2 and Row3
else if ((b[i].bottomLeft.y < ROW2.topLeft.y) && (b[i].topLeft.y > ROW2.topLeft.y))
{
//System.out.println("ROW2 and ROW3 Executed");
distanceFromBottom = ROW2.topLeft.y - b[i].bottomLeft.y;
distanceFromTop = b[i].height - distanceFromBottom;
if (distanceFromBottom > distanceFromTop)
{
move(0, -distanceFromTop, &b[i].bottomLeft);
move(0, -distanceFromTop, &b[i].topLeft);
move(0, -distanceFromTop, &b[i].bottomRight);
move(0, -distanceFromTop, &b[i].topRight);
}
else
{
move(0, distanceFromBottom, &b[i].bottomLeft);
move(0, distanceFromBottom, &b[i].topLeft);
move(0, distanceFromBottom, &b[i].bottomRight);
move(0, distanceFromBottom, &b[i].topRight);
}
}
else if ((b[i].bottomLeft.y >= ROW1.bottomLeft.y) && (b[i].topLeft.y <= ROW1.topLeft.y))
{
// do nothing in ROW1
}
else if ((b[i].bottomLeft.y >= ROW2.bottomLeft.y) && (b[i].topLeft.y <= ROW2.topLeft.y))
{
// do nothing in ROW2
}
else // ((b[i].bottomLeft.y >=
// ROW2.bottomLeft.y)&&(b[i].topLeft.y <=
// ROW2.topLeft.y))
{
// do nothing in ROW3
}
}
}
//use when floating point operations create run time problems
void linkfloat()
{
float a = 0.0, *x;
x = &a;
a = *x;
}
int findOverlaps(struct Block *b, int n)
{
int k, j, p = 0;
//struct Overlap OL[200];
//short flag = FALSE;
double overlapLength = 0.0;
for (int i = 0; i < n - 1; i++)
{
k = i;
for (j = i + 1; j < n; j++)
{
if (k == j)
continue;
overlapLength = 0.0;
//for ROW1
if (b[k].bottomLeft.y >= 0 && b[k].topLeft.y <= 100 && b[j].bottomLeft.y >= 0 && b[j].topLeft.y <= 100)
{
//if ((b[k].bottomRight.x > b[j].bottomLeft.x) && (b[k].bottomRight.y < b[j].topLeft.y || b[k].topRight.y > b[j].bottomLeft.y))
if ((b[k].bottomLeft.y == b[j].bottomLeft.y) && (b[k].bottomRight.x > b[j].bottomLeft.x))
{
overlapLength = b[k].bottomRight.x - b[j].bottomLeft.x;
OL[p].overlapLength = overlapLength;
OL[p].b1 = &b[k];
OL[p].b2 = &b[j];
p++;
}
else if (((b[k].topLeft.y > b[j].bottomLeft.y) && (b[k].topRight.x > b[j].bottomLeft.x)) || ((b[k].bottomLeft.y < b[j].topLeft.y) && (b[k].bottomRight.x > b[j].topLeft.x)))
{
//flag = TRUE;
overlapLength = b[k].bottomRight.x - b[j].bottomLeft.x;
OL[p].overlapLength = overlapLength;
OL[p].b1 = &b[k];
OL[p].b2 = &b[j];
p++;
}
else
{
}
overlapLength = 0.0;
}
//For Row2
else if (b[k].bottomLeft.y >= 100 && b[k].topLeft.y <= 200 && b[j].bottomLeft.y >= 100 && b[j].topLeft.y <= 200)
{
if ((b[k].bottomLeft.y == b[j].bottomLeft.y) && (b[k].bottomRight.x > b[j].bottomLeft.x))
{
overlapLength = b[k].bottomRight.x - b[j].bottomLeft.x;
OL[p].overlapLength = overlapLength;
OL[p].b1 = &b[k];
OL[p].b2 = &b[j];
p++;
}
else if (((b[k].topLeft.y > b[j].bottomLeft.y) && (b[k].topRight.x > b[j].bottomLeft.x)) || ((b[k].bottomLeft.y < b[j].topLeft.y) && (b[k].bottomRight.x > b[j].topLeft.x)))
{
//flag = TRUE;
overlapLength = b[k].bottomRight.x - b[j].bottomLeft.x;
OL[p].overlapLength = overlapLength;
OL[p].b1 = &b[k];
OL[p].b2 = &b[j];
p++;
}
else
{
}
overlapLength = 0.0;
}
//For Row3
else if (b[k].bottomLeft.y >= 200 && b[k].topLeft.y <= 300 && b[j].bottomLeft.y >= 200 && b[j].topLeft.y <= 300)
{
if ((b[k].bottomLeft.y == b[j].bottomLeft.y) && (b[k].bottomRight.x > b[j].bottomLeft.x))
{
overlapLength = b[k].bottomRight.x - b[j].bottomLeft.x;
OL[p].overlapLength = overlapLength;
OL[p].b1 = &b[k];
OL[p].b2 = &b[j];
p++;
}
else if (((b[k].topLeft.y > b[j].bottomLeft.y) && (b[k].topRight.x > b[j].bottomLeft.x)) || ((b[k].bottomLeft.y < b[j].topLeft.y) && (b[k].bottomRight.x > b[j].topLeft.x)))
{
//flag = TRUE;
overlapLength = b[k].bottomRight.x - b[j].bottomLeft.x;
OL[p].overlapLength = overlapLength;
OL[p].b1 = &b[k];
OL[p].b2 = &b[j];
p++;
}
else
{
}
overlapLength = 0.0;
}
else
{
//do nothing
}
}
}
return p;
}
struct Block *
getBlock(struct Block *b, int n, int id)
{
int i;
for (i = 0; i < n; i++)
{
if (id == b[i].id)
return (b + i);
}
return NULL;
}
void placeHorizontalGreedy(struct Block *b, int n)
{
struct Block *t = NULL;
int p = 0, k = 0;
p = findOverlaps(b, n);
qsort(OL, p, sizeof(struct Overlap), comparator);
while (TRUE)
{
t = getBlock(b, 12, OL[k].b2->id);
if (t != NULL)
{
//t->bottomLeft.x = t->bottomLeft.x+OL[0].overlapLength;
if ((t->bottomLeft.x + OL[0].overlapLength + t->width) <= ROW1.bottomRight.x)
{
move(OL[0].overlapLength, 0, &t->bottomLeft);
intialiseBlock(t);
}
}
p = findOverlaps(b, n);
if (p == 0)
break;
else
qsort(OL, p, sizeof(struct Overlap), comparator);
}
}
void placeHorizontalNonGreedy(struct Block *b, int n, struct Block ROW1,
struct Block ROW2, struct Block ROW3)
{
int k, j, p = 0;
double overlapLength = 0.0;
for (int i = 0; i < n - 1; i++)
{
k = i;
for (j = i + 1; j < n; j++)
{
if (k == j)
continue;
overlapLength = 0.0;
//check if in Row1
if (b[k].bottomLeft.y >= ROW1.bottomLeft.y && b[k].topLeft.y <= ROW1.topLeft.y && b[j].bottomLeft.y >= ROW1.bottomLeft.y && b[j].topLeft.y <= ROW1.topLeft.y)
{
if ((b[k].bottomRight.x > b[j].bottomLeft.x) && (b[k].bottomRight.y < b[j].topLeft.y || b[k].topRight.y > b[j].bottomLeft.y))
{
//flag = TRUE;
overlapLength = b[k].bottomRight.x - b[j].bottomLeft.x;
if (overlapLength != 0)
{
if (b[j].bottomLeft.x + overlapLength + b[j].width <=
ROW1.bottomRight.x)
{
b[j].bottomLeft.x += overlapLength;
intialiseBlock(&b[j]);
}
else
{
b[j].bottomLeft.x =
b[j].bottomLeft.x + (ROW1.bottomRight.x -
b[j].bottomRight.x);
}
}
}
}
//check if in Row2
else if (b[k].bottomLeft.y >= ROW2.bottomLeft.y && b[k].topLeft.y <= ROW2.topLeft.y && b[j].bottomLeft.y >= ROW2.bottomLeft.y && b[j].topLeft.y <= ROW2.topLeft.y)
{
if ((b[k].bottomRight.x > b[j].bottomLeft.x) && (b[k].bottomRight.y < b[j].topLeft.y || b[k].topRight.y > b[j].bottomLeft.y))
{
//flag = TRUE;
overlapLength = b[k].bottomRight.x - b[j].bottomLeft.x;
if (overlapLength != 0)
{
if (b[j].bottomLeft.x + overlapLength + b[j].width <=
400)
{
b[j].bottomLeft.x += overlapLength;
intialiseBlock(&b[j]);
}
}
}
}
//check if in Row3
else if (b[k].bottomLeft.y >= ROW3.bottomLeft.y && b[k].topLeft.y <= ROW3.topLeft.y && b[j].bottomLeft.y >= ROW3.bottomLeft.y && b[j].topLeft.y <= ROW3.topLeft.y)
{
if ((b[k].bottomRight.x > b[j].bottomLeft.x) && (b[k].bottomRight.y < b[j].topLeft.y || b[k].topRight.y > b[j].bottomLeft.y))
{
//flag = TRUE;
overlapLength = b[k].bottomRight.x - b[j].bottomLeft.x;
if (overlapLength != 0)
{
if (b[j].bottomLeft.x + overlapLength + b[j].width <=
400)
{
b[j].bottomLeft.x += overlapLength;
intialiseBlock(&b[j]);
}
}
}
}
else
{
//printf("Invalid input\n");
continue;
}
}
}
}
int main()
{
//struct Block b[16];
//struct Block b[4];
//struct Block *b;
//struct Block ROW1, ROW2, ROW3;
//FILE *fp = fopen("/home/jeetu/experimentprograms/recordcoord.txt", "w+");
//FILE *fp = fopen("/home/jeetu/experimentprograms/blockcoordinates.txt", "r");
int ncell = 0, width = 0, i = 0, totalncells = 0, id = 0;
double distanceFromBottom = 0.0;
double distanceFromTop = 0.0;
int x = 0, y = 0, temp = 0, d = 0;
printf("Enter number of cells: ");
scanf("%d", &ncell);
width = computeCellWidth(ncell);
//width = 40;
b = (struct Block *)malloc(3 * ncell * sizeof(struct Block));
//b = (struct Block *)malloc(12 * sizeof(struct Block));
srand(time(0));
ROW1.bottomLeft.x = 0;
ROW1.bottomLeft.y = 0;
ROW1.height = 100;
ROW1.width = 400;
ROW1.whitespace = 40000;
intialiseBlock(&ROW1);
ROW2.bottomLeft.x = 0;
ROW2.bottomLeft.y = 100;
ROW2.height = 100;
ROW2.width = 400;
ROW2.whitespace = 40000;
intialiseBlock(&ROW2);
ROW3.bottomLeft.x = 0;
ROW3.bottomLeft.y = 200;
ROW3.height = 100;
ROW3.width = 400;
ROW3.whitespace = 40000;
intialiseBlock(&ROW3);
for (i = 0; i < ncell; i++)
{
if (i == 0)
{
// x = rand_interval(0, width / 2);
x = rand() % (width / 2);
//y = rand_interval(0, 70);
y = rand() % 70;
temp = x;
}
//m = rand();
else
{
x = rand_interval((temp + (int)width / 2), temp + width);
//x = (rand()%((temp+width)-(temp+width/2)))+(temp+width/2);
//y = rand_interval(0, 70);
y = rand() % 70;
temp = x;
}
b[totalncells].bottomLeft.x = x;
b[totalncells].bottomLeft.y = y;
b[totalncells].width = width;
b[totalncells].height = 50;
b[totalncells].id = id;
//initial white space calculation for ROW1
if (b[totalncells].bottomLeft.y >= ROW1.bottomLeft.y && b[totalncells].topLeft.y <= ROW1.topLeft.y)
{
ROW1.whitespace =
ROW1.whitespace - b[totalncells].width * b[totalncells].height;
}
id++;
intialiseBlock(&b[totalncells]);
totalncells++;
//printf("x=%d\ty=%d\n", x, y);
}
temp = 0;
//Generate random coordinates For Row2
for (i = 0; i < ncell; i++)
{
//int x = 0, y = 0, m = 0, d = 0;
if (i == 0)
{
/*x = rand_interval(0, width / 2);
y = rand_interval(100, 170); */
//x = rand() % (width / 2);
x = rand() % (width / 2);
y = (rand() % (170 - 100)) + 100;
temp = x;
}
//m = rand();
else
{
/*x = rand_interval((temp + (int)width / 2), 400 - (int)width);
y = rand_interval(100, 170); */
//x = (rand()%((temp+width)-(temp+width/2)))+(temp+width/2);
x = rand_interval((temp + (int)width / 2), temp + width);
y = (rand() % (170 - 100)) + 100;
temp = x;
}
b[totalncells].bottomLeft.x = x;
b[totalncells].bottomLeft.y = y;
b[totalncells].width = width;
b[totalncells].height = 50;
b[totalncells].id = id;
//initial white space calculation for ROW2
if (b[totalncells].bottomLeft.y >= ROW2.bottomLeft.y && b[totalncells].topLeft.y <= ROW2.topLeft.y)
{
ROW2.whitespace =
ROW2.whitespace - b[totalncells].width * b[totalncells].height;
}
id++;
intialiseBlock(&b[totalncells]);
totalncells++;
//printf("x=%d\ty=%d\n", x, y);
}
temp = 0;
//Generate random coordinates For Row3
for (i = 0; i < ncell; i++)
{
//int x = rand_interval(0, 100 - (int)width);
//int y = rand_interval(20, 25); //cell height is 5 so max will reach 30
//int x = 0, y = 0, m = 0, d = 0;
if (i == 0)
{
/*x = rand_interval(0, width / 2);
y = rand_interval(200, 250); */
x = rand() % (width / 2);
y = (rand() % (250 - 200)) + 200;
temp = x;
}
//m = rand();
else
{
/*x = rand_interval((temp + (int)width / 2), 400 - (int)width);
y = rand_interval(200, 250); */
x = rand_interval((temp + (int)width / 2), temp + width);
//x = (rand()%((temp+width)-(temp+width/2)))+(temp+width/2);
y = (rand() % (250 - 200)) + 200;
temp = x;
}
b[totalncells].bottomLeft.x = x;
b[totalncells].bottomLeft.y = y;
b[totalncells].width = width;
b[totalncells].height = 50;
b[totalncells].id = id;
//initial white space calculation for ROW3
if (b[totalncells].bottomLeft.y >= ROW3.bottomLeft.y && b[totalncells].topLeft.y <= ROW3.topLeft.y)
{
ROW3.whitespace =
ROW3.whitespace - b[totalncells].width * b[totalncells].height;
}
id++;
intialiseBlock(&b[totalncells]);
totalncells++;
//printf("x=%d\ty=%d\n", x, y);
}
for (i = 0; i < totalncells; i++)
{
//printf("%f %f %f %f\n", b[i].bottomLeft.x, b[i].bottomLeft.y, b[i].width, b[i].height);
printf("%d\t%d\t%d\t%d\n", (int)b[i].bottomLeft.x,
(int)b[i].bottomLeft.y, (int)b[i].width, (int)b[i].height);
}
placeVertical(b, totalncells, ROW1, ROW2, ROW3);
//placeVerticalWithDensityConstraints(b,totalncells,ROW1,ROW2,ROW3);
printf("\nAfter vertical Updation\n");
for (i = 0; i < totalncells; i++)
{
printf("%d\t%d\t%d\t%d\n", (int)b[i].bottomLeft.x,
(int)b[i].bottomLeft.y, (int)b[i].width, (int)b[i].height);
}
/*placeHorizontalNonGreedy(b, 12, ROW1, ROW2, ROW3);
printf("\nAfter Horizontal Updation(Non greedy)\n");
for (i = 0; i < 12; i++)
{
printf("%d\t%d\t%d\t%d\n", (int)b[i].bottomLeft.x, (int)b[i].bottomLeft.y, (int)b[i].width, (int)b[i].height);
} */
placeHorizontalGreedy(b, totalncells);
printf("\nAfter Horizontal Updation(Greedy)\n");
for (i = 0; i < totalncells; i++)
{
printf("%d\t%d\t%d\t%d\n", (int)b[i].bottomLeft.x,
(int)b[i].bottomLeft.y, (int)b[i].width, (int)b[i].height);
}
return 0;
}
Explanation about the code
in this program I have defined three structures
one to represent a Point,one to represent rectangular block with 4 coordinates,one to represent overlap between pair of cells.
There is function(computeCellWidth) to dynamically compute width of cells according to a formula.
There are three rows ROW1,ROW2,ROW3 in which cells will reside.
This program will first ask for number of cells and this is numbers of cells per row.At first x,y coordinates for each cell is randomly generated.Then placeVertical() function will move cells to different rows which are spanning across two rows.Then there is a placeHorizontalGreedy() function which will remove overlap among cells by first finding overlaplength and then sorting them and removing the overlap between cells which has least overlap and this process will continue till either there will be no overlaps or overlap removal is not possible anymore.Here I would like to bring to the notice of everybody that cells will be moved towards the right of the grid to remove overlaps.In placeHorizontalGreedy() function I have used a variable p which will indicate number of overlaps after each iteration.for small number of cells testing for p to be zero works fine but not as I increase the numbers.Plus how can I make sure that overlaps exists but overlap removal is not possible anymore,so that I can stop the loop. Please help me out.

I am unable to display my corresponding region for the largest PSI value

I am unable to display my corresponding region among all regions for the highest PSI reading.
I have tried many other various methods, but I could not display my corresponding region (Central, East, North, South, West....) for that highest PSI value.
I have declared the PSI values in the arrays for each region.
int i, largest;
int Time[] = { 600,700,800,900,1000,1100,1200,1300,1400,1500,1600,1700,1800 };
int Central[] = { 89,88,87,143,139,79,144,85,83,90,89,88,76 };
int East[] = { 80,79,78,77,76,80,90,89,88,110,109,143,136 };
int North[] = { 147,144,141,139,137,132,109,110,109,80,77,132,108 };
int South[] = { 90,89,88,139,136,132,102,105,109,110,109,80,77 };
int West[] = { 141,137,153,147,143,83,90,89,141,138,134,130,127 };
largest = Central[0];
for (i = 1; i < 13; i++)
{
if (largest < Central[i])
largest = Central[i];
}
largest = Central;
for (i = 0; i < 13; i++)
{
if (largest < East[i])
largest = East[i];
}
for (i = 0; i < 13; i++)
{
if (largest < North[i])
largest = North[i];
}
for (i = 0; i < 13; i++)
{
if (largest < South[i])
largest = South[i];
}
for (i = 0; i < 13; i++)
{
if (largest < West[i])
largest = West[i];
}
printf(" Highest PSI value amongst all is %d\n\n\n", largest);
break;
I am able to display my largest PSI value, but I am not able to display the region for that highest PSI value.
For example, if my largest PSI in the arrays was 180 that is in Central, it will display PSI value is 180 and correspondent region is Central.
If my largest PSI in the arrays was 180 that is in West, it will display PSI value is 180 and correspondent region is West.
You assign an array to an int : largest = Central;
You need to create a variable containing the name of the region and update it each time the PSI is larger. All you have to do is print it at the end. Which give us :
#include <stdio.h>
int i, largest;
char *region = NULL;
int Time[] = { 600,700,800,900,1000,1100,1200,1300,1400,1500,1600,1700,1800 };
int Central[] = { 89,88,87,143,139,79,144,85,83,90,89,88,76 };
int East[] = { 80,79,78,77,76,80,90,89,88,110,109,143,136 };
int North[] = { 147,144,141,139,137,132,109,110,109,80,77,132,108 };
int South[] = { 90,89,88,139,136,132,102,105,109,110,109,80,77 };
int West[] = { 141,137,153,147,143,83,90,89,141,138,134,130,127 };
largest = Central[0];
for (i = 1; i < 13; i++) {
if (largest < Central[i]) {
largest = Central[i];
region = "Central";
}
}
for (i = 0; i < 13; i++) {
if (largest < East[i]) {
largest = East[i];
region = "East";
}
}
for (i = 0; i < 13; i++) {
if (largest < North[i]) {
largest = North[i];
region = "North";
}
}
for (i = 0; i < 13; i++) {
if (largest < South[i]) {
largest = South[i];
region = "South";
}
}
for (i = 0; i < 13; i++) {
if (largest < West[i]) {
largest = West[i];
region = "West";
}
}
printf(" Highest PSI value amongst all is %d in %s\n\n\n", largest, region);
This statement in your code snippet
largest = Central;
is redundant and does not make sense (it tries convert a pointer to int).
It seems what you mean is something like the following.
#include <stdio.h>
int main(void)
{
enum { N = 13 };
int Central[N] = { 89,88,87,143,139,79,144,85,83,90,89,88,76 };
int East[N] = { 80,79,78,77,76,80,90,89,88,110,109,143,136 };
int North[N] = { 147,144,141,139,137,132,109,110,109,80,77,132,108 };
int South[N] = { 90,89,88,139,136,132,102,105,109,110,109,80,77 };
int West[N] = { 141,137,153,147,143,83,90,89,141,138,134,130,127 };
const int *regions[] = { Central, East, North, South, West };
const char *region_name[] = { "Central", "East", "North", "South", "West" };
int largest_PSI = regions[0][0];
const char *target_region_name = region_name[0];
for ( size_t i = 0; i < sizeof( regions ) / sizeof( *regions ); i++ )
{
int region_largest_PSI = regions[i][0];
for ( size_t j = 1; j < N; j++ )
{
if ( region_largest_PSI < regions[i][j] )
{
region_largest_PSI = regions[i][j];
}
}
if ( largest_PSI < region_largest_PSI )
{
largest_PSI = region_largest_PSI;
target_region_name = region_name[i];
}
}
printf( "Highest PSI value amongst all is %d in region %s.\n\n\n", largest_PSI, target_region_name );
return 0;
}
The program output is
Highest PSI value amongst all is 153 in region West.
To simplify the code you could write a separate function that searches the maximum element. For example
#include <stdio.h>
int * max_element( const int a[], size_t N )
{
const int *max = a;
for ( size_t i = 1; i < N; i++ )
{
if ( *max < *( a + i ) ) max = a + i;
}
return ( int * )max;
}
int main(void)
{
enum { N = 13 };
int Central[N] = { 89,88,87,143,139,79,144,85,83,90,89,88,76 };
int East[N] = { 80,79,78,77,76,80,90,89,88,110,109,143,136 };
int North[N] = { 147,144,141,139,137,132,109,110,109,80,77,132,108 };
int South[N] = { 90,89,88,139,136,132,102,105,109,110,109,80,77 };
int West[N] = { 141,137,153,147,143,83,90,89,141,138,134,130,127 };
const int * regions[] = { Central, East, North, South, West };
const char *region_name[] = { "Central", "East", "North", "South", "West" };
int largest_PSI = regions[0][0];
const char *target_region_name = region_name[0];
for ( size_t i = 0; i < sizeof( regions ) / sizeof( *regions ); i++ )
{
int *region_largest_PSI = max_element( regions[i], N );
if ( largest_PSI < *region_largest_PSI )
{
largest_PSI = *region_largest_PSI;
target_region_name = region_name[i];
}
}
printf( "Highest PSI value amongst all is %d in region %s.\n\n\n", largest_PSI, target_region_name );
return 0;
}
To find largest region's name, create another variable to store which region has the largest value and assign it inside each if statement.
Also, I've combined your for loops to make your code clearer.
int i, largest;
char region[strlen("Central") + 1];
int Time[] = { 600,700,800,900,1000,1100,1200,1300,1400,1500,1600,1700,1800 };
int Central[] = { 89,88,87,143,139,79,144,85,83,90,89,88,76 };
int East[] = { 80,79,78,77,76,80,90,89,88,110,109,143,136 };
int North[] = { 147,144,141,139,137,132,109,110,109,80,77,132,108 };
int South[] = { 90,89,88,139,136,132,102,105,109,110,109,80,77 };
int West[] = { 141,137,153,147,143,83,90,89,141,138,134,130,127 };
largest = Central[0];
// Combine the for loops to make your code more clear
for (i = 0; i < 13; i++)
{
if (largest < Central[i]){
largest = Central[i];
region = "Central";
}
if (largest < East[i]){
largest = East[i];
region = "East";
}
if (largest < North[i]){
largest = North[i];
region = "North";
}
if (largest < South[i]){
largest = South[i];
region = "South";
}
if (largest < West[i]){
largest = West[i];
region = "West";
}
}
// Display results
printf("PSI value is %d and correspondent region is %s.", largest, region);

Box2d elastic rope joint

I'm writing a game, and I need to make up a rope. I maked it by b2RopeJoint, but there I have not found an opportunity to make it elastic.
Then I looked for b2DistanceJoint, everything is cool with the elasticity, but I can't find an ability to set a limit only to the maximum distance (without minimum one).
How can I do it?
Try this.
-(void) CreateElasticRope {
//=======Params
// Position and size
b2Vec2 lastPos = b2Vec2(4,4); //set position first body
float widthBody = 0.35;
float heightBody = 0.1;
// Body params
float density = 0.05;
float restitution = 0.5;
float friction = 0.5;
// Distance joint
float dampingRatio = 0.0;
float frequencyHz = 0;
// Rope joint
float kMaxWidth = 1.1;
// Bodies
int countBodyInChain = 15;
b2Body* prevBody;
//========Create bodies and joints
for (int k = 0; k < countBodyInChain; k++) {
b2BodyDef bodyDef;
if(k==0 ) bodyDef.type = b2_staticBody; //first body is static
else bodyDef.type = b2_dynamicBody;
bodyDef.position = lastPos;
lastPos += b2Vec2(2*widthBody, 0); //modify b2Vect for next body
bodyDef.fixedRotation = YES;
b2Body* body = world->CreateBody(&bodyDef);
b2PolygonShape distBodyBox;
distBodyBox.SetAsBox(widthBody, heightBody);
b2FixtureDef fixDef;
fixDef.density = density;
fixDef.restitution = restitution;
fixDef.friction = friction;
fixDef.shape = &distBodyBox;
body->CreateFixture(&fixDef);
body->SetHealth(9999999);
body->SetLinearDamping(0.0005f);
if(k>0) {
//Create distance joint
b2DistanceJointDef distJDef;
b2Vec2 anchor1 = prevBody->GetWorldCenter();
b2Vec2 anchor2 = body->GetWorldCenter();
distJDef.Initialize(prevBody, body, anchor1, anchor2);
distJDef.collideConnected = false;
distJDef.dampingRatio = dampingRatio;
distJDef.frequencyHz = frequencyHz;
world->CreateJoint(&distJDef);
//Create rope joint
b2RopeJointDef rDef;
rDef.maxLength = (body->GetPosition() - prevBody->GetPosition()).Length() * kMaxWidth;
rDef.localAnchorA = rDef.localAnchorB = b2Vec2_zero;
rDef.bodyA = prevBody;
rDef.bodyB = body;
world->CreateJoint(&rDef);
} //if k>0
prevBody = body;
} //for
}
There's a 2.2 style ropejoint implementation here: https://github.com/aaronfarr/box2Dweb
You can use both a rope joint and a distance joint together. Make the distance of the rope joint a bit longer than the distance joint.
From the Box2D testbed example, I modified the "Web" example as follows:
#ifndef ELASTICROPE_H
#define ELASTICROPE_H
#define NUM_JOINTS 7
#define NUM_LINKS 8
class ElasticRope : public Test
{
public:
ElasticRope()
{
b2Body* ground = NULL;
{
b2BodyDef bd;
ground = m_world->CreateBody(&bd);
b2EdgeShape shape;
shape.Set(b2Vec2(-40.0f, 0.0f), b2Vec2(40.0f, 0.0f));
ground->CreateFixture(&shape, 0.0f);
}
{
b2CircleShape shape;
shape.m_radius = 0.8f;
// create bodies
for (int b = 0; b < NUM_LINKS; b++) {
b2BodyDef bd;
bd.type = b2_dynamicBody;
bd.position.Set(5.0f, NUM_LINKS-b);
m_bodies[b] = m_world->CreateBody(&bd);
m_bodies[b]->CreateFixture(&shape, 5.0f);
}
for (int j = 0; j < NUM_JOINTS; j++) {
b2DistanceJointDef jd;
b2Vec2 p1, p2, d;
jd.frequencyHz = 5.0f;
jd.dampingRatio = 1.0f;
jd.bodyA = m_bodies[j];
jd.bodyB = m_bodies[j+1];
m_joints[j] = m_world->CreateJoint(&jd);
}
}
}
void Step(Settings* settings)
{
Test::Step(settings);
m_debugDraw.DrawString(5, m_textLine, "This demonstrates an elastic rope.");
m_textLine += DRAW_STRING_NEW_LINE;
}
void JointDestroyed(b2Joint* joint)
{
for (int32 i = 0; i < 8; ++i)
{
if (m_joints[i] == joint)
{
m_joints[i] = NULL;
break;
}
}
}
static Test* Create()
{
return new ElasticRope;
}
b2Body* m_bodies[NUM_LINKS];
b2Joint* m_joints[NUM_JOINTS];
};
#endif // ELASTICROPE_H
Its far from perfect, but may be a starting point.

Resources