Esempio n. 1
0
int main(int argc, char const *argv[])
{
	Poly *poly1, *poly2, *polySum;

	puts("Input the 1st polynomial: ");
	poly1 = Poly_new();
	Poly_input(poly1);
	printf("You input is: ");
	Poly_print(poly1);

	puts("Input the 2nd polynomial: ");
	poly2 = Poly_new();
	Poly_input(poly2);
	printf("You input is: ");
	Poly_print(poly2);

	polySum = Poly_new();
	Poly_add(poly1, poly2, polySum);
	printf("Sum = ");
	Poly_print(polySum);

	Poly_free(poly1);
	Poly_free(poly2);
	Poly_free(polySum);
	return 0;
}
static polypaths_planar_overridePolygonObject *
Poly_create_new_from_points(PyTypeObject *type, PyObject *points)
{
	polypaths_planar_overridePolygonObject *poly;
    Py_ssize_t size;
    Py_ssize_t i;

	if (polypaths_planar_overridePolygon_CheckExact(points)) {
		poly = (polypaths_planar_overridePolygonObject *)Poly_copy(
			(polypaths_planar_overridePolygonObject *)points, NULL);
	} else if (polypaths_planar_overrideSeq2_Check(points)) {
		/* Copy existing Seq2 (optimized) */
		poly = Poly_new(type, Py_SIZE(points));
		if (poly == NULL) {
			return NULL;
		}
		memcpy(poly->vert, ((polypaths_planar_overrideSeq2Object *)points)->vec, 
			sizeof(polypaths_planar_override_vec2_t) * Py_SIZE(points));
    } else {
		/* Generic iterable of points */
		points = PySequence_Fast(points, "expected iterable of Vec2 objects");
		if (points == NULL) {
			return NULL;
		}
		size = PySequence_Fast_GET_SIZE(points);
		poly = Poly_new(type, size);
		if (poly == NULL) {
			Py_DECREF(points);
			return NULL;
		}
		for (i = 0; i < size; ++i) {
			if (!polypaths_planar_overrideVec2_Parse(PySequence_Fast_GET_ITEM(points, i), 
				&poly->vert[i].x, &poly->vert[i].y)) {
				PyErr_SetString(PyExc_TypeError,
					"expected iterable of Vec2 objects");
				Py_DECREF(poly);
				Py_DECREF(points);
				return NULL;
			}
		}
		Py_DECREF(points);
    }
    return poly;
}
static polypaths_planar_overridePolygonObject *
Poly_create_new_regular(PyTypeObject *type, PyObject *args, PyObject *kwargs)
{
	Py_ssize_t vert_count, i;
	double radius, angle_step, x, y;
	PyObject *center_arg = NULL;
	double center_x = 0.0, center_y = 0.0;
	double angle = 0.0;
	polypaths_planar_override_vec2_t *vert;
	polypaths_planar_overridePolygonObject *poly;

    static char *kwlist[] = {
		"vertex_count", "radius", "center", "angle", NULL};

    if (!PyArg_ParseTupleAndKeywords(
        args, kwargs, "nd|Od:Polygon.regular", kwlist, 
			&vert_count, &radius, &center_arg, &angle)) {
        return NULL;
    }
	if (center_arg != NULL) {
		if (!polypaths_planar_overrideVec2_Parse(center_arg, &center_x, &center_y)) {
			PyErr_SetString(PyExc_TypeError,
				"Polygon.regular(): "
				"expected Vec2 object for argument center");
			return NULL;
		}
	}
	poly = Poly_new(type, vert_count);
	if (poly == NULL) {
		return NULL;
	}
	angle_step = 360.0 / vert_count;
	for (i = 0, vert = poly->vert; i < vert_count; ++i, ++vert) {
		cos_sin_deg(angle, &x, &y);
		vert->x = x * radius + center_x;
		vert->y = y * radius + center_y;
		angle += angle_step;
	}
	poly->centroid.x = center_x;
	poly->centroid.y = center_y;
	x = (poly->vert[0].x + poly->vert[1].x) * 0.5 - center_x;
	y = (poly->vert[0].y + poly->vert[1].y) * 0.5 - center_y;
	poly->min_r2 = x*x + y*y;
	poly->max_r2 = radius * radius;
	poly->flags |= (POLY_CENTROID_KNOWN_FLAG | POLY_DUP_VERTS_KNOWN_FLAG 
		| POLY_CONVEX_KNOWN_FLAG | POLY_CONVEX_FLAG 
		| POLY_SIMPLE_KNOWN_FLAG | POLY_SIMPLE_FLAG
		| POLY_RADIUS_KNOWN_FLAG | POLY_DEGEN_KNOWN_FLAG);
	if (radius == 0.0) {
		poly->flags |= POLY_DEGEN_FLAG | POLY_DUP_VERTS_FLAG;
	}
	return poly;
}
Esempio n. 4
0
static PlanarPolygonObject *
BBox_to_polygon(PlanarBBoxObject *self)
{
	PlanarPolygonObject *poly;

    assert(PlanarBBox_Check(self));
	poly = Poly_new(&PlanarPolygonType, 4);
	if (poly != NULL) {
		poly->vert[0].x = self->min.x;
		poly->vert[0].y = self->min.y;
		poly->vert[1].x = self->min.x;
		poly->vert[1].y = self->max.y;
		poly->vert[2].x = self->max.x;
		poly->vert[2].y = self->max.y;
		poly->vert[3].x = self->max.x;
		poly->vert[3].y = self->min.y;
		poly->flags = POLY_SIMPLE_KNOWN_FLAG | POLY_SIMPLE_FLAG	
			| POLY_CONVEX_KNOWN_FLAG | POLY_CONVEX_FLAG;
	}
	return poly;
}
static polypaths_planar_overridePolygonObject *
Poly_convex_hull(PyTypeObject *type, PyObject *points) 
{
	polypaths_planar_override_vec2_t *pts;
	polypaths_planar_override_vec2_t *hull_pts = NULL;
	PyObject *pts_alloc = NULL;
	Py_ssize_t size;
	polypaths_planar_overridePolygonObject *hull_poly = NULL;

	if (polypaths_planar_overridePolygon_CheckExact(points) && 
		((polypaths_planar_overridePolygonObject *)points)->flags & POLY_CONVEX_FLAG) {
		return (polypaths_planar_overridePolygonObject *)Poly_copy(
			(polypaths_planar_overridePolygonObject *)points, NULL);
	}
	if (!polypaths_planar_overrideSeq2_Check(points)) {
		points = pts_alloc = call_from_points((PyObject *)type, points);
		if (points == NULL) goto error;
		pts = ((polypaths_planar_overridePolygonObject *)points)->vert;
	} else {
		pts = ((polypaths_planar_overrideSeq2Object *)points)->vec;
	}
	size = Py_SIZE(points);
	hull_pts = adaptive_quick_hull(pts, &size);
	hull_poly = Poly_new(type, size);
	if (hull_pts == NULL || hull_poly == NULL) goto error;
	memcpy(hull_poly->vert, hull_pts, sizeof(polypaths_planar_override_vec2_t) * size);
	PyMem_Free(hull_pts);
	Py_XDECREF(pts_alloc);
	hull_poly->flags = (POLY_CONVEX_KNOWN_FLAG | POLY_CONVEX_FLAG
		| POLY_SIMPLE_KNOWN_FLAG | POLY_SIMPLE_FLAG);
	return hull_poly;
error:
	if (hull_pts != NULL) {
		PyMem_Free(hull_pts);
	}
	Py_XDECREF(hull_poly);
	Py_XDECREF(pts_alloc);
	return NULL;
}
static PyObject *
Poly_copy(polypaths_planar_overridePolygonObject *self, PyObject *args)
{
	PyObject *result;
    polypaths_planar_overridePolygonObject *poly;
    
    assert(polypaths_planar_overridePolygon_Check(self));
    poly = Poly_new(Py_TYPE(self), Py_SIZE(self));
    if (poly == NULL) {
		return NULL;
    }
    memcpy(poly->vert, self->vert, sizeof(polypaths_planar_override_vec2_t) * Py_SIZE(self));
	if (polypaths_planar_overridePolygon_CheckExact(self)) {
		poly->flags = self->flags;
		poly->centroid.x = self->centroid.x;
		poly->centroid.y = self->centroid.y;
		poly->min_r2 = self->min_r2;
		poly->max_r2 = self->max_r2;
		if (self->lt_y_poly != NULL) {
			poly->lt_y_poly = (polypaths_planar_override_vec2_t *)PyMem_Malloc(
				sizeof(polypaths_planar_override_vec2_t) * (Py_SIZE(self) + 2));
			if (poly == NULL) {
				Py_DECREF(poly);
				return PyErr_NoMemory();
			}
			memcpy(poly->lt_y_poly, self->lt_y_poly, 
				sizeof(polypaths_planar_override_vec2_t) * (Py_SIZE(self) + 2));
			poly->rt_y_poly = poly->lt_y_poly + (
				self->rt_y_poly - self->lt_y_poly);
		}
		return (PyObject *)poly;
	} else {
		result = call_from_points((PyObject *)self, (PyObject *)poly);
		Py_DECREF(poly);
		return result;
	}
}
static polypaths_planar_overridePolygonObject *
Poly_create_new_star(PyTypeObject *type, PyObject *args, PyObject *kwargs)
{
	Py_ssize_t peak_count, i;
	double radius1, radius2, angle_step, x, y;
	PyObject *center_arg = NULL;
	double center_x = 0.0, center_y = 0.0;
	double angle = 0.0;
	polypaths_planar_override_vec2_t *vert;
	polypaths_planar_overridePolygonObject *poly;

    static char *kwlist[] = {
		"peak_count", "radius1", "radius2", "center", "angle", NULL};

    if (!PyArg_ParseTupleAndKeywords(
        args, kwargs, "ndd|Od:Polygon.regular", kwlist, 
			&peak_count, &radius1, &radius2, &center_arg, &angle)) {
        return NULL;
    }
	if (peak_count < 2) {
		PyErr_SetString(PyExc_ValueError,
			"star polygon must have a minimum of 2 peaks");
		return NULL;
	}
	if (center_arg != NULL) {
		if (!polypaths_planar_overrideVec2_Parse(center_arg, &center_x, &center_y)) {
			PyErr_SetString(PyExc_TypeError,
				"Polygon.star(): "
				"expected Vec2 object for argument center");
			return NULL;
		}
	}
	poly = Poly_new(type, peak_count * 2);
	if (poly == NULL) {
		return NULL;
	}
	angle_step = 180.0 / peak_count;
	for (i = 0, vert = poly->vert; i < peak_count; ++i, ++vert) {
		cos_sin_deg(angle, &x, &y);
		vert->x = x * radius1 + center_x;
		vert->y = y * radius1 + center_y;
		angle += angle_step;
		++vert;
		cos_sin_deg(angle, &x, &y);
		vert->x = x * radius2 + center_x;
		vert->y = y * radius2 + center_y;
		angle += angle_step;
	}
	poly->centroid.x = center_x;
	poly->centroid.y = center_y;
	x = (poly->vert[0].x + poly->vert[1].x) * 0.5 - center_x;
	y = (poly->vert[0].y + poly->vert[1].y) * 0.5 - center_y;
	if (radius1 != radius2) {
		if (radius1 < radius2) {
			poly->min_r2 = MIN(radius1 * radius1, x*x + y*y);
			poly->max_r2 = radius2 * radius2;
		} else {
			poly->min_r2 = MIN(radius2 * radius2, x*x + y*y);
			poly->max_r2 = radius1 * radius1;
		}
		poly->flags |= POLY_CONVEX_KNOWN_FLAG;
		poly->flags &= ~POLY_CONVEX_FLAG;
		poly->flags |= POLY_DUP_VERTS_FLAG * (
			radius1 == 0.0 || radius2 == 0.0);
		if ((radius1 > 0.0) == (radius2 > 0.0)) {
			poly->flags |= POLY_SIMPLE_FLAG | POLY_SIMPLE_KNOWN_FLAG
				| POLY_CENTROID_KNOWN_FLAG | POLY_RADIUS_KNOWN_FLAG 
				| POLY_DEGEN_KNOWN_FLAG;
		}
	} else {
		poly->min_r2 = x*x + y*y;
		poly->max_r2 = radius1 * radius1;
		poly->flags |= POLY_CONVEX_KNOWN_FLAG | POLY_CONVEX_FLAG
			| POLY_SIMPLE_KNOWN_FLAG | POLY_SIMPLE_FLAG 
			| POLY_CENTROID_KNOWN_FLAG | POLY_RADIUS_KNOWN_FLAG 
			| POLY_DEGEN_KNOWN_FLAG;
		if (radius1 == 0.0) {
			poly->flags |= POLY_DEGEN_FLAG | POLY_DUP_VERTS_FLAG;
		}
	}
	return poly;
}
static polypaths_planar_overridePolygonObject *
Poly_create_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
{
	PyObject *verts_arg, *is_convex_arg = NULL, *is_simple_arg = NULL;
	PyObject *verts_seq = NULL;
	polypaths_planar_overridePolygonObject *poly = NULL;
	Py_ssize_t size, i;

    static char *kwlist[] = {"vertices", "is_convex", "is_simple", NULL};

    if (!PyArg_ParseTupleAndKeywords(
        args, kwargs, "O|OO:Polygon.__init__", kwlist, 
			&verts_arg, &is_convex_arg, &is_simple_arg)) {
        return NULL;
    }
	if (!PySequence_Check(verts_arg)) {
		verts_arg = verts_seq = PySequence_Fast(verts_arg, 
			"expected iterable of Vec2 objects");
		if (verts_seq == NULL) {
			goto error;
		}
	}
	size = PySequence_Size(verts_arg);
	if (size == -1) {
		goto error;
	}
	poly = Poly_new(type, size);
	if (poly == NULL) {
		goto error;
	}
	if ((is_convex_arg != NULL && PyObject_IsTrue(is_convex_arg) > 0)
		|| size == 3) {
		poly->flags = (POLY_CONVEX_FLAG | POLY_CONVEX_KNOWN_FLAG 
			| POLY_SIMPLE_FLAG | POLY_SIMPLE_KNOWN_FLAG);
	} else if (is_simple_arg != NULL && PyObject_IsTrue(is_simple_arg) > 0) {
		poly->flags = POLY_SIMPLE_FLAG | POLY_SIMPLE_KNOWN_FLAG;
	}

    if (polypaths_planar_overrideSeq2_Check(verts_arg)) {
		/* Copy existing Seq2 (optimized) */
		memcpy(poly->vert, ((polypaths_planar_overrideSeq2Object *)verts_arg)->vec, 
			sizeof(polypaths_planar_override_vec2_t) * size);
    } else {
		/* Generic iterable of points */
		for (i = 0; i < size; ++i) {
			if (!polypaths_planar_overrideVec2_Parse(PySequence_Fast_GET_ITEM(verts_arg, i), 
				&poly->vert[i].x, &poly->vert[i].y)) {
				PyErr_SetString(PyExc_TypeError,
					"expected iterable of Vec2 objects");
				goto error;
			}
		}
    }
	Py_XDECREF(verts_seq);
	return poly;

error:
	Py_XDECREF(verts_seq);
	Py_XDECREF(poly);
	return NULL;
}