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, ¢er_arg, &angle)) { return NULL; } if (center_arg != NULL) { if (!polypaths_planar_overrideVec2_Parse(center_arg, ¢er_x, ¢er_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; }
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, ¢er_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, ¢er_x, ¢er_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; }