bool Polygon::convertToInequalityConstraints(Eigen::MatrixXd& A, Eigen::VectorXd& b) const { Eigen::MatrixXd V(nVertices(), 2); for (unsigned int i = 0; i < nVertices(); ++i) V.row(i) = vertices_[i]; // Create k, a list of indices from V forming the convex hull. // TODO: Assuming counter-clockwise ordered convex polygon. // MATLAB: k = convhulln(V); Eigen::MatrixXi k; k.resizeLike(V); for (unsigned int i = 0; i < V.rows(); ++i) k.row(i) << i, (i+1) % V.rows(); Eigen::RowVectorXd c = V.colwise().mean(); V.rowwise() -= c; A = Eigen::MatrixXd::Constant(k.rows(), V.cols(), NAN); unsigned int rc = 0; for (unsigned int ix = 0; ix < k.rows(); ++ix) { Eigen::MatrixXd F(2, V.cols()); F.row(0) << V.row(k(ix, 0)); F.row(1) << V.row(k(ix, 1)); Eigen::FullPivLU<Eigen::MatrixXd> luDecomp(F); if (luDecomp.rank() == F.rows()) { A.row(rc) = F.colPivHouseholderQr().solve(Eigen::VectorXd::Ones(F.rows())); ++rc; } } A = A.topRows(rc); b = Eigen::VectorXd::Ones(A.rows()); b = b + A * c.transpose(); return true; }
std::vector<carve::geom::vector<2> > Face<ndim>::projectedVertices() const { p2_adapt_project<ndim> proj = projector(); std::vector<carve::geom::vector<2> > result; result.reserve(nVertices()); for (size_t i = 0; i < nVertices(); ++i) { result.push_back(proj(vertex(i)->v)); } return result; }
Face<ndim> *Face<ndim>::init(const Face<ndim> *base, iter_t vbegin, iter_t vend, bool flipped) { CARVE_ASSERT(vbegin < vend); vertices.reserve((size_t)std::distance(vbegin, vend)); if (flipped) { std::reverse_copy(vbegin, vend, std::back_inserter(vertices)); plane_eqn = -base->plane_eqn; } else { std::copy(vbegin, vend, std::back_inserter(vertices)); plane_eqn = base->plane_eqn; } edges.clear(); edges.resize(nVertices(), NULL); aabb.fit(vertices.begin(), vertices.end(), vec_adapt_vertex_ptr()); untag(); int da = carve::geom::largestAxis(plane_eqn.N); project = getProjector(plane_eqn.N.v[da] > 0, da); unproject = getUnprojector(plane_eqn.N.v[da] > 0, da); return this; }
void tDxfSpline::refresh() { hs->removeAllVertices(); /* for (int i=0; i<nVertices(); i++){ hs->addVertex(vertex(i)); }*/ if (nVertices()>2){ UpdateControlPoints(); updateXX(); } /* if (data.degree<1 || data.degree>3) { RS_DEBUG->print("RS_Spline::update: invalid degree: %d", data.degree); return; } if (data.controlPoints.size() < data.degree+1) { RS_DEBUG->print("RS_Spline::update: not enough control points"); return; } */ // controlpoints berechnen. }
void Mesh::addRow() { // Create new vertices 2d (temporary). IndexVector2d newVertices2d; resizeVertices2d(newVertices2d, nColumns(), nRows()+1); // Top displacement of points already there. qreal topMoveProp = 1.0f/(nRows()-1) - 1.0f/nRows(); // Add a point at each row. int k = nVertices(); for (int x=0; x<nColumns(); x++) { // Get left and right vertices. QPointF top = getVertex2d(x, 0); QPointF bottom = getVertex2d(x, nRows()-1); QPointF diff = bottom - top; // First pass: move middle points. for (int y=1; y<nRows()-1; y++) { QPointF p = getVertex2d(x, y); p -= diff * y * topMoveProp; _rawSetVertex( _vertices2d[x][y], p ); } // Create and add new point. QPointF newPoint = bottom - diff * 1.0f/nRows(); _addVertex(newPoint); // Assign new vertices 2d. for (int y=0; y<nRows()-1; y++) newVertices2d[x][y] = _vertices2d[x][y]; // The new point. newVertices2d[x][nRows()-1] = k; // The rightmost point. newVertices2d[x][nRows()] = _vertices2d[x][nRows()-1]; k++; } // Copy new mapping. _vertices2d = newVertices2d; // Increment number of columns. _nRows++; // Reorder. _reorderVertices(); }
// vertices 0..3 = 4 corners // void Mesh::addColumn() { // Create new vertices 2d (temporary). IndexVector2d newVertices2d; resizeVertices2d(newVertices2d, nColumns()+1, nRows()); // Left displacement of points already there. qreal leftMoveProp = 1.0f/(nColumns()-1) - 1.0f/nColumns(); // Add a point at each row. int k = nVertices(); for (int y=0; y<nRows(); y++) { // Get left and right vertices. QPointF left = getVertex2d( 0, y ); QPointF right = getVertex2d( nColumns()-1, y ); QPointF diff = right - left; // First pass: move middle points. for (int x=1; x<nColumns()-1; x++) { QPointF p = getVertex2d(x, y); p -= diff * x * leftMoveProp; _rawSetVertex( _vertices2d[x][y], p ); } // Create and add new point. QPointF newPoint = right - diff * 1.0f/nColumns(); _addVertex(newPoint); // Assign new vertices 2d. for (int x=0; x<nColumns()-1; x++) newVertices2d[x][y] = _vertices2d[x][y]; // The new point. newVertices2d[nColumns()-1][y] = k; // The rightmost point. newVertices2d[nColumns()][y] = _vertices2d[nColumns()-1][y]; k++; } // Copy new mapping. _vertices2d = newVertices2d; // Increment number of columns. _nColumns++; // Reorder. _reorderVertices(); }
void MShape::write(QDomElement& obj) { // Write basic data. Serializable::write(obj); // Write vertices. QDomElement verticesObj = obj.ownerDocument().createElement("vertices"); for (int i=0; i<nVertices(); i++) { QDomElement vertexObj = obj.ownerDocument().createElement("vertex"); vertexObj.setAttribute("x", QString::number(getVertex(i).x())); vertexObj.setAttribute("y", QString::number(getVertex(i).y())); verticesObj.appendChild(vertexObj); } obj.appendChild(verticesObj); }
bool Polygon::offsetInward(const double margin) { // Create a list of indices of the neighbours of each vertex. // TODO: Assuming counter-clockwise ordered convex polygon. std::vector<Eigen::Array2i> neighbourIndices; const unsigned int n = nVertices(); neighbourIndices.resize(n); for (unsigned int i = 0; i < n; ++i) { neighbourIndices[i] << (i > 0 ? (i-1)%n : n-1), (i + 1) % n; } std::vector<Position> copy(vertices_); for (unsigned int i = 0; i < neighbourIndices.size(); ++i) { Eigen::Vector2d v1 = vertices_[neighbourIndices[i](0)] - vertices_[i]; Eigen::Vector2d v2 = vertices_[neighbourIndices[i](1)] - vertices_[i]; v1.normalize(); v2.normalize(); const double angle = acos(v1.dot(v2)); copy[i] += margin / sin(angle) * (v1 + v2); } vertices_ = copy; return true; }
void MayaNurbsCurveWriter::write() { Alembic::AbcGeom::OCurvesSchema::Sample samp; samp.setBasis(Alembic::AbcGeom::kBsplineBasis); MStatus stat; mCVCount = 0; // if inheritTransform is on and the curve group is animated, // bake the cv positions in the world space MMatrix exclusiveMatrixInv = mRootDagPath.exclusiveMatrixInverse(&stat); std::size_t numCurves = 1; if (mIsCurveGrp) numCurves = mNurbsCurves.length(); std::vector<Alembic::Util::int32_t> nVertices(numCurves); std::vector<float> points; std::vector<float> width; std::vector<float> knots; std::vector<Alembic::Util::uint8_t> orders(numCurves); MMatrix transformMatrix; bool useConstWidth = false; MFnDependencyNode dep(mRootDagPath.transform()); MPlug constWidthPlug = dep.findPlug("width"); if (!constWidthPlug.isNull()) { useConstWidth = true; width.push_back(constWidthPlug.asFloat()); } for (unsigned int i = 0; i < numCurves; i++) { MFnNurbsCurve curve; if (mIsCurveGrp) { curve.setObject(mNurbsCurves[i]); MMatrix inclusiveMatrix = mNurbsCurves[i].inclusiveMatrix(&stat); transformMatrix = inclusiveMatrix*exclusiveMatrixInv; } else { curve.setObject(mRootDagPath.node()); } if (i == 0) { if (curve.form() == MFnNurbsCurve::kOpen) { samp.setWrap(Alembic::AbcGeom::kNonPeriodic); } else { samp.setWrap(Alembic::AbcGeom::kPeriodic); } if (curve.degree() == 3) { samp.setType(Alembic::AbcGeom::kCubic); } else if (curve.degree() == 1) { samp.setType(Alembic::AbcGeom::kLinear); } else { samp.setType(Alembic::AbcGeom::kVariableOrder); } } else { if (curve.form() == MFnNurbsCurve::kOpen) { samp.setWrap(Alembic::AbcGeom::kNonPeriodic); } if ((samp.getType() == Alembic::AbcGeom::kCubic && curve.degree() != 3) || (samp.getType() == Alembic::AbcGeom::kLinear && curve.degree() != 1)) { samp.setType(Alembic::AbcGeom::kVariableOrder); } } orders[i] = static_cast<Alembic::Util::uint8_t>(curve.degree() + 1); Alembic::Util::int32_t numCVs = curve.numCVs(&stat); MPointArray cvArray; stat = curve.getCVs(cvArray, MSpace::kObject); mCVCount += numCVs; nVertices[i] = numCVs; for (Alembic::Util::int32_t j = 0; j < numCVs; j++) { MPoint transformdPt; if (mIsCurveGrp) { transformdPt = cvArray[j]*transformMatrix; } else { transformdPt = cvArray[j]; } points.push_back(static_cast<float>(transformdPt.x)); points.push_back(static_cast<float>(transformdPt.y)); points.push_back(static_cast<float>(transformdPt.z)); } MDoubleArray knotsArray; curve.getKnots(knotsArray); knots.reserve(knotsArray.length() + 2); // need to add a knot to the start and end (M + 2N + 1) if (knotsArray.length() > 1) { unsigned int knotsLength = knotsArray.length(); if (knotsArray[0] == knotsArray[knotsLength - 1] || knotsArray[0] == knotsArray[1]) { knots.push_back(knotsArray[0]); } else { knots.push_back(2 * knotsArray[0] - knotsArray[1]); } for (unsigned int j = 0; j < knotsLength; ++j) { knots.push_back(knotsArray[j]); } if (knotsArray[0] == knotsArray[knotsLength - 1] || knotsArray[knotsLength - 1] == knotsArray[knotsLength - 2]) { knots.push_back(knotsArray[knotsLength - 1]); } else { knots.push_back(2 * knotsArray[knotsLength - 1] - knotsArray[knotsLength - 2]); } } // width MPlug widthPlug = curve.findPlug("width"); if (!useConstWidth && !widthPlug.isNull()) { MObject widthObj; MStatus status = widthPlug.getValue(widthObj); MFnDoubleArrayData fnDoubleArrayData(widthObj, &status); MDoubleArray doubleArrayData = fnDoubleArrayData.array(); Alembic::Util::int32_t arraySum = doubleArrayData.length(); if (arraySum == numCVs) { for (Alembic::Util::int32_t i = 0; i < arraySum; i++) { width.push_back(static_cast<float>(doubleArrayData[i])); } } else if (status == MS::kSuccess) { MString msg = "Curve "; msg += curve.partialPathName(); msg += " has incorrect size for the width vector."; msg += "\nUsing default constant width of 0.1."; MGlobal::displayWarning(msg); width.clear(); width.push_back(0.1f); useConstWidth = true; } else { width.push_back(widthPlug.asFloat()); useConstWidth = true; } } else if (!useConstWidth) { // pick a default value width.clear(); width.push_back(0.1f); useConstWidth = true; } } Alembic::AbcGeom::GeometryScope scope = Alembic::AbcGeom::kVertexScope; if (useConstWidth) scope = Alembic::AbcGeom::kConstantScope; samp.setCurvesNumVertices(Alembic::Abc::Int32ArraySample(nVertices)); samp.setPositions(Alembic::Abc::V3fArraySample( (const Imath::V3f *)&points.front(), points.size() / 3 )); samp.setWidths(Alembic::AbcGeom::OFloatGeomParam::Sample( Alembic::Abc::FloatArraySample(width), scope) ); if (samp.getType() == Alembic::AbcGeom::kVariableOrder) { samp.setOrders(Alembic::Abc::UcharArraySample(orders)); } if (!knots.empty()) { samp.setKnots(Alembic::Abc::FloatArraySample(knots)); } mSchema.set(samp); }
VertexIter HalfedgeMesh::collapseEdge( EdgeIter e ) { // TODO This method should collapse the given edge and return an iterator to the new vertex created by the collapse. //1. collect elements EdgeIter e4 = e; //Halfedges HalfedgeIter h1 = e4->halfedge(); HalfedgeIter h5 = h1->twin(); //Faces FaceIter f0 = h1->face(); FaceIter f1 = h5->face(); //Early Exit #1: Ignore requests to collapse boundary edges if(f0->isBoundary() || f1->isBoundary()) return verticesEnd(); //Halfedges, cont' HalfedgeIter h2 = h1->next(); HalfedgeIter h0 = h2->next(); HalfedgeIter h3 = h5->next(); HalfedgeIter h4 = h3->next(); HalfedgeIter h7 = h0->twin(); HalfedgeIter h12 = h3->twin(); HalfedgeIter h20 = h2->twin(); HalfedgeIter h15 = h4->twin(); //Edges EdgeIter e0 = h0->edge(); EdgeIter e1 = h3->edge(); EdgeIter e2 = h4->edge(); EdgeIter e3 = h2->edge(); //EdgeIter e4 //Faces //Vertices VertexIter v0 = h0->vertex(); VertexIter v1 = h3->vertex(); VertexIter v2 = h4->vertex(); VertexIter v3 = h2->vertex(); //Early Exit #2: The number of the joint neighbor vertices of the two merging vertices //must be EXACTLY TWO std::vector<VertexIter> v1_neighbors; std::vector<VertexIter> v3_neighbors; HalfedgeIter h = h3; do { h = h->twin(); if(h->vertex() != v1) v1_neighbors.push_back(h->vertex()); h = h->next(); } while(h != h3); h = h2; do { h = h->twin(); if(h->vertex() != v3) v3_neighbors.push_back(h->vertex()); h = h->next(); } while(h != h2); std::sort(v1_neighbors.begin(), v1_neighbors.end()); std::sort(v3_neighbors.begin(), v3_neighbors.end()); std::vector<VertexIter> joint_neighbors; std::set_intersection(v1_neighbors.begin(), v1_neighbors.end(), v3_neighbors.begin(), v3_neighbors.end(), std::back_inserter(joint_neighbors)); if(joint_neighbors.size() != 2) return verticesEnd(); //Early Exit #3: mesh must have more than 4 vertices if neither v1 nor v3 is boundary vertex, //and more than 3 vertices if either v1 or v3 is boundary vertex if(!v1->isBoundary() && !v3->isBoundary() && nVertices() <= 4) return verticesEnd(); if((v1->isBoundary() || v3->isBoundary()) && nVertices() <= 3) return verticesEnd(); //Early Exit #4: v1, v3 cannot be both boundary vertex if(v1->isBoundary() && v3->isBoundary()) return verticesEnd(); //Early Exit #5: boundary vertex needs at least one triangle //By convention, Vertex::degree() returns the face degree if(v0->isBoundary() && v0->degree() <= 1) return verticesEnd(); if(v1->isBoundary() && v1->degree() <= 1) return verticesEnd(); if(v2->isBoundary() && v2->degree() <= 1) return verticesEnd(); if(v3->isBoundary() && v3->degree() <= 1) return verticesEnd(); //Early Exit #6: degenerated case: v0/v1/v2/v3 are duplicated if(v0 == v1 || v0 == v2 || v0 == v3 || v1 == v2 || v1 == v3 || v2 == v3) return verticesEnd(); VertexIter output = verticesEnd(); if(v3->isBoundary()) { std::vector<HalfedgeIter> v1_out; HalfedgeIter h = v1->halfedge(); do { v1_out.push_back(h); h = h->next()->next()->twin(); } while(h != v1->halfedge()); //2. reassign elements //Halfedges h7->twin() = h20; h7->edge() = e3; h20->twin() = h7; h12->twin() = h15; h12->edge() = e2; h15->twin() = h12; for(auto h = v1_out.begin(); h!= v1_out.end(); ++h) (*h)->vertex() = v3; //Vertices v0->halfedge() = h20; v3->halfedge() = h15; v3->position = 0.5f * (v1->position + v3->position); v2->halfedge() = h12; //Edges e3->halfedge() = h20; e2->halfedge() = h15; //Faces //3. delete elements //Halfedges deleteHalfedge(h0); deleteHalfedge(h1); deleteHalfedge(h2); deleteHalfedge(h3); deleteHalfedge(h4); deleteHalfedge(h5); //Vertices deleteVertex(v1); //Edges deleteEdge(e0); deleteEdge(e1); deleteEdge(e4); //Faces deleteFace(f0); deleteFace(f1); output = v3; } else { std::vector<HalfedgeIter> v3_out; HalfedgeIter h = v3->halfedge(); do { v3_out.push_back(h); h = h->next()->next()->twin(); } while(h != v3->halfedge()); //2. reassign elements //Halfedges h7->twin() = h20; h20->twin() = h7; h20->edge() = e0; h12->twin() = h15; h15->twin() = h12; h15->edge() = e1; for(auto h = v3_out.begin(); h!= v3_out.end(); ++h) (*h)->vertex() = v1; //Vertices v0->halfedge() = h20; v1->halfedge() = h15; v1->position = 0.5f * (v1->position + v3->position); v2->halfedge() = h12; //Edges e0->halfedge() = h20; e1->halfedge() = h15; //Faces //3. delete elements //Halfedges deleteHalfedge(h0); deleteHalfedge(h1); deleteHalfedge(h2); deleteHalfedge(h3); deleteHalfedge(h4); deleteHalfedge(h5); //Vertices deleteVertex(v3); //Edges deleteEdge(e2); deleteEdge(e3); deleteEdge(e4); //Faces deleteFace(f0); deleteFace(f1); output = v1; } return output; }
void Face<ndim>::getVertexLoop(std::vector<const vertex_t *> &loop) const { loop.resize(nVertices(), NULL); std::copy(vbegin(), vend(), loop.begin()); }
void tDxfSpline::UpdateControlPoints() { controlPoints.clear(); //tList<tVector> controlPoints; int n = nVertices(); if(isClosed && n < 3) { if(n > 0) controlPoints.append(vertex(0)->vector()); if(n > 1) controlPoints.append(vertex(1)->vector()); return; } if(isClosed && n < 4) { if(n > 0) controlPoints.append(vertex(0)->vector()); if(n > 2) { tVector x1 = vertex(0)->vector(), x2 = vertex(1)->vector(), x3 = vertex(2)->vector(); double dl1 = (x2 - x1).length(); double dl2 = (x3 - x2).length(); double dt = dl1/(dl1 + dl2); if(dt < RS_TOLERANCE || dt > 1.0 - RS_TOLERANCE) //return RS_Vector(false); controlPoints.append((x2 - x1*(1.0 - dt)*(1.0 - dt) - x3*dt*dt)*(1./dt/(1 - dt)/2.0)); } if(n > 1) { controlPoints.append(vertex(n - 1)->vector()); } return; } int iDim = 0; if(isClosed) { iDim = n; } else { iDim = n - 2; } double *dt = new double[iDim]; double dl1, dl2; if(isClosed) { dl1 = (vertex(n - 1)->vector() - vertex(0)->vector()).length(); dl2 = (vertex(1)->vector() - vertex(0)->vector()).length(); dt[0] = dl1/(dl1 + dl2); for(int i = 1; i < iDim - 1; i++) { dl1 = dl2; dl2 = (vertex(i + 1)->vector() - vertex(i)->vector()).length(); dt[i] = dl1/(dl1 + dl2); } dl1 = (vertex(n - 1)->vector() - vertex(n - 2)->vector()).length(); dl2 = (vertex(0)->vector() - vertex(n - 1)->vector()).length(); dt[iDim - 1] = dl1/(dl1 + dl2); } else { dl1 = (vertex(1)->vector() - vertex(0)->vector()).length(); dl2 = (vertex(2)->vector() - vertex(1)->vector()).length(); dt[0] = dl1/(dl1 + dl2/2.0); for(int i = 1; i < iDim - 1; i++) { dl1 = dl2; dl2 = (vertex(i + 2)->vector() - vertex(i + 1)->vector()).length(); dt[i] = dl1/(dl1 + dl2); } dl1 = dl2; dl2 = (vertex(iDim)->vector() - vertex(iDim + 1)->vector()).length(); dt[iDim - 1] = dl1/(dl1 + 2.0*dl2); } double *pdMatrix = GetMatrix(n, dt); if(!pdMatrix) return; tVector *dx = new tVector[iDim], *dx2 = new tVector[iDim]; /*double *dx = new double[iDim]; double *dy = new double[iDim]; double *dx2 = new double[iDim]; double *dy2 = new double[iDim];*/ if(isClosed) { double *pdDiag = pdMatrix; double *pdDiag1 = &pdMatrix[n]; double *pdDiag2 = &pdMatrix[2*n - 1]; double *pdLastCol1 = &pdMatrix[3*n - 2]; double *pdLastCol2 = &pdMatrix[4*n - 4]; dx[0] = vertex(0)->vector() * (1./pdDiag[0]); //dx[0] = vertex(0).x/pdDiag[0]; //dy[0] = vertex(0).y/pdDiag[0]; for(int i = 1; i < iDim - 1; i++) { dx[i] = (vertex(i)->vector() - dx[i-1]*pdDiag2[i-1])*(1./pdDiag[i]); //dx[i] = (vertex(i).x - pdDiag2[i - 1]*dx[i - 1])/pdDiag[i]; //dy[i] = (vertex(i).y - pdDiag2[i - 1]*dy[i - 1])/pdDiag[i]; } dx[iDim-1] = vertex(iDim - 1)->vector() - dx[iDim - 2]*pdDiag2[iDim - 2]; //dx[iDim - 1] = vertex(iDim - 1).x - pdDiag2[iDim - 2]*dx[iDim - 2]; //dy[iDim - 1] = vertex(iDim - 1).y - pdDiag2[iDim - 2]*dy[iDim - 2]; for(int i = 0; i < iDim - 2; i++) { dx[iDim-1] = dx[iDim-1] - (dx[i] * pdLastCol2[i]); //dx[iDim - 1] -= (dx[i]*pdLastCol2[i]); //dy[iDim - 1] -= (dy[i]*pdLastCol2[i]); } dx[iDim-1] = dx[iDim-1] * (1./pdDiag[iDim - 1]); //dx[iDim - 1] /= pdDiag[iDim - 1]; //dy[iDim - 1] /= pdDiag[iDim - 1]; dx2[iDim-1] = dx[iDim-1]*(1./pdDiag[iDim-1]); //dx2[iDim - 1] = dx[iDim - 1]/pdDiag[iDim - 1]; //dy2[iDim - 1] = dy[iDim - 1]/pdDiag[iDim - 1]; dx2[iDim-2] = (dx[iDim-2]-dx2[iDim-1]*pdDiag1[iDim-2])*(1./pdDiag[iDim - 2]); //dx2[iDim - 2] = (dx[iDim - 2] - pdDiag1[iDim - 2]*dx2[iDim - 1])/pdDiag[iDim - 2]; //dy2[iDim - 2] = (dy[iDim - 2] - pdDiag1[iDim - 2]*dy2[iDim - 1])/pdDiag[iDim - 2]; for(int i = iDim - 3; i >= 0; i--) { dx2[i] = (dx[i] - dx2[i + 1]*pdDiag1[i] - dx2[iDim - 1]*pdLastCol1[i])*(1./pdDiag[i]); //dx2[i] = (dx[i] - pdDiag1[i]*dx2[i + 1] - pdLastCol1[i]*dx2[iDim - 1])/pdDiag[i]; //dy2[i] = (dy[i] - pdDiag1[i]*dy2[i + 1] - pdLastCol1[i]*dy2[iDim - 1])/pdDiag[i]; } for(int i = 0; i < iDim; i++) { controlPoints.append(dx2[i]); } } else { double *pdDiag = pdMatrix; double *pdDiag1 = &pdMatrix[n - 2]; double *pdDiag2 = &pdMatrix[2*n - 5]; dx[0] = (vertex(1)->vector() - vertex(0)->vector()*(1.0-dt[0]) * (1.0 - dt[0]))*(1./pdDiag[0]); //dx[0] = (vertex(1).x - vertex(0).x*(1.0 - dt[0])*(1.0 - dt[0]))/pdDiag[0]; //dy[0] = (vertex(1).y - vertex(0).y*(1.0 - dt[0])*(1.0 - dt[0]))/pdDiag[0]; for(int i = 1; i < iDim - 1; i++) { dx[i] = (vertex(i + 1)->vector() - dx[i-1]*pdDiag2[i-1])*(1./pdDiag[i]); //dx[i] = (vertex(i + 1).x - pdDiag2[i - 1]*dx[i - 1])/pdDiag[i]; //dy[i] = (vertex(i + 1).y - pdDiag2[i - 1]*dy[i - 1])/pdDiag[i]; } dx[iDim-1] = ((vertex(iDim)->vector() - vertex(iDim + 1)->vector()*dt[n-3]*dt[n-3]) - dx[iDim-2]*pdDiag2[iDim-2])*(1./pdDiag[iDim-1]); //dx[iDim - 1] = ((vertex(iDim).x - vertex(iDim + 1).x*dt[n - 3]*dt[n - 3]) - // pdDiag2[iDim - 2]*dx[iDim - 2])/pdDiag[iDim - 1]; //dy[iDim - 1] = ((vertex(iDim).y - vertex(iDim + 1).y*dt[n - 3]*dt[n - 3]) - // pdDiag2[iDim - 2]*dy[iDim - 2])/pdDiag[iDim - 1]; dx2[iDim-1] = dx[iDim-1]*(1./pdDiag[iDim - 1]); //dx2[iDim - 1] = dx[iDim - 1]/pdDiag[iDim - 1]; //dy2[iDim - 1] = dy[iDim - 1]/pdDiag[iDim - 1]; for(int i = iDim - 2; i >= 0; i--) { dx2[i] = (dx[i]-dx2[i+1]*pdDiag1[i])*(1./pdDiag[i]); //dx2[i] = (dx[i] - pdDiag1[i]*dx2[i + 1])/pdDiag[i]; //dy2[i] = (dy[i] - pdDiag1[i]*dy2[i + 1])/pdDiag[i]; } controlPoints.append(vertex(0)->vector()); for(int i = 0; i < iDim; i++) { controlPoints.append(dx2[i]); } controlPoints.append(vertex(n - 1)->vector()); } delete[] pdMatrix; delete[] dt; //delete[] dy2; delete[] dx2; //delete[] dy; delete[] dx; }