void DeformationPath::badMorphing()
{
	for(double t = 0; t <= 1.0; t += scheduler->timeStep)
	{
		// Current nodes geometry
		QMap<Structure::Node*, Array1D_Vector3> startGeometry;
		for(auto n : scheduler->activeGraph->nodes)
		{
			if(n->property["taskTypeReal"].toInt() == Task::GROW)
			{
				Array1D_Vector3 pnts = n->controlPoints();
				Vector3 p = pnts.front();
				Array1D_Vector3 newpnts(pnts.size(), p);
				for(auto & p: newpnts) p += Eigen::Vector3d(starlab::uniformRand(), starlab::uniformRand(), starlab::uniformRand()) * 1e-5;
				n->setControlPoints(newpnts);
			}

			if(n->property["taskTypeReal"].toInt() == Task::SHRINK)
			{
				auto tn = scheduler->targetGraph->getNode( n->property["correspond"].toString() );
				Array1D_Vector3 pnts = tn->controlPoints();
				Vector3 p = pnts[pnts.size() / 2];
				Array1D_Vector3 newpnts(pnts.size(), p);
				for(auto & p: newpnts) p += Eigen::Vector3d(starlab::uniformRand(), starlab::uniformRand(), starlab::uniformRand()) * 1e-5;
				tn->setControlPoints(newpnts);
			}

			startGeometry[n] = n->controlPoints();
		}

		// Morph nodes
		for(auto n : scheduler->activeGraph->nodes)
		{
			auto tn = scheduler->targetGraph->getNode( n->property["correspond"].toString() );
			if(!tn) continue;

			Array1D_Vector3 finalGeometry = tn->controlPoints();
			Array1D_Vector3 newGeometry;

			for(int i = 0; i < (int) finalGeometry.size(); i++)
				newGeometry.push_back( AlphaBlend(t, startGeometry[n][i], Vector3(finalGeometry[i])) );

			n->setControlPoints( newGeometry );
			n->property["t"].setValue( t );

			if(t > 0.5 && n->property["taskTypeReal"].toInt() == Task::SHRINK) 
				n->property["shrunk"].setValue( true );
		}

		scheduler->allGraphs.push_back(  new Structure::Graph( *scheduler->activeGraph )  );
	}

	property["progressDone"] = true;
}
Пример #2
0
/*  ||>*----*----*----*----*
       |    |    |    |    | -->
       |    |    |    |    |
    ||>*----*----*----*----*     Sigma
       |    |    |    |    | -->
       |    |    |    |    |
    ||>*----*----*----*----*
       ^
*/
NuTo::BSplineSurface buildRect2D(double x0, double y0, double Height, double Length)
{
    /** Knots and control points **/
    int numElementsX = 1;
    int numElementsY = 1;

    Eigen::Vector2i degree(2, 2);

    int numKnotsX = 2 * (degree(0) + 1) + numElementsX - 1;
    int numKnotsY = 2 * (degree(1) + 1) + numElementsY - 1;

    Eigen::VectorXd knotsX(numKnotsX);
    Eigen::VectorXd knotsY(numKnotsY);

    for (int i = 0; i <= degree(0); i++)
        knotsX(i) = 0.;
    for (int i = degree(0) + 1; i <= degree(0) + numElementsX - 1; i++)
        knotsX(i) = knotsX(i - 1) + 1. / numElementsX;
    for (int i = degree(0) + numElementsX; i < numKnotsX; i++)
        knotsX(i) = 1;

    for (int i = 0; i <= degree(1); i++)
        knotsY(i) = 0.;
    for (int i = degree(1) + 1; i <= degree(1) + numElementsY - 1; i++)
        knotsY(i) = knotsY(i - 1) + 1. / numElementsY;
    for (int i = degree(1) + numElementsY; i < numKnotsY; i++)
        knotsY(i) = 1;

    int numControlPointsX = (numKnotsX - 1) - degree(0);
    int numControlPointsY = (numKnotsY - 1) - degree(1);

    Eigen::Matrix<Eigen::VectorXd, Eigen::Dynamic, Eigen::Dynamic> controlPoints(numControlPointsY, numControlPointsX);

    double incrx = (Length / (numControlPointsX - 1));
    double incry = (Height / (numControlPointsY - 1));
    for (int i = 0; i < numControlPointsY; i++)
    {
        for (int j = 0; j < numControlPointsX; j++)
        {
            controlPoints(i, j) = Eigen::Vector2d(x0 + incrx * j, y0 + incry * i);
        }
    }

    Eigen::MatrixXd weights(numControlPointsY, numControlPointsX);
    weights.setOnes(numControlPointsY, numControlPointsX);

    return NuTo::BSplineSurface(degree, knotsX, knotsY, controlPoints, weights);
}
Пример #3
0
DenseMatrix BSpline::getControlPoints() const
{
    int nc = coefficients.size();
    DenseMatrix controlPoints(nc, numVariables + 1);

    controlPoints.block(0, 0, nc, numVariables) = knotaverages;
    controlPoints.block(0, numVariables, nc, 1) = coefficients;

    return controlPoints;
}
Пример #4
0
void GraphicsPainter::drawSpline(const QList<Point3f> &points, float radius, int order)
{
    if(points.size() < 2){
        return;
    }

    // calculate axis and up vectors (needed to calculate control points)
    QVector<Vector3f> axisVectors(points.size());
    axisVectors[0] = (points[1] - points[0]).normalized();

    QVector<Vector3f> upVectors(points.size());
    if(points.size() > 2)
        upVectors[0] = (points[1] - points[0]).cross(points[2] - points[1]).normalized();
    else
        upVectors[0] = Vector3f::UnitZ();

    for(int i = 1; i < points.size(); i++){
        Vector3f axis = points[i] - points[i-1];

        if(i != (points.size() - 1)){
            float angle = chemkit::geometry::angle(axis.cast<Real>(), (points[i+1] - points[i]).cast<Real>());
            Vector3f rotationAxis = (points[i] - points[i-1]).cross(points[i+1] - points[i]).normalized();
            axis = chemkit::geometry::rotate(axis, rotationAxis, angle / 2.0f);
        }

        axisVectors[i] = axis.normalized();

        Vector3f rotationAxis = axisVectors[i-1].cross(axisVectors[i]);
        float angle = chemkit::geometry::angle(axis.cast<Real>(), axisVectors[i-1].cast<Real>());
        Vector3f up = chemkit::geometry::rotate(upVectors[i-1], rotationAxis, angle);
        up.normalize();

        upVectors[i] = up;
    }

    // calculate control points
    QVector<Point3f> controlPoints(points.size() * 9);

    for(int i = 0; i < points.size(); i++){
        const Point3f &point = points.at(i);

        Vector3f upVector = upVectors[i];
        Vector3f rightVector = upVector.cross(axisVectors[i]).normalized();

        // 8 points around a square surrounding point

        // right
        Point3f right = point + (rightVector * radius);
        controlPoints[i*9+0] = right;

        // bottom right
        Point3f bottomRight = right + (upVector * -radius);
        controlPoints[i*9+1] = bottomRight;

        // bottom
        Point3f bottom = point + (upVector * -radius);
        controlPoints[i*9+2] = bottom;

        // bottom left
        Point3f bottomLeft = bottom + (rightVector * -radius);
        controlPoints[i*9+3] = bottomLeft;

        // left
        Point3f left = point + (rightVector * -radius);
        controlPoints[i*9+4] = left;

        // top left
        Point3f topLeft = left + (upVector * radius);
        controlPoints[i*9+5] = topLeft;

        // top
        Point3f top = point + (upVector * radius);
        controlPoints[i*9+6] = top;

        // top right
        Point3f topRight = top + (rightVector * radius);

        controlPoints[i*9+7] = topRight;

        // right (again)
        controlPoints[i*9+8] = right;
    }

    // build knot vector
    QVector<float> uKnots(points.size() + order);
    for(int i = 0; i < uKnots.size(); i++){
        if(i < order)
            uKnots[i] = 0;
        else if(i > (points.size()) - 1)
            uKnots[i] = (points.size() + order) - 2 * order + 1;
        else
            uKnots[i] = (i - order + 1);
    }

    QVector<float> vKnots(12);
    vKnots[0] = 0;
    vKnots[1] = 0;
    vKnots[2] = 0;
    vKnots[3] = chemkit::constants::Pi / 2.0;
    vKnots[4] = chemkit::constants::Pi / 2.0;
    vKnots[5] = chemkit::constants::Pi;
    vKnots[6] = chemkit::constants::Pi;
    vKnots[7] = 3.0 * chemkit::constants::Pi / 2.0;
    vKnots[8] = 3.0 * chemkit::constants::Pi / 2.0;
    vKnots[9] = 2.0 * chemkit::constants::Pi;
    vKnots[10] = 2.0 * chemkit::constants::Pi;
    vKnots[11] = 2.0 * chemkit::constants::Pi;

    drawNurbsSurface(controlPoints, uKnots, vKnots, order, 3);

    drawCircle(points.first(), radius * 1.08, -axisVectors.first());
    drawCircle(points.last(), radius * 1.08, axisVectors.last());
}
Пример #5
0
void Apsis::Map::raise(float amount) {
  // Every tile this touches is raised a little bit
  Apsis::Tile* tile;
  float old_height;

  if (_x != _width && _z != _height) {
    // Bottom Right
    tile = atIndex(_x, _z);
    old_height = tile->cornerHeight(Apsis::TOP_LEFT);
    tile->cornerHeight(Apsis::TOP_LEFT, old_height + amount);
  }

  if (_x != 0 && _z != _height) {
    // Bottom Left
    tile = atIndex(_x-1, _z);
    old_height = tile->cornerHeight(Apsis::TOP_RIGHT);
    tile->cornerHeight(Apsis::TOP_RIGHT, old_height + amount);
  }

  if (_x != _width && _z != 0) {
    // Top Right
    tile = atIndex(_x, _z-1);
    old_height = tile->cornerHeight(Apsis::BOT_LEFT);
    tile->cornerHeight(Apsis::BOT_LEFT, old_height + amount);
  }

  if (_x != 0 && _z != 0) {
    // Top Left
    tile = atIndex(_x-1, _z-1);
    old_height = tile->cornerHeight(Apsis::BOT_RIGHT);
    tile->cornerHeight(Apsis::BOT_RIGHT, old_height + amount);
  }

  // Regenerate curve points along this point

  // Horizontal

  Point* line;
  Point* first;
  Point* second;
  line = new Point[_width+1];
  first = new Point[_width];
  second = new Point[_width];

  for (unsigned int x = 0; x < _width; x++) {
    tile = atIndex(x, _z);
    line[x].x = (float)x;
    line[x].y = tile->cornerHeight(Apsis::TOP_LEFT);
    line[x].z = 0.0f; // does not matter
  }
  line[_width].x = (float)_width;
  line[_width].y = tile->cornerHeight(Apsis::TOP_RIGHT);
  line[_width].z = 0.0f;

  controlPoints(line, first, second, _width+1);

  // Pass control points back to tiles

  for (unsigned int x = 0; x < _width; x++) {
    tile = atIndex(x, _z);
    tile->firstControl(Apsis::TOP_LEFT, first[x].y);
    tile->secondControl(Apsis::TOP_LEFT, second[x].y);
    if (_z != 0) {
      tile = atIndex(x, _z-1);
      tile->firstControl(Apsis::BOT_RIGHT, first[x].y);
      tile->secondControl(Apsis::BOT_RIGHT, second[x].y);
    }
  }

  delete [] first;
  delete [] second;
  delete [] line;

  // Vertical

  line = new Point[_height+1];
  first = new Point[_height+1];
  second = new Point[_height+1];

  for (unsigned int z = 0; z < _height; z++) {
    tile = atIndex(_x, z);
    line[z].x = (float)z; // does not matter
    line[z].y = tile->cornerHeight(Apsis::TOP_LEFT);
    line[z].z = 0.0f;
  }
  line[_height].x = (float)_height;
  line[_height].y = tile->cornerHeight(Apsis::BOT_LEFT);
  line[_height].z = 0.0f;

  controlPoints(line, first, second, _height+1);

  // Pass control points back to tiles

  for (unsigned int z = 0; z < _height; z++) {
    tile = atIndex(_x, z);
    tile->firstControl(Apsis::BOT_LEFT, first[z].y);
    tile->secondControl(Apsis::BOT_LEFT, second[z].y);
    if (_x != 0) {
      tile = atIndex(_x-1, z);
      tile->firstControl(Apsis::TOP_RIGHT, first[z].y);
      tile->secondControl(Apsis::TOP_RIGHT, second[z].y);
    }
  }

  delete [] first;
  delete [] second;
  delete [] line;
}