bool GeometryUtils::project(const Mat4d& projectionMultViewMatrix, const Vec2i& viewportPosition, const Vec2ui& viewportSize, const Vec3d& point, Vec3d* out)
{
    CVF_ASSERT(out);

    Vec4d v = projectionMultViewMatrix * Vec4d(point, 1.0);

    if (v.w() == 0.0f)
    {
        return false;
    }

    v.x() /= v.w();
    v.y() /= v.w();
    v.z() /= v.w();

    // map to range 0-1
    out->x() = v.x()*0.5 + 0.5;
    out->y() = v.y()*0.5 + 0.5;
    out->z() = v.z()*0.5 + 0.5;

    // map to viewport
    out->x() = out->x() * viewportSize.x() + viewportPosition.x();
    out->y() = out->y() * viewportSize.y() + viewportPosition.y();

    return true;
}
Exemple #2
0
int
XSpline::linearCombinationFor(LinearCoefficient* coeffs, int segment, double t) const
{
	assert(segment >= 0 && segment < (int)m_controlPoints.size() - 1);
	assert(t >= 0 && t <= 1);

	int idxs[4];
	idxs[0] = std::max<int>(0, segment - 1);
	idxs[1] = segment;
	idxs[2] = segment + 1;
	idxs[3] = std::min<int>(segment + 2, m_controlPoints.size() - 1);

	ControlPoint pts[4];
	for (int i = 0; i < 4; ++i) {
		pts[i] = m_controlPoints[idxs[i]];
	}

	TensionDerivedParams const tdp(pts[1].tension, pts[2].tension);

	Vec4d A;

	if (t <= tdp.T0p) {
		A[0] = GBlendFunc(tdp.q[0], tdp.p[0]).value((t - tdp.T0p) / (tdp.t0 - tdp.T0p));
	} else {
		A[0] = HBlendFunc(tdp.q[0]).value((t - tdp.T0p) / (tdp.t0 - tdp.T0p));
	}

	A[1] = GBlendFunc(tdp.q[1], tdp.p[1]).value((t - tdp.T1p) / (tdp.t1 - tdp.T1p));
	A[2] = GBlendFunc(tdp.q[2], tdp.p[2]).value((t - tdp.T2m) / (tdp.t2 - tdp.T2m));

	if (t >= tdp.T3m) {
		A[3] = GBlendFunc(tdp.q[3], tdp.p[3]).value((t - tdp.T3m) / (tdp.t3 - tdp.T3m));
	} else {
		A[3] = HBlendFunc(tdp.q[3]).value((t - tdp.T3m) / (tdp.t3 - tdp.T3m));
	}

	A /= A.sum();

	int out_idx = 0;

	if (idxs[0] == idxs[1]) {
		coeffs[out_idx++] = LinearCoefficient(idxs[0], A[0] + A[1]);
	} else {
		coeffs[out_idx++] = LinearCoefficient(idxs[0], A[0]);
		coeffs[out_idx++] = LinearCoefficient(idxs[1], A[1]);
	}
	
	if (idxs[2] == idxs[3]) {
		coeffs[out_idx++] = LinearCoefficient(idxs[2], A[2] + A[3]);
	} else {
		coeffs[out_idx++] = LinearCoefficient(idxs[2], A[2]);
		coeffs[out_idx++] = LinearCoefficient(idxs[3], A[3]);
	}

	return out_idx;
}
Exemple #3
0
Intersector* RayIntersector::clone(IntersectionVisitor& iv)
{
    if (_coordinateFrame==MODEL && iv.getModelMatrix()==0)
    {
        return new RayIntersector(MODEL, _start, _direction, this, _intersectionLimit);
    }

    Matrix matrix(LineSegmentIntersector::getTransformation(iv, _coordinateFrame));

    Vec3d newStart = _start * matrix;
    Vec4d tmp = Vec4d(_start + _direction, 1.) * matrix;
    Vec3d newEnd = Vec3d(tmp.x(), tmp.y(), tmp.z()) - (newStart * tmp.w());
    return new RayIntersector(MODEL, newStart, newEnd, this, _intersectionLimit);
}
Vec4d HfT_osg_Plugin01_ParametricSurface::Curvature2Color(double curvature, double curvaturemin, double curvaturemax)
{
    Vec4d color;
    curvature *= 1000;
    curvaturemin *= 1000;
    curvaturemax *= 1000;

    double rotf = rot(curvature, curvaturemax);
    double gruenf = gruen(curvature, curvaturemin);
    double blauf = blau();

    color.set(rotf, gruenf, blauf, 1.);

    //fprintf(stderr,"r,g,b = %f %f %f \n",color[0],color[1],color[2]);
    return (color);
}
bool Component::setupClipping(Graphics* const Graphics) const
{
    if(getClipping())
    {    
        //Get Clipping initial settings
        Pnt2f ClipTopLeft,ClipBottomRight;
        getClipBounds(ClipTopLeft,ClipBottomRight);

        Vec4d LeftPlaneEquation  (1.0,0.0,0.0, -ClipTopLeft.x()     + Graphics->getClipPlaneOffset()),
              RightPlaneEquation (-1.0,0.0,0.0, ClipBottomRight.x() + Graphics->getClipPlaneOffset()),
              TopPlaneEquation   (0.0,1.0,0.0, -ClipTopLeft.y()     + Graphics->getClipPlaneOffset()),
              BottomPlaneEquation(0.0,-1.0,0.0, ClipBottomRight.y() + Graphics->getClipPlaneOffset());

        //glClipPlane
        //Clip with the Intersection of this components RenderingSurface bounds
        //and its parents RenderingSurface bounds
        if(ClipBottomRight.x()-ClipTopLeft.x() <= 0 || ClipBottomRight.y()-ClipTopLeft.y()<= 0)
        {
            return false;
        }

        if(!glIsEnabled(GL_CLIP_PLANE0)) { glEnable(GL_CLIP_PLANE0); }
        if(!glIsEnabled(GL_CLIP_PLANE1)) { glEnable(GL_CLIP_PLANE1); }
        if(!glIsEnabled(GL_CLIP_PLANE2)) { glEnable(GL_CLIP_PLANE2); }
        if(!glIsEnabled(GL_CLIP_PLANE3)) { glEnable(GL_CLIP_PLANE3); }

        //Clip Plane Equations
        //Clip Planes get transformed by the ModelViewMatrix when set
        //So we can rely on the fact that our current coordinate space
        //is relative to the this components position

        glClipPlane(GL_CLIP_PLANE0,LeftPlaneEquation.getValues());
        glClipPlane(GL_CLIP_PLANE1,RightPlaneEquation.getValues());
        glClipPlane(GL_CLIP_PLANE2,TopPlaneEquation.getValues());
        glClipPlane(GL_CLIP_PLANE3,BottomPlaneEquation.getValues());
    }
    else
    {
        if(glIsEnabled(GL_CLIP_PLANE0)) { glDisable(GL_CLIP_PLANE0); }
        if(glIsEnabled(GL_CLIP_PLANE1)) { glDisable(GL_CLIP_PLANE1); }
        if(glIsEnabled(GL_CLIP_PLANE2)) { glDisable(GL_CLIP_PLANE2); }
        if(glIsEnabled(GL_CLIP_PLANE3)) { glDisable(GL_CLIP_PLANE3); }
    }
    return true;
}
  double objective_cost(map<string,Vec4d>&target_positions,map<string,double>&solution)
  {
    // compute target component
    double ssd = 0;
    for(auto && targ : target_positions)
    {
      Vec4d cur = joint_position(targ.first,solution);
      ssd += cur.dist(targ.second);
    }

    // compute the reguarizer cost.
    for(auto && param : solution)
    {
      auto null_value = null_solution.find(param.first);
      if(null_value != null_solution.end())
      {
	double C = regularizers[param.first];
	double diff = null_value->second - param.second;
	ssd += C * diff * diff;
      }
    }
    
    return ssd;
  }
Exemple #7
0
Array* Array_readLocalData(Input& fr)
{
    if (fr[0].matchWord("Use"))
    {
        if (fr[1].isString())
        {
            Object* obj = fr.getObjectForUniqueID(fr[1].getStr());
            if (obj)
            {
                fr+=2;
                return dynamic_cast<Array*>(obj);
            }
        }

        osg::notify(osg::WARN)<<"Warning: invalid uniqueID found in file."<<std::endl;
        return NULL;
    }

    std::string uniqueID;
    if (fr[0].matchWord("UniqueID") && fr[1].isString())
    {
        uniqueID = fr[1].getStr();
        fr += 2;
    }


    int entry = fr[0].getNoNestedBrackets();

    const char* arrayName = fr[0].getStr();

    unsigned int capacity = 0;
    fr[1].getUInt(capacity);
    ++fr;

    fr += 2;


    Array* return_array = 0;

    if (strcmp(arrayName,"ByteArray")==0)
    {
        ByteArray* array = new ByteArray;
        array->reserve(capacity);
        while (!fr.eof() && fr[0].getNoNestedBrackets()>entry)
        {
            int int_value;
            if (fr[0].getInt(int_value))
            {
                ++fr;
                array->push_back(int_value);
            }
            else ++fr;
        }
        ++fr;

        return_array = array;
    }
    else if (strcmp(arrayName,"ShortArray")==0)
    {
        ShortArray* array = new ShortArray;
        array->reserve(capacity);
        while (!fr.eof() && fr[0].getNoNestedBrackets()>entry)
        {
            int int_value;
            if (fr[0].getInt(int_value))
            {
                ++fr;
                array->push_back(int_value);
            }
            else ++fr;
        }
        ++fr;
        return_array = array;
    }
    else if (strcmp(arrayName,"IntArray")==0)
    {
        IntArray* array = new IntArray;
        array->reserve(capacity);
        while (!fr.eof() && fr[0].getNoNestedBrackets()>entry)
        {
            int int_value;
            if (fr[0].getInt(int_value))
            {
                ++fr;
                array->push_back(int_value);
            }
            else ++fr;
        }
        ++fr;
        return_array = array;
    }
    else if (strcmp(arrayName,"UByteArray")==0)
    {
        UByteArray* array = new UByteArray;
        array->reserve(capacity);
        while (!fr.eof() && fr[0].getNoNestedBrackets()>entry)
        {
            unsigned int uint_value;
            if (fr[0].getUInt(uint_value))
            {
                ++fr;
                array->push_back(uint_value);
            }
            else ++fr;
        }
        ++fr;
        return_array = array;
    }
    else if (strcmp(arrayName,"UShortArray")==0)
    {
        UShortArray* array = new UShortArray;
        array->reserve(capacity);
        while (!fr.eof() && fr[0].getNoNestedBrackets()>entry)
        {
            unsigned int uint_value;
            if (fr[0].getUInt(uint_value))
            {
                ++fr;
                array->push_back(uint_value);
            }
            else ++fr;
        }
        ++fr;
        return_array = array;
    }
    else if (strcmp(arrayName,"UIntArray")==0)
    {
        UIntArray* array = new UIntArray;
        array->reserve(capacity);
        while (!fr.eof() && fr[0].getNoNestedBrackets()>entry)
        {
            unsigned int uint_value;
            if (fr[0].getUInt(uint_value))
            {
                ++fr;
                array->push_back(uint_value);
            }
            else ++fr;
        }
        ++fr;
        return_array = array;
    }
    else if (strcmp(arrayName,"UVec4bArray")==0 || strcmp(arrayName,"Vec4ubArray")==0)
    {
        Vec4ubArray* array = new Vec4ubArray;
        array->reserve(capacity);
        while (!fr.eof() && fr[0].getNoNestedBrackets()>entry)
        {
            unsigned int r,g,b,a;
            if (fr[0].getUInt(r) &&
                fr[1].getUInt(g) &&
                fr[2].getUInt(b) &&
                fr[3].getUInt(a))
            {
                fr+=4;
                array->push_back(osg::Vec4ub(r,g,b,a));
            }
            else ++fr;
        }
        ++fr;
        return_array = array;
    }
    else if (strcmp(arrayName,"FloatArray")==0)
    {
        FloatArray* array = new FloatArray;
        array->reserve(capacity);
        while (!fr.eof() && fr[0].getNoNestedBrackets()>entry)
        {
            float float_value;
            if (fr[0].getFloat(float_value))
            {
                ++fr;
                array->push_back(float_value);
            }
            else ++fr;
        }
        ++fr;
        return_array = array;
    }
    else if (strcmp(arrayName,"DoubleArray")==0)
    {
        DoubleArray* array = new DoubleArray;
        array->reserve(capacity);
        while (!fr.eof() && fr[0].getNoNestedBrackets()>entry)
        {
            double double_value;
            if (fr[0].getFloat(double_value))
            {
                ++fr;
                array->push_back(double_value);
            }
            else ++fr;
        }
        ++fr;
        return_array = array;
    }
    else if (strcmp(arrayName,"Vec2Array")==0)
    {
        Vec2Array* array = new Vec2Array;
        array->reserve(capacity);
        while (!fr.eof() && fr[0].getNoNestedBrackets()>entry)
        {
            Vec2 v;
            if (fr[0].getFloat(v.x()) && fr[1].getFloat(v.y()))
            {
                fr += 2;
                array->push_back(v);
            }
            else ++fr;
        }
        ++fr;
        return_array = array;
    }
    else if (strcmp(arrayName,"Vec2dArray")==0)
    {
        Vec2dArray* array = new Vec2dArray;
        array->reserve(capacity);
        while (!fr.eof() && fr[0].getNoNestedBrackets()>entry)
        {
            Vec2d v;
            if (fr[0].getFloat(v.x()) && fr[1].getFloat(v.y()))
            {
                fr += 2;
                array->push_back(v);
            }
            else ++fr;
        }
        ++fr;
        return_array = array;
    }
    else if (strcmp(arrayName,"Vec3Array")==0)
    {
        Vec3Array* array = new Vec3Array;
        array->reserve(capacity);
        while (!fr.eof() && fr[0].getNoNestedBrackets()>entry)
        {
            Vec3 v;
            if (fr[0].getFloat(v.x()) && fr[1].getFloat(v.y()) && fr[2].getFloat(v.z()))
            {
                fr += 3;
                array->push_back(v);
            }
            else ++fr;
        }
        ++fr;
        return_array = array;
    }
    else if (strcmp(arrayName,"Vec3dArray")==0)
    {
        Vec3dArray* array = new Vec3dArray;
        array->reserve(capacity);
        while (!fr.eof() && fr[0].getNoNestedBrackets()>entry)
        {
            Vec3d v;
            if (fr[0].getFloat(v.x()) && fr[1].getFloat(v.y()) && fr[2].getFloat(v.z()))
            {
                fr += 3;
                array->push_back(v);
            }
            else ++fr;
        }
        ++fr;
        return_array = array;
    }
    else if (strcmp(arrayName,"Vec4Array")==0)
    {
        Vec4Array* array = new Vec4Array;
        array->reserve(capacity);
        while (!fr.eof() && fr[0].getNoNestedBrackets()>entry)
        {
            Vec4 v;
            if (fr[0].getFloat(v.x()) && fr[1].getFloat(v.y()) && fr[2].getFloat(v.z()) && fr[3].getFloat(v.w()))
            {
                fr += 4;
                array->push_back(v);
            }
            else ++fr;
        }
        ++fr;
        return_array = array;
    }
    else if (strcmp(arrayName,"Vec4dArray")==0)
    {
        Vec4dArray* array = new Vec4dArray;
        array->reserve(capacity);
        while (!fr.eof() && fr[0].getNoNestedBrackets()>entry)
        {
            Vec4d v;
            if (fr[0].getFloat(v.x()) && fr[1].getFloat(v.y()) && fr[2].getFloat(v.z()) && fr[3].getFloat(v.w()))
            {
                fr += 4;
                array->push_back(v);
            }
            else ++fr;
        }
        ++fr;
        return_array = array;
    }
    else if (strcmp(arrayName,"Vec2bArray")==0)
    {
        Vec2bArray* array = new Vec2bArray;
        array->reserve(capacity);
        while (!fr.eof() && fr[0].getNoNestedBrackets()>entry)
        {
            unsigned int r,g;
            if (fr[0].getUInt(r) &&
                fr[1].getUInt(g))
            {
                fr+=2;
                array->push_back(osg::Vec2b(r,g));
            }
            else ++fr;
        }
        ++fr;
        return_array = array;
    }
    else if (strcmp(arrayName,"Vec3bArray")==0)
    {
        Vec3bArray* array = new Vec3bArray;
        array->reserve(capacity);
        while (!fr.eof() && fr[0].getNoNestedBrackets()>entry)
        {
            unsigned int r,g,b;
            if (fr[0].getUInt(r) &&
                fr[1].getUInt(g) &&
                fr[2].getUInt(b))
            {
                fr+=3;
                array->push_back(osg::Vec3b(r,g,b));
            }
            else ++fr;
        }
        ++fr;
        return_array = array;
    }
    else if (strcmp(arrayName,"Vec4bArray")==0)
    {
        Vec4bArray* array = new Vec4bArray;
        array->reserve(capacity);
        while (!fr.eof() && fr[0].getNoNestedBrackets()>entry)
        {
            unsigned int r,g,b,a;
            if (fr[0].getUInt(r) &&
                fr[1].getUInt(g) &&
                fr[2].getUInt(b) &&
                fr[3].getUInt(a))
            {
                fr+=4;
                array->push_back(osg::Vec4b(r,g,b,a));
            }
            else ++fr;
        }
        ++fr;
        return_array = array;
    }
    else if (strcmp(arrayName,"Vec2sArray")==0)
    {
        Vec2sArray* array = new Vec2sArray;
        array->reserve(capacity);
        while (!fr.eof() && fr[0].getNoNestedBrackets()>entry)
        {
            unsigned int r,g;
            if (fr[0].getUInt(r) &&
                fr[1].getUInt(g))
            {
                fr+=2;
                array->push_back(osg::Vec2s(r,g));
            }
            else ++fr;
        }
        ++fr;
        return_array = array;
    }
    else if (strcmp(arrayName,"Vec3sArray")==0)
    {
        Vec3sArray* array = new Vec3sArray;
        array->reserve(capacity);
        while (!fr.eof() && fr[0].getNoNestedBrackets()>entry)
        {
            unsigned int r,g,b;
            if (fr[0].getUInt(r) &&
                fr[1].getUInt(g) &&
                fr[2].getUInt(b))
            {
                fr+=3;
                array->push_back(osg::Vec3s(r,g,b));
            }
            else ++fr;
        }
        ++fr;
        return_array = array;
    }
    else if (strcmp(arrayName,"Vec4sArray")==0)
    {
        Vec4sArray* array = new Vec4sArray;
        array->reserve(capacity);
        while (!fr.eof() && fr[0].getNoNestedBrackets()>entry)
        {
            unsigned int r,g,b,a;
            if (fr[0].getUInt(r) &&
                fr[1].getUInt(g) &&
                fr[2].getUInt(b) &&
                fr[3].getUInt(a))
            {
                fr+=4;
                array->push_back(osg::Vec4s(r,g,b,a));
            }
            else ++fr;
        }
        ++fr;
        return_array = array;
    }

    if (return_array)
    {
        if (!uniqueID.empty()) fr.registerUniqueIDForObject(uniqueID.c_str(),return_array);
    }

    return return_array;
}
//
// TODO 2: ConvertToPlaneCoordinate()
//		Given a plane defined by points, converts their coordinates into
//		plane coordinates. See the following document for more detail.
//		http://www.cs.cornell.edu/courses/cs4670/2012fa/projects/p4/homography.pdf.
//      The final divisors you apply to the u and v coordinates should be saved uScale and vScale
//
void ConvertToPlaneCoordinate(const vector<SVMPoint>& points, vector<Vec3d>& basisPts, double &uScale, double &vScale)
{
    int numPoints = points.size();

    /******** BEGIN TODO ********/
	// Choose p,q,r from points to define a unique plane
	Vec4d r = Vec4d(points[0].X, points[0].Y, points[0].Z, points[0].W);
	Vec4d p = Vec4d(points[1].X, points[1].Y, points[1].Z, points[1].W);
	Vec4d q;

	Vec4d rp = p - r;
	rp.normalize();
	
	// Initialize as worst
	double best_angleCOS = 1.0;

	// Loop to find the best q s.t. angle(rp,rq)->90 degrees, i.e. dot(rp/|rp|,rq/|rq|)->0
	for (int cnt_q = 2; cnt_q < numPoints; cnt_q++)
	{
		Vec4d qTmp = Vec4d(points[cnt_q].X, points[cnt_q].Y, points[cnt_q].Z, points[cnt_q].W);
		Vec4d rqTmp = qTmp - r;
		rqTmp.normalize();
		// Compute the angle between rp and rq
		//double angleCOS = rp * rqTmp;
		double angleCOS = (rp[0] * rqTmp[0])+(rp[1] * rqTmp[1])+(rp[2] * rqTmp[2])+(rp[3] * rqTmp[3]);
		if (abs(angleCOS) < abs(best_angleCOS))
		{
			best_angleCOS = angleCOS;
			q = qTmp;
		}
	}
	
	Vec4d rq = q - r;

	// Normalized already
	Vec4d e_x = rp;
	//Vec4d s = (rq * e_x) * e_x;
	double num1=(rq[0] * e_x[0])+(rq[1] * e_x[1])+(rq[2] * e_x[2])+(rq[3] * e_x[3]);
	Vec4d s=Vec4d(e_x[0]*num1,e_x[1]*num1,e_x[2]*num1,e_x[3]*num1);
	Vec4d t = rq - s;
	Vec4d e_y = t;
	e_y.normalize();

	// Ready for u,v
	double u_min = FLT_MAX, v_min = FLT_MAX;
	double u_max = 0, v_max = 0;

	for (int cnt_a = 0; cnt_a < numPoints; cnt_a++)
	{
		Vec4d a = Vec4d(points[cnt_a].X, points[cnt_a].Y, points[cnt_a].Z, points[cnt_a].W);
		Vec4d ra = a - r;
		//Vec3d Coord2D = Vec3d(ra*e_x, ra*e_y, 1.0);
		double num1=(ra[0] * e_x[0])+(ra[1] * e_x[1])+(ra[2] * e_x[2])+(ra[3] * e_x[3]);
		double num2=(ra[0] * e_y[0])+(ra[1] * e_y[1])+(ra[2] * e_y[2])+(ra[3] * e_y[3]);
		Vec3d Coord2D = Vec3d(num1, num2, 1.0);
		basisPts.push_back(Coord2D);
		if (Coord2D[0] < u_min)
			u_min = Coord2D[0];
		if (Coord2D[0] > u_max)
			u_max = Coord2D[0];
		if (Coord2D[1] < v_min)
			v_min = Coord2D[1];
		if (Coord2D[1] > v_max)
			v_max = Coord2D[1];
	}

	// Output
	uScale = u_max - u_min;
	vScale = v_max - v_min;

    /******** END TODO ********/
}
Exemple #9
0
XSpline::DecomposedDerivs
XSpline::decomposedDerivsImpl(int const segment, double const t) const
{
	assert(segment >= 0 && segment < (int)m_controlPoints.size() - 1);
	assert(t >= 0 && t <= 1);

	DecomposedDerivs derivs;

	derivs.numControlPoints = 4; // May be modified later in this function.
	derivs.controlPoints[0] = std::max<int>(0, segment - 1);
	derivs.controlPoints[1] = segment;
	derivs.controlPoints[2] = segment + 1;
	derivs.controlPoints[3] = std::min<int>(segment + 2, m_controlPoints.size() - 1);

	ControlPoint pts[4];
	for (int i = 0; i < 4; ++i) {
		pts[i] = m_controlPoints[derivs.controlPoints[i]];
	}

	TensionDerivedParams const tdp(pts[1].tension, pts[2].tension);

	// Note that we don't want the derivate with respect to t that's
	// passed to us (ranging from 0 to 1 within a segment).
	// Rather we want it with respect to the t that's passed to
	// decomposedDerivs(), ranging from 0 to 1 across all segments.
	// Let's call the latter capital T.  Their relationship is:
	// t = T*num_segments - C
	// dt/dT = num_segments
	double const dtdT = numSegments();

	Vec4d A;
	Vec4d dA; // First derivatives with respect to T.
	Vec4d ddA; // Second derivatives with respect to T.

	// Control point 0.
	{
		// u = (t - tdp.T0p) / (tdp.t0 - tdp.T0p)
		double const ta = 1.0 / (tdp.t0 - tdp.T0p);
		double const tb = -tdp.T0p * ta;
		double const u = ta * t + tb;		
		if (t <= tdp.T0p) {
			// u(t) = ta * tt + tb
			// u'(t) = ta
			// g(t) = g(u(t), <tension derived params>)
			GBlendFunc g(tdp.q[0], tdp.p[0]);
			A[0] = g.value(u);

			// g'(u(t(T))) = g'(u)*u'(t)*t'(T)
			dA[0] = g.firstDerivative(u) * (ta * dtdT);

			// Note that u'(t) and t'(T) are constant functions.
			// g"(u(t(T))) = g"(u)*u'(t)*t'(T)*u'(t)*t'(T)
			ddA[0] = g.secondDerivative(u) * (ta * dtdT) * (ta * dtdT);
		} else {
			HBlendFunc h(tdp.q[0]);
			A[0] = h.value(u);
			dA[0] = h.firstDerivative(u) * (ta * dtdT);
			ddA[0] = h.secondDerivative(u) * (ta * dtdT) * (ta * dtdT);
		}
	}

	// Control point 1.
	{
		// u = (t - tdp.T1p) / (tdp.t1 - tdp.T1p)
		double const ta = 1.0 / (tdp.t1 - tdp.T1p);
		double const tb = -tdp.T1p * ta;
		double const u = ta * t + tb;
		GBlendFunc g(tdp.q[1], tdp.p[1]);
		A[1] = g.value(u);
		dA[1] = g.firstDerivative(u) * (ta * dtdT);
		ddA[1] = g.secondDerivative(u) * (ta * dtdT) * (ta * dtdT);
	}

	// Control point 2.
	{
		// u = (t - tdp.T2m) / (tdp.t2 - tdp.T2m)
		double const ta = 1.0 / (tdp.t2 - tdp.T2m);
		double const tb = -tdp.T2m * ta;
		double const u = ta * t + tb;
		GBlendFunc g(tdp.q[2], tdp.p[2]);
		A[2] = g.value(u);
		dA[2] = g.firstDerivative(u) * (ta * dtdT);
		ddA[2] = g.secondDerivative(u) * (ta * dtdT) * (ta * dtdT);
	}

	// Control point 3.
	{
		// u = (t - tdp.T3m) / (tdp.t3 - tdp.T3m)
		double const ta = 1.0 / (tdp.t3 - tdp.T3m);
		double const tb = -tdp.T3m * ta;
		double const u = ta * t + tb;
		if (t >= tdp.T3m) {
			GBlendFunc g(tdp.q[3], tdp.p[3]);
			A[3] = g.value(u);
			dA[3] = g.firstDerivative(u) * (ta * dtdT);
			ddA[3] = g.secondDerivative(u) * (ta * dtdT) * (ta * dtdT);
		} else {
			HBlendFunc h(tdp.q[3]);
			A[3] = h.value(u);
			dA[3] = h.firstDerivative(u) * (ta * dtdT);
			ddA[3] = h.secondDerivative(u) * (ta * dtdT) * (ta * dtdT);
		}
	}
	
	double const sum = A.sum();
	double const sum2 = sum * sum;
	double const sum4 = sum2 * sum2;
	double const d_sum = dA.sum();
	double const dd_sum = ddA.sum();

	for (int i = 0; i < 4; ++i) {
		derivs.zeroDerivCoeffs[i] = A[i] / sum;
 
		double const d1 = dA[i] * sum - A[i] * d_sum;
		derivs.firstDerivCoeffs[i] = d1 / sum2; // Derivative of: A[i] / sum
		
		// Derivative of: dA[i] * sum
		double const dd1 = ddA[i] * sum + dA[i] * d_sum;

		// Derivative of: A[i] * d_sum
		double const dd2 = dA[i] * d_sum + A[i] * dd_sum;

		// Derivative of (dA[i] * sum - A[i] * d_sum) / sum2
		double const dd3 = ((dd1 - dd2) * sum2 - d1 * (2 * sum * d_sum)) / sum4;
		derivs.secondDerivCoeffs[i] = dd3;
	}

	// Merge / throw away some control points.
	int write_idx = 0;
	int merge_idx = 0;
	int read_idx = 1;
	int const end = 4;
	for (;;) {
		assert(merge_idx != read_idx);
		for (; read_idx != end && derivs.controlPoints[read_idx] == derivs.controlPoints[merge_idx]; ++read_idx) {
			// Merge
			derivs.zeroDerivCoeffs[merge_idx] += derivs.zeroDerivCoeffs[read_idx];
			derivs.firstDerivCoeffs[merge_idx] += derivs.firstDerivCoeffs[read_idx];
			derivs.secondDerivCoeffs[merge_idx] += derivs.secondDerivCoeffs[read_idx];
		}

		if (derivs.hasNonZeroCoeffs(merge_idx)) {
			// Copy
			derivs.zeroDerivCoeffs[write_idx] = derivs.zeroDerivCoeffs[merge_idx];
			derivs.firstDerivCoeffs[write_idx] = derivs.firstDerivCoeffs[merge_idx];
			derivs.secondDerivCoeffs[write_idx] = derivs.secondDerivCoeffs[merge_idx];
			derivs.controlPoints[write_idx] = derivs.controlPoints[merge_idx];
			++write_idx;
		}
		
		if (read_idx == end) {
			break;
		}

		merge_idx = read_idx;
		++read_idx;
	}
	derivs.numControlPoints = write_idx;

	return derivs;
}
Exemple #10
0
int main(void)
{
	try
	{
		using namespace oglplus;

		shapes::Sphere s(1.0, 3, 4);
		shapes::ShapeAnalyzer a(s);

		std::cout << "graph Shape {" << std::endl;

		std::cout << "\tsplines=true;" << std::endl;
		std::cout << "\tnode [shape=box];" << std::endl;

		auto tm =
			ModelMatrixd::Scale(5, 5, 5)*
			CamMatrixd::PerspectiveX(Angle<double>::Degrees(80), 1, 1, 20)*
			CamMatrixd::LookingAt(Vec3d(5, 5, 5), Vec3d());

		for(GLuint f=0; f!=a.FaceCount(); ++f)
		{
			auto face = a.Face(f);
			Vec4d v0 = face.Vert(0).MainAttrib();
			Vec4d v1 = face.Vert(1).MainAttrib();
			Vec4d v2 = face.Vert(2).MainAttrib();

			Vec4d v = tm*Vec4d((v0+v1+v2).xyz()/3.0, 1.0);
			std::cout
				<< "\tf" << f
				<< " [label=\"" << f << "\""
				<< ", pos=\"" << v.x() << "," << v.y() << "\""
				<< "];" << std::endl;
		}

		std::cout
			<< "\tnode ["
			<< "shape=circle,"
			<< "style=filled,"
			<< "fillcolor=\"#00FF00\""
			<< "];" << std::endl;
		for(GLuint f=0; f!=a.FaceCount(); ++f)
		{
			auto face = a.Face(f);
			for(GLuint e=0; e!=face.Arity(); ++e)
			{
				std::cout
					<< "\tf" << f
					<< "e" << e
					<< " [label=\"" << e
					<< "\"];" << std::endl;
				std::cout
					<< "\tf" << f
					<< " -- "
					<< "f" << f
					<< "e" << e
					<< ";" << std::endl;
			}
		}

		for(GLuint f=0; f!=a.FaceCount(); ++f)
		{
			auto face = a.Face(f);
			for(GLuint e=0; e!=face.Arity(); ++e)
			{
				auto edge = face.Edge(e);
				if(edge.HasAdjacentEdge())
				{
					auto adje = edge.AdjacentEdge();
					GLuint ae = adje.Index();
					GLuint af = adje.Face().Index();

					if(f < af)
					{
						std::cout
							<< "\tf" << f
							<< "e" << e
							<< " -- f" << af
							<< "e" << ae;
						if(edge.IsStripEdge())
						{
							std::cout << " [style=bold]";
						}
						else
						{
							std::cout << " [style=dotted]";
						}
						std::cout << std::endl;
					}
				}
			}
		}
		std::cout << "\toverlap=false;" << std::endl;
		std::cout << "}" << std::endl;

		return 0;
	}
	catch(oglplus::Error& err)
	{
		std::cerr
			<< "Error (in "
			<< err.GLFunc()
			<< "'): "
			<< err.what()
			<< " ["
			<< err.SourceFile()
			<< ":"
			<< err.SourceLine()
			<< "] "
			<< std::endl;
	}
	return 1;
}