PyObject * sktrafo_rotation(PyObject * self, PyObject * args) { double angle, cx = 0.0, cy = 0.0; double s, c, offx, offy; if (PyTuple_Size(args) == 2) { PyObject * point; if (!PyArg_ParseTuple(args, "dO", &angle, &point)) return NULL; if (!skpoint_extract_xy(point, &cx, &cy)) { PyErr_SetString(PyExc_ValueError, "Center must be a point object " "or a tuple of floats"); return NULL; } } else if (!PyArg_ParseTuple(args, "d|dd", &angle, &cx, &cy)) return NULL; s = sin(angle); c = cos(angle); /* compute offset. * The rotation around center is * T(p) = center + M * (p - center) * => offset = center - M * center */ offx = cx - c * cx + s * cy; offy = cy - s * cx - c * cy; return SKTrafo_FromDouble(c, s, -s, c, offx, offy); }
/* append a straight line to self. */ static PyObject * curve_append_straight(SKCurveObject * self, PyObject * args) { double x, y; int cont = ContAngle; if (!PyArg_ParseTuple(args, "dd|i", &x, &y, &cont)) { PyObject * sequence; PyErr_Clear(); if (!PyArg_ParseTuple(args, "O|i", &sequence, &cont)) return NULL; if (!skpoint_extract_xy(sequence, &x, &y)) { PyErr_SetString(PyExc_TypeError, "first argument is neither number nor sequence of two numbers"); return NULL; } } if (!SKCurve_AppendLine(self, x, y, cont)) return NULL; Py_INCREF(Py_None); return Py_None; }
static PyObject * sktrafo_call(SKTrafoObject * self, PyObject * args, PyObject * kw) { PyObject * arg; double x, y; if (PyTuple_Size(args) == 2) arg = args; else if (!PyArg_ParseTuple(args, "O", &arg)) return NULL; if (skpoint_extract_xy(arg, &x, &y)) { return SKPoint_FromXY(self->m11 * x + self->m12 * y + self->v1, self->m21 * x + self->m22 * y + self->v2); } else if (SKTrafo_Check(arg)) { register SKTrafoObject * t = (SKTrafoObject *) arg; return SKTrafo_FromDouble(self->m11 * t->m11 + self->m12 * t->m21, self->m21 * t->m11 + self->m22 * t->m21, self->m11 * t->m12 + self->m12 * t->m22, self->m21 * t->m12 + self->m22 * t->m22, self->m11*t->v1 + self->m12*t->v2 + self->v1, self->m21*t->v1 + self->m22*t->v2 +self->v2); } else if (SKRect_Check(arg)) { SKRectObject * result; register SKRectObject * r = (SKRectObject*)arg; if (r == SKRect_InfinityRect || r == SKRect_EmptyRect) { Py_INCREF(r); return (PyObject*)r; } result = (SKRectObject*) \ SKRect_FromDouble(self->m11 * r->left + self->m12 * r->top, self->m21 * r->left + self->m22 * r->top, self->m11 * r->right + self->m12 * r->bottom, self->m21 * r->right + self->m22 * r->bottom); if (result) { SKRect_AddXY(result, self->m11 * r->right + self->m12 * r->top, self->m21 * r->right + self->m22 * r->top); SKRect_AddXY(result, self->m11 * r->left + self->m12 * r->bottom, self->m21 * r->left + self->m22 * r->bottom); result->left += self->v1; result->right += self->v1; result->top += self->v2; result->bottom += self->v2; } return (PyObject*) result; } PyErr_SetString(PyExc_TypeError, "SKTrafo must be applied to SKPoints, " "SKRects or SKTrafos"); return NULL; }
static PyObject * curve_append_segment(SKCurveObject * self, PyObject * args) { double x, y, x1, y1, x2, y2; int cont = ContAngle; int type; PyObject * p, *p1, *p2, *tuple; if (!PyArg_ParseTuple(args, "iOO|i", &type, &tuple, &p, &cont)) return NULL; if (!skpoint_extract_xy(p, &x, &y)) { PyErr_SetString(PyExc_TypeError, "third argument must be a point spec"); return NULL; } if (type == CurveLine) { if (!SKCurve_AppendLine(self, x, y, cont)) return NULL; } else if (type == CurveBezier) { if (!PyArg_ParseTuple(tuple, "OO", &p1, &p2)) return NULL; if (!skpoint_extract_xy(p1, &x1, &y1) || !skpoint_extract_xy(p2, &x2, &y2)) { PyErr_SetString(PyExc_TypeError, "for bezier segments, second argument " "must be a sequence of two point specs "); return NULL; } if (!SKCurve_AppendBezier(self, x1, y1, x2, y2, x, y, cont)) return NULL; } Py_INCREF(Py_None); return Py_None; }
/* append a bezier segment to self. */ static PyObject * curve_append_curve(SKCurveObject * self, PyObject * args) { int cont = ContAngle; double x, y, x1, y1, x2, y2; if (PyTuple_Size(args) > 4) { if (!PyArg_ParseTuple(args, "dddddd|i", &x1, &y1, &x2, &y2, &x, &y, &cont)) return NULL; } else { PyObject *p1, *p2, *p3; int result; if (!PyArg_ParseTuple(args, "OOO|i", &p1, &p2, &p3, &cont)) return NULL; result = skpoint_extract_xy(p1, &x1, &y1); result = result && skpoint_extract_xy(p2, &x2, &y2); result = result && skpoint_extract_xy(p3, &x, &y); if (!result) { PyErr_SetString(PyExc_TypeError, "three points expected"); return NULL; } } if (!SKCurve_AppendBezier(self, x1, y1, x2, y2, x, y, cont)) return NULL; Py_INCREF(Py_None); return Py_None; }
static PyObject * curve_set_straight(SKCurveObject * self, PyObject * args) { double x, y; int idx, cont = ContAngle; if (!PyArg_ParseTuple(args, "idd|i", &idx, &x, &y, &cont)) { PyObject * sequence; PyErr_Clear(); if (!PyArg_ParseTuple(args, "iO|i", &idx, &sequence, &cont)) return NULL; if (!skpoint_extract_xy(sequence, &x, &y)) { PyErr_SetString(PyExc_TypeError, "first argument is neither number nor sequence of two numbers"); return NULL; } } idx = check_index(self, idx, "SetLine"); if (idx < 0) return NULL; self->segments[idx].type = CurveLine; self->segments[idx].cont = cont; self->segments[idx].x = x; self->segments[idx].y = y; if (self->closed) { if (idx == 0) { self->segments[self->len - 1].x = x; self->segments[self->len - 1].y = y; self->segments[self->len - 1].cont = cont; } else if (idx == self->len - 1) { self->segments[0].x = x; self->segments[0].y = y; self->segments[0].cont = cont; } } Py_INCREF(Py_None); return Py_None; }
PyObject * sktrafo_translation(PyObject * self, PyObject * args) { double offx, offy; if (PyTuple_Size(args) == 1) { PyObject * point; if (!PyArg_ParseTuple(args, "O", &point)) return NULL; if (!skpoint_extract_xy(point, &offx, &offy)) { PyErr_SetString(PyExc_ValueError, "Offset must be a point object " "or a tuple of floats"); return NULL; } } else if (!PyArg_ParseTuple(args, "dd", &offx, &offy)) return NULL; return SKTrafo_FromDouble(1.0, 0.0, 0.0, 1.0, offx, offy); }
/* trafo.DTransform(POINT) * * Transform POINT as a vector. This means that the translation is not * applied. (In homogeneous coordinates: if POINT is SKPoint(x, y), treat it as * (x, y, 0) and not (x, y, 1)) */ static PyObject * sktrafo_dtransform(SKTrafoObject * self, PyObject * args) { PyObject * arg; double x, y; if (PyTuple_Size(args) == 2) arg = args; else if (!PyArg_ParseTuple(args, "O", &arg)) return NULL; if (skpoint_extract_xy(arg, &x, &y)) { return SKPoint_FromXY(self->m11 * x + self->m12 * y, self->m21 * x + self->m22 * y); } PyErr_SetString(PyExc_TypeError, "arguments must be either be two numbers, " "a point or a sequence of two numbers"); return NULL; }
static PyObject * curve_apply_translation(SKCurveObject * self, PyObject * args) { double x, y; int i; CurveSegment * segment; if (!PyArg_ParseTuple(args, "dd", &x, &y)) { PyObject * sequence; PyErr_Clear(); if (!PyArg_ParseTuple(args, "O", &sequence)) return NULL; if (!skpoint_extract_xy(sequence, &x, &y)) { PyErr_SetString(PyExc_TypeError, "argument is neither number nor sequence of two numbers"); return NULL; } } segment = self->segments; for (i = 0; i < self->len; i++, segment++) { segment->x += x; segment->y += y; if (segment->type == CurveBezier) { segment->x1 += x; segment->y1 += y; segment->x2 += x; segment->y2 += y; } } Py_INCREF(Py_None); return Py_None; }
/* trafo.DocToWin(POINT) * or: trafo.DocToWin(X, Y) * * Return the point POINT or (X, Y) in window coordinates as a tuple of ints. * POINT may be an SKPointObject or any sequence of two numbers. */ PyObject * sktrafo_DocToWin(SKTrafoObject * self, PyObject * args) { PyObject * arg; double docx, docy; int x, y; if (PyTuple_Size(args) == 2) arg = args; else if (!PyArg_ParseTuple(args, "O", &arg)) return NULL; if (skpoint_extract_xy(arg, &docx, &docy)) { x = ceil(self->m11 * docx + self->m12 * docy + self->v1); y = ceil(self->m21 * docx + self->m22 * docy + self->v2); return Py_BuildValue("ii", x, y); } PyErr_SetString(PyExc_TypeError, "arguments must be either be two numbers, " "a point or a sequence of two numbers"); return NULL; }
static PyObject * curve_set_segment(SKCurveObject * self, PyObject * args) { double x, y, x1, y1, x2, y2; int cont = ContAngle; int idx, type; PyObject * p, *p1, *p2, *tuple; if (!PyArg_ParseTuple(args, "iOO|i", &idx, &type, &tuple, &p, &cont)) return NULL; if (!skpoint_extract_xy(p, &x, &y)) { PyErr_SetString(PyExc_TypeError, "third argument must be a point spec"); return NULL; } idx = check_index(self, idx, "SetSegment"); if (idx < 0) return NULL; self->segments[idx].type = CurveLine; self->segments[idx].cont = cont; self->segments[idx].x = x; self->segments[idx].y = y; if (type == CurveBezier) { if (!PyArg_ParseTuple(tuple, "OO", &p1, &p2)) return NULL; if (!skpoint_extract_xy(p1, &x1, &y1) || !skpoint_extract_xy(p2, &x2, &y2)) { PyErr_SetString(PyExc_TypeError, "for bezier segments, second argument " "must be a sequence of two point specs "); return NULL; } self->segments[idx].x1 = x1; self->segments[idx].y1 = y1; self->segments[idx].x2 = x2; self->segments[idx].y2 = y2; } if (self->closed) { if (idx == 0) { self->segments[self->len - 1].x = x; self->segments[self->len - 1].y = y; self->segments[self->len - 1].cont = cont; } else if (idx == self->len - 1) { self->segments[0].x = x; self->segments[0].y = y; self->segments[0].cont = cont; } } Py_INCREF(Py_None); return Py_None; }
/* append a bezier segment to self. */ static PyObject * curve_set_curve(SKCurveObject * self, PyObject * args) { int idx, cont = ContAngle; double x, y, x1, y1, x2, y2; if (PyTuple_Size(args) > 5) { if (!PyArg_ParseTuple(args, "idddddd|i", &idx, &x1, &y1, &x2, &y2, &x, &y, &cont)) return NULL; } else { PyObject *p1, *p2, *p3; int result; if (!PyArg_ParseTuple(args, "iOOO|i", &idx, &p1, &p2, &p3, &cont)) return NULL; result = skpoint_extract_xy(p1, &x1, &y1); result = result && skpoint_extract_xy(p2, &x2, &y2); result = result && skpoint_extract_xy(p3, &x, &y); if (!result) { PyErr_SetString(PyExc_TypeError, "three points expected"); return NULL; } } idx = check_index(self, idx, "SetBezier"); if (idx < 0) return NULL; self->segments[idx].type = CurveBezier; self->segments[idx].cont = cont; self->segments[idx].x = x; self->segments[idx].y = y; self->segments[idx].x1 = x1; self->segments[idx].y1 = y1; self->segments[idx].x2 = x2; self->segments[idx].y2 = y2; if (self->closed) { if (idx == 0) { self->segments[self->len - 1].x = x; self->segments[self->len - 1].y = y; self->segments[self->len - 1].cont = cont; } else if (idx == self->len - 1) { self->segments[0].x = x; self->segments[0].y = y; self->segments[0].cont = cont; } } Py_INCREF(Py_None); return Py_None; }