double ConvexHullProjectionConstraint::computeMargin(const Vector2& posIn2D)
    {
        bool isInside = true;

        // First check if the point is inside the convex hull or not
        iDynTree::VectorDynSize Ax(A.rows());

        toEigen(Ax) = toEigen(A)*toEigen(posIn2D);

        // If even one of the constraint is violated, then the point is outside the convex hull
        for (int i=0; i < Ax.size(); i++)
        {
            if (!(Ax(i) <= b(i)))
            {
                isInside = false;
                break;
            }
        }

        // Then, compute the distance between each segment of the convex hull and the point :
        // the minimum one is the distance of the point from the convex hull

        // We start from the last segment that do not follow the segment[i],segment[i+1] structure
        double distanceWithoutSign = distanceBetweenPointAndSegment(posIn2D,
                                                                    projectedConvexHull(projectedConvexHull.getNrOfVertices()-1),
                                                                    projectedConvexHull(0));
        // Find the minimum distance
        for (int i=0; i < projectedConvexHull.getNrOfVertices()-1; i++)
        {
            double candidateDistance = distanceBetweenPointAndSegment(posIn2D,
                                                                      projectedConvexHull(i),
                                                                      projectedConvexHull(i+1));

            if (candidateDistance < distanceWithoutSign)
            {
                distanceWithoutSign = candidateDistance;
            }
        }

        double margin;
        // If the point is inside the convex hull, we return the distance, otherwise the negated distance
        if (isInside)
        {
            margin = distanceWithoutSign;
        }
        else
        {
            margin = -distanceWithoutSign;
        }

        return margin;
    }
Exemple #2
0
int save_pgm(Drawing D, int pix_per_unit, int sample_type, int sample_size, FILE *outfile) {
	List *layer;
	LineSegment *ls;
	Circle *cr;
	double x1 = 0.0, x2 = 0.0, y1 = 0.0, y2 = 0.0, x_ij = 0.0, y_ij = 0.0;
	double dist, val;
	int H, W, i, imax, j, jmax, k, l, n;
	int **matrix, *content;

	if (D->firstLayer == NULL) {
		return EMPTY_IMAGE_ERROR;
	}
	
	layer = D->firstLayer;
	while(layer != NULL) {
		ls = layer->lineSegment;
		cr = layer->circle;

		if (ls != NULL) {
			// Normalize units
			ls->x1			*= pix_per_unit;
			ls->y1			*= pix_per_unit;
			ls->x2			*= pix_per_unit;
			ls->y2			*= pix_per_unit;
			ls->thickness	*= pix_per_unit;

			if ((min(ls->x1, ls->x2) - ls->thickness) < x1)
				x1 = min(ls->x1, ls->x2) - ls->thickness;

			if ((min(ls->y1, ls->y2) - ls->thickness) < y1)
				y1 = min(ls->y1, ls->y2) - ls->thickness;

			if ((max(ls->x1, ls->x2) + ls->thickness) > x2)
				x2 = max(ls->x1, ls->x2) + ls->thickness;

			if ((max(ls->y1, ls->y2) + ls->thickness) > y2)
				y2 = max(ls->y1, ls->y2) + ls->thickness;
		

		} else {
			// Normalize units
			cr->x			*= pix_per_unit;
			cr->y			*= pix_per_unit;
			cr->radius 		*= pix_per_unit;
			cr->thickness 	*= pix_per_unit;

			if (cr->x - cr->radius - cr->thickness < x1)
				x1 = cr->x - cr->radius - cr->thickness;

			if (cr->y - cr->radius - cr->thickness < y1)
				y1 = cr->y - cr->radius - cr->thickness;

			if (cr->x + cr->radius + cr->thickness > x2)
				x2 = cr->x + cr->radius + cr->thickness;

			if (cr->y + cr->radius + cr->thickness > y2)
				y2 = cr->y + cr->radius + cr->thickness;
		

		}

		layer = layer->next;
	}

	W = ceil(x2 - x1);
	H = ceil(y2 - y1);

	matrix = malloc(H * sizeof(int *));
	if (!matrix) {
		printf("Erro ao alocar matriz enquanto tentava salvar o PGM.\n");
		return MEMORY_ERROR;
	}

	content = malloc(H * W * sizeof(int));
	if (!content) {
		printf("Erro ao alocar vetor de conteúdo para a matriz enquanto tentava salvar o PGM.\n");
		return MEMORY_ERROR;
	}

	for (int i = 0; i < H; i++) {
		matrix[i] = &(content[i * W]);

		for (int j = 0; j < W; j++) {
			matrix[i][j] = 255;
		}
	}

	layer = D->firstLayer;
	while(layer != NULL) {
		ls = layer->lineSegment;
		cr = layer->circle;

		if (ls != NULL) {
			ls->x1 -= x1;
			ls->y1 -= y1;
			ls->x2 -= x1;
			ls->y2 -= y1;

			i 		= floor(min(ls->x1, ls->x2) - ls->thickness);
			imax	= floor(max(ls->x1, ls->x2) + ls->thickness);
			jmax	= floor(max(ls->y1, ls->y2) + ls->thickness);

			
			for (; i < imax; i++) {
				for (j = floor(min(ls->y1, ls->y2) - ls->thickness); j < jmax; j++) {
					n = 0;
					
					if (sample_type == GRID_SAMPLE) {
						for (k = 1; k <= sample_size; k++) {
							y_ij = j + 1.0 * k / (sample_size + 1.0);

							for (l = 1; l <= sample_size; l++) {
								x_ij = i + 1.0 * l / (sample_size + 1.0);
								
								dist = distanceBetweenPointAndSegment(x_ij, y_ij, ls->x1, ls->y1, ls->x2, ls->y2);
								printf("Distancia: %lf <= %lf\n", dist, ls->thickness);

								if (dist <= ls->thickness)
									n++;
							}
						}

					} else {
						for (k = 0; k < sample_size; k++) {
							y_ij = j + (double)rand() / (double)((unsigned)RAND_MAX + 1);
							x_ij = i + (double)rand() / (double)((unsigned)RAND_MAX + 1);

							dist = distanceBetweenPointAndSegment(x_ij, y_ij, ls->x1, ls->y1, ls->x2, ls->y2);

							if (dist <= ls->thickness)
								n++;
						}
					}

					/* 	NOTE QUE O MODO BORRACHA FOI INSERIDO POR CONTA PRÓPRIA DOS ALUNOS,
						CONFORME AUTORIZADO PELO PROFESSOR NO ENUNCIADO DO EXERCICIO-PROGRAMA */

					if (ls->eraseMode) {
						if (sample_type == GRID_SAMPLE)
							val = (1.0 * n) / (sample_size * sample_size);
						else
							val = (1.0 * n) / (sample_size);

						matrix[j][i] = floor(max(1.0 * matrix[j][i], 255.0 * val));

					} else {
						if (sample_type == GRID_SAMPLE)
							val = 1.0 - (1.0 * n) / (sample_size * sample_size);
						else
							val = 1.0 - (1.0 * n) / (sample_size);

						matrix[j][i] = floor(min(1.0 * matrix[j][i], 255.0 * val));

					}
					
				}
			}

		} else {
			cr->x -= x1;
			cr->y -= y1;

			i 		= floor(cr->x - cr->thickness - cr->radius);
			imax	= floor(cr->x + cr->thickness + cr->radius);
			jmax	= floor(cr->y + cr->thickness + cr->radius);

			
			for (; i < imax; i++) {
				for (j = floor(cr->y - cr->thickness - cr->radius); j < jmax; j++) {
					n = 0;
					
					if (sample_type == GRID_SAMPLE) {
						for (k = 1; k <= sample_size; k++) {
							y_ij = j + 1.0 * k / (sample_size + 1.0);

							for (l = 1; l <= sample_size; l++) {
								x_ij = i + 1.0 * l / (sample_size + 1.0);
								dist = distance(x_ij, y_ij, cr->x, cr->y);

								if ((cr->filled && dist <= (cr->radius + cr->thickness)) ||
									(!cr->filled && dist >= (cr->radius - cr->thickness) && dist <= (cr->radius + cr->thickness)))
										n++;
							}
						}

					} else {
						for (k = 1; k <= sample_size; k++) {
							y_ij = j + (double)rand() / (double)((unsigned)RAND_MAX + 1);
							x_ij = i + (double)rand() / (double)((unsigned)RAND_MAX + 1);
							dist = distance(x_ij, y_ij, cr->x, cr->y);

							if ((cr->filled && dist <= (cr->radius + cr->thickness)) ||
								(!cr->filled && dist >= (cr->radius - cr->thickness) && dist <= (cr->radius + cr->thickness)))
									n++;
						}
					}

					if (sample_type == GRID_SAMPLE)
						val = 1.0 - (1.0 * n) / (1.0 * sample_size * sample_size);
					else
						val = 1.0 - (1.0 * n) / (1.0 * sample_size);

					matrix[j][i] = floor(min(1.0 * matrix[j][i], 255.0 * val));
				}
			}

		}

		layer = layer->next;
	}

/*
	/* REDEFINIR OS LIMITES DA IMAGEM É NECESSÁRIO DEVIDO A OPERAÇÃO DE BORRACHA/
	for (y1 = 0; y1 < H; y1++) {
		for (j = 0; j < W; j++)
			if (matrix[(int)y1][j] != 255) break;

		if (j < W && matrix[(int)y1][j] != 255) break;
	}

	for (y2 = H - 1; y2 >= 0; y2--) {
		for (j = 0; j < W; j++)
			if (matrix[(int)y2][j] != 255) break;

		if (j < W && matrix[(int)y2][j] != 255) break;
	}

	for (x1 = 0; x1 < W; x1++) {
		for (j = 0; j < H; j++)
			if (matrix[j][(int)x1] != 255) break;

		if (j < H && matrix[j][(int)x1] != 255) break;
	}

	for (x2 = W - 1; x2 >= 0; x2--) {
		for (j = 0; j < H; j++)
			if (matrix[j][(int)x2] != 255) break;

		if (j < H && matrix[j][(int)x2] != 255) break;
	}
*/



	fprintf(outfile, "P2\n");
	fprintf(outfile, "%d %d\n", W, H);
	fprintf(outfile, "255\n");

	for(i = 0; i < H; i++) {
		for (j = 0; j < W; j++) {
			fprintf(outfile, "%d ", matrix[i][j]);
		}
		fprintf(outfile, "\n");
	}

	return 0;
}