Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • sw/simox/simox
  • uwkce_singer/simox
2 results
Show changes
Showing
with 0 additions and 6770 deletions
#ifndef _SAMPLE_DATA_H
#define _SAMPLE_DATA_H
struct SampleData {
SampleData() :
count (0), q(NULL), qdot(NULL), qddot(NULL), tau(NULL)
{}
~SampleData() {
deleteData();
}
SampleData(const SampleData &data) {
count = data.count;
q = new RigidBodyDynamics::Math::VectorNd[count];
qdot = new RigidBodyDynamics::Math::VectorNd[count];
qddot = new RigidBodyDynamics::Math::VectorNd[count];
tau = new RigidBodyDynamics::Math::VectorNd[count];
for (int si = 0; si < count; si++) {
q[si] = data.q[si];
qdot[si] = data.qdot[si];
qddot[si] = data.qddot[si];
tau[si] = data.tau[si];
}
}
SampleData& operator= (const SampleData &data) {
if (this != &data) {
deleteData();
*this = SampleData (data);
}
return *this;
}
unsigned int count;
RigidBodyDynamics::Math::VectorNd *q;
RigidBodyDynamics::Math::VectorNd *qdot;
RigidBodyDynamics::Math::VectorNd *qddot;
RigidBodyDynamics::Math::VectorNd *tau;
void deleteData() {
count = 0;
if (q)
delete[] q;
q = NULL;
if (qdot)
delete[] qdot;
qdot = NULL;
if (qddot)
delete[] qddot;
qddot = NULL;
if (tau)
delete[] tau;
tau = NULL;
}
void fillRandom (int dof_count, int sample_count) {
deleteData();
count = sample_count;
q = new RigidBodyDynamics::Math::VectorNd[count];
qdot = new RigidBodyDynamics::Math::VectorNd[count];
qddot = new RigidBodyDynamics::Math::VectorNd[count];
tau = new RigidBodyDynamics::Math::VectorNd[count];
for (int si = 0; si < count; si++) {
q[si].resize (dof_count);
qdot[si].resize (dof_count);
qddot[si].resize (dof_count);
tau[si].resize (dof_count);
for (int i = 0; i < dof_count; i++) {
q[si][i] = (static_cast<double>(rand()) / static_cast<double>(RAND_MAX)) * 2. -1.;
qdot[si][i] = (static_cast<double>(rand()) / static_cast<double>(RAND_MAX)) * 2. -1.;
qddot[si][i] = (static_cast<double>(rand()) / static_cast<double>(RAND_MAX)) * 2. -1.;
tau[si][i] = (static_cast<double>(rand()) / static_cast<double>(RAND_MAX)) * 2. -1.;
}
}
}
};
#endif
#ifndef _TIMER_H
#define _TIMER_H
#include <ctime>
struct TimerInfo {
/// time stamp when timer_start() gets called
clock_t clock_start_value;
/// time stamp when the timer was stopped
clock_t clock_end_value;
/// duration between clock_start_value and clock_end_value in seconds
double duration_sec;
};
inline void timer_start (TimerInfo *timer) {
timer->clock_start_value = clock();
}
inline double timer_stop (TimerInfo *timer) {
timer->clock_end_value = clock();
timer->duration_sec = static_cast<double>(timer->clock_end_value - timer->clock_start_value) * 1 / CLOCKS_PER_SEC;
return timer->duration_sec;
}
#endif
This diff is collapsed.
#include "model_generator.h"
#include "rbdl/rbdl.h"
using namespace RigidBodyDynamics;
using namespace RigidBodyDynamics::Math;
void generate_planar_tree_recursive (Model *model,
unsigned int parent_body_id,
int depth,
double length) {
if (depth == 0)
return;
// create left child
Joint joint_rot_z (JointTypeRevolute, Vector3d (0., 0., 1.));
Body body (length, Vector3d (0., -0.25 * length, 0.), Vector3d (length, length, length));
Vector3d displacement (-0.5 * length, -0.25 * length, 0.);
unsigned int child_left = model->AddBody (parent_body_id, Xtrans (displacement), joint_rot_z, body);
generate_planar_tree_recursive (model,
child_left,
depth - 1,
length * 0.4);
displacement.set (0.5 * length, -0.25 * length, 0.);
unsigned int child_right = model->AddBody (parent_body_id, Xtrans (displacement), joint_rot_z, body);
generate_planar_tree_recursive (model,
child_right,
depth - 1,
length * 0.4);
}
void generate_planar_tree (Model *model, int depth) {
// we first add a single body that is hanging straight down from
// (0, 0, 0). After that we generate the tree recursively such that each
// call adds two children.
//
double length = 1.;
Joint joint_rot_z (JointTypeRevolute, Vector3d (0., 0., 1.));
Body body (length, Vector3d (0., -0.25 * length, 0.), Vector3d (length, length, length));
unsigned int base_child = model->AddBody (0, Xtrans (Vector3d (0., 0., 0.)), joint_rot_z, body);
generate_planar_tree_recursive (
model,
base_child,
depth,
length * 0.4);
}
#ifndef _MODEL_GENERATOR_H
#define _MODEL_GENERATOR_H
namespace RigidBodyDynamics {
class Model;
}
void generate_planar_tree (RigidBodyDynamics::Model *model, int depth);
/* _MODEL_GENERATOR_H */
#endif
CMAKE_MINIMUM_REQUIRED(VERSION 3.0)
SET ( RBDL_ADDON_GEOMETRY_VERSION_MAJOR 1 )
SET ( RBDL_ADDON_GEOMETRY_VERSION_MINOR 0 )
SET ( RBDL_ADDON_GEOMETRY_VERSION_PATCH 0 )
SET ( RBDL_ADDON_GEOMETRY_VERSION
${RBDL_ADDON_GEOMETRY_VERSION_MAJOR}.${RBDL_ADDON_GEOMETRY_VERSION_MINOR}.${RBDL_ADDON_GEOMETRY_VERSION_PATCH}
)
PROJECT (RBDL_ADDON_GEOMETRY VERSION ${RBDL_ADDON_GEOMETRY_VERSION})
LIST( APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/CMake )
SET_TARGET_PROPERTIES ( ${PROJECT_EXECUTABLES} PROPERTIES
LINKER_LANGUAGE CXX
)
INCLUDE_DIRECTORIES (
${CMAKE_CURRENT_BINARY_DIR}/include/rbdl
)
SET(GEOMETRY_SOURCES
SegmentedQuinticBezierToolkit.cc
SmoothSegmentedFunction.cc
SegmentedQuinticBezierToolkit.h
SmoothSegmentedFunction.h
geometry.h
Function.h
)
SET(GEOMETRY_HEADERS
geometry.h
Function.h
SegmentedQuinticBezierToolkit.h
SmoothSegmentedFunction.h
)
IF (RBDL_BUILD_STATIC)
ADD_LIBRARY ( rbdl_geometry-static STATIC ${GEOMETRY_SOURCES} )
SET_TARGET_PROPERTIES ( rbdl_geometry-static PROPERTIES PREFIX "lib")
SET_TARGET_PROPERTIES ( rbdl_geometry-static PROPERTIES OUTPUT_NAME "rbdl_geometry")
TARGET_LINK_LIBRARIES (
rbdl_geometry-static
rbdl-static
)
INSTALL (TARGETS rbdl_geometry-static
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
)
ELSE (RBDL_BUILD_STATIC)
ADD_LIBRARY ( rbdl_geometry SHARED ${GEOMETRY_SOURCES} )
SET_TARGET_PROPERTIES ( rbdl_geometry PROPERTIES
VERSION ${RBDL_VERSION}
SOVERSION ${RBDL_SO_VERSION}
)
TARGET_LINK_LIBRARIES (
rbdl_geometry
rbdl
)
INSTALL (TARGETS rbdl_geometry
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
)
ENDIF (RBDL_BUILD_STATIC)
FILE ( GLOB headers
"${CMAKE_CURRENT_SOURCE_DIR}/*.h"
)
INSTALL ( FILES ${GEOMETRY_HEADERS}
DESTINATION
${CMAKE_INSTALL_INCLUDEDIR}/rbdl/addons/geometry
)
#ifndef SimTK_SimTKCOMMON_FUNCTION_H_
#define SimTK_SimTKCOMMON_FUNCTION_H_
/* -------------------------------------------------------------------------- *
* Simbody(tm): SimTKcommon *
* -------------------------------------------------------------------------- *
* This is part of the SimTK biosimulation toolkit originating from *
* Simbios, the NIH National Center for Physics-Based Simulation of *
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org/home/simbody. *
* *
* Portions copyright (c) 2008-12 Stanford University and the Authors. *
* Authors: Peter Eastman *
* Contributors: Michael Sherman *
* *
* Licensed under the Apache License, Version 2.0 (the "License"); you may *
* not use this file except in compliance with the License. You may obtain a *
* copy of the License at http://www.apache.org/licenses/LICENSE-2.0. *
* *
* Unless required by applicable law or agreed to in writing, software *
* distributed under the License is distributed on an "AS IS" BASIS, *
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
* See the License for the specific language governing permissions and *
* limitations under the License. *
* -------------------------------------------------------------------------- */
// Note: this file was moved from Simmath to SimTKcommon 20100601; see the
// Simmath repository for earlier history.
//#include "SimTKcommon/basics.h"
//#include "SimTKcommon/Simmatrix.h"
/*
Update:
This is a port of the original code so that it will work with
the multibody code RBDL written by Martin Felis.
Author:
Matthew Millard
Date:
Nov 2015
*/
#include <cassert>
#include <rbdl/rbdl_math.h>
#include <vector>
#include <cmath>
#include <cstdio>
/**
This abstract class represents a mathematical function that calculates a
value of arbitrary type based on M real arguments. The output type is set
as a template argument, while the number of input components may be
determined at runtime. The name "Function" (with no trailing _) may be
used as a synonym for Function_<double>.
Subclasses define particular mathematical functions. Predefined subclasses
are provided for several common function types: Function_<T>::Constant,
Function_<T>::Linear, Function_<T>::Polynomial, and Function_<T>::Step.
You can define your own subclasses for other function types. The
Spline_ class also provides a convenient way to create various types of
Functions.
*/
namespace RigidBodyDynamics {
namespace Addons {
namespace Geometry{
template <class T>
class Function_ {
public:
class Constant;
class Linear;
class Polynomial;
class Sinusoid;
class Step;
virtual ~Function_() {
}
/**
Calculate the value of this function at a particular point.
@param x the RigidBodyDynamics::Math::VectorNd of input arguments. Its
size must equal the value returned by getArgumentSize().
*/
virtual T calcValue(const RigidBodyDynamics::Math::VectorNd& x) const = 0;
/**
Calculate a partial derivative of this function at a particular point.
Which derivative to take is specified by listing the input components
with which to take it. For example, if derivComponents=={0}, that
indicates a first derivative with respective to component 0. If
derivComponents=={0, 0, 0}, that indicates a third derivative with
respective to component 0. If derivComponents=={4, 7}, that indicates a
partial second derivative with respect to components 4 and 7.
@param derivComponents
The input components with respect to which the derivative should be
taken. Its size must be less than or equal to the value returned
by getMaxDerivativeOrder().
@param x
The RigidBodyDynamics::Math::VectorNd of input arguments. Its size must
equal the value
returned by getArgumentSize().
@return
The value of the selected derivative, which is of type T.
*/
virtual T calcDerivative(const std::vector<int>& derivComponents,
const RigidBodyDynamics::Math::VectorNd& x) const = 0;
/** This provides compatibility with std::vector without requiring any
copying. **/
/*
T calcDerivative(const std::vector<int>& derivComponents,
const RigidBodyDynamics::Math::VectorNd& x) const
{ return calcDerivative(std::vector<int>(derivComponents),x); }
*/
/**
* Get the number of components expected in the input vector.
*/
virtual int getArgumentSize() const = 0;
/**
* Get the maximum derivative order this Function_ object can calculate.
*/
virtual int getMaxDerivativeOrder() const = 0;
};
/** This typedef is used for the very common case that the return type of
the Function object is double. **/
typedef Function_<double> Function;
/**
* This is a Function_ subclass which simply returns a fixed value, independent
* of its arguments.
*/
template <class T>
class Function_<T>::Constant : public Function_<T> {
public:
/**
* Create a Function_::Constant object.
*
* @param value the value which should be returned by calcValue();
* @param argumentSize the value which should be returned by
* getArgumentSize(), with a default of 1.
*/
explicit Constant(T value, int argumentSize=1)
: argumentSize(argumentSize), value(value) {
}
T calcValue(const RigidBodyDynamics::Math::VectorNd& x) const {
assert(x.size() == argumentSize);
return value;
}
T calcDerivative(const std::vector<int>& derivComponents,
const RigidBodyDynamics::Math::VectorNd& x) const {
return static_cast<T>(0);
}
virtual int getArgumentSize() const {
return argumentSize;
}
int getMaxDerivativeOrder() const {
return std::numeric_limits<int>::max();
}
/** This provides compatibility with std::vector without requiring any
copying. **/
/*
T calcDerivative(const std::vector<int>& derivComponents,
const RigidBodyDynamics::Math::VectorNd& x) const
{ return calcDerivative(std::vector<int>(derivComponents),x); }
*/
private:
const int argumentSize;
const T value;
};
/**
* This is a Function_ subclass whose output value is a linear function of its
* arguments: f(x, y, ...) = ax+by+...+c.
*/
template <class T>
class Function_<T>::Linear : public Function_<T> {
public:
/**
* Create a Function_::Linear object.
*
* @param coefficients
* The coefficients of the linear function. The number of arguments
* expected by the function is equal to coefficients.size()-1.
* coefficients[0] is the coefficient for the first argument,
* coefficients[1] is the coefficient for the second argument, etc.
* The final element of coefficients contains the constant term.
*/
explicit Linear(
const RigidBodyDynamics::Math::VectorNd& coefficients)
: coefficients(coefficients) {
}
T calcValue(const RigidBodyDynamics::Math::VectorNd& x) const {
assert(x.size() == coefficients.size()-1);
T value = static_cast<T>(0);
for (int i = 0; i < x.size(); ++i)
value += x[i]*coefficients[i];
value += coefficients[x.size()];
return value;
}
T calcDerivative(const std::vector<int>& derivComponents,
const RigidBodyDynamics::Math::VectorNd& x) const {
assert(x.size() == coefficients.size()-1);
assert(derivComponents.size() > 0);
if (derivComponents.size() == 1)
return coefficients(derivComponents[0]);
return static_cast<T>(0);
}
virtual int getArgumentSize() const {
return coefficients.size()-1;
}
int getMaxDerivativeOrder() const {
return std::numeric_limits<int>::max();
}
/** This provides compatibility with std::vector without requiring any
copying. **/
/*
T calcDerivative(const std::vector<int>& derivComponents,
const RigidBodyDynamics::Math::VectorNd& x) const
{ return calcDerivative(ArrayViewConst_<int>(derivComponents),x); }
*/
private:
const RigidBodyDynamics::Math::VectorNd coefficients;
};
/**
* This is a Function_ subclass whose output value is a polynomial of its
* argument: f(x) = ax^n+bx^(n-1)+...+c.
*/
template <class T>
class Function_<T>::Polynomial : public Function_<T> {
public:
/**
* Create a Function_::Polynomial object.
*
* @param coefficients the polynomial coefficients in order of decreasing
* powers
*/
Polynomial(const RigidBodyDynamics::Math::VectorNd& coefficients)
: coefficients(coefficients) {
}
T calcValue(const RigidBodyDynamics::Math::VectorNd& x) const {
assert(x.size() == 1);
double arg = x[0];
T value = static_cast<T>(0);
for (int i = 0; i < coefficients.size(); ++i)
value = value*arg + coefficients[i];
return value;
}
T calcDerivative(const std::vector<int>& derivComponents,
const RigidBodyDynamics::Math::VectorNd& x) const {
assert(x.size() == 1);
assert(derivComponents.size() > 0);
double arg = x[0];
T value = static_cast<T>(0);
const int derivOrder = (int)derivComponents.size();
const int polyOrder = coefficients.size()-1;
for (int i = 0; i <= polyOrder-derivOrder; ++i) {
T coeff = coefficients[i];
for (int j = 0; j < derivOrder; ++j)
coeff *= polyOrder-i-j;
value = value*arg + coeff;
}
return value;
}
virtual int getArgumentSize() const {
return 1;
}
int getMaxDerivativeOrder() const {
return std::numeric_limits<int>::max();
}
/** This provides compatibility with std::vector without requiring any
copying. **/
/*
T calcDerivative(const std::vector<int>& derivComponents,
const RigidBodyDynamics::Math::VectorNd& x) const
{ return calcDerivative(ArrayViewConst_<int>(derivComponents),x); }
*/
private:
const RigidBodyDynamics::Math::VectorNd coefficients;
};
/**
* This is a Function_ subclass whose output value is a sinusoid of its
* argument: f(x) = a*sin(w*x + p) where a is amplitude, w is frequency
* in radians per unit of x, p is phase in radians.
*
* This is only defined for a scalar (double) return value.
*/
template <>
class Function_<double>::Sinusoid : public Function_<double> {
public:
/**
* Create a Function::Sinusoid object, returning a*sin(w*x+p).
*
* @param[in] amplitude 'a' in the above formula
* @param[in] frequency 'w' in the above formula
* @param[in] phase 'p' in the above formula
*/
Sinusoid(double amplitude, double frequency, double phase=0)
: a(amplitude), w(frequency), p(phase) {}
void setAmplitude(double amplitude) {a=amplitude;}
void setFrequency(double frequency) {w=frequency;}
void setPhase (double phase) {p=phase;}
double getAmplitude() const {return a;}
double getFrequency() const {return w;}
double getPhase () const {return p;}
// Implementation of Function_<T> virtuals.
virtual double calcValue(
const RigidBodyDynamics::Math::VectorNd& x) const {
const double t = x[0]; // we expect just one argument
return a*std::sin(w*t + p);
}
virtual double calcDerivative(
const std::vector<int>& derivComponents,
const RigidBodyDynamics::Math::VectorNd& x) const {
const double t = x[0]; // time is the only argument
const int order = derivComponents.size();
// The n'th derivative is
// sign * a * w^n * sc
// where sign is -1 if floor(order/2) is odd, else 1
// and sc is cos(w*t+p) if order is odd, else sin(w*t+p)
switch(order) {
case 0: return a* std::sin(w*t + p);
case 1: return a*w* std::cos(w*t + p);
case 2: return -a*w*w* std::sin(w*t + p);
case 3: return -a*w*w*w*std::cos(w*t + p);
default:
const double sign = double(((order/2) & 0x1) ? -1 : 1);
const double sc = (order & 0x1) ? std::cos(w*t+p) : std::sin(w*t+p);
const double wn = std::pow(w, order);
return sign*a*wn*sc;
}
}
virtual int getArgumentSize() const {return 1;} // just time
virtual int getMaxDerivativeOrder() const {
return std::numeric_limits<int>::max();
}
/** This provides compatibility with std::vector without requiring any
copying. **/
/*
double calcDerivative(const std::vector<int>& derivComponents,
const RigidBodyDynamics::Math::VectorNd& x) const
{ return calcDerivative(ArrayViewConst_<int>(derivComponents),x); }
*/
private:
double a, w, p;
};
/**
* This is a Function_ subclass whose output value y=f(x) is smoothly stepped
* from y=y0 to y1 as its input argument goes from x=x0 to x1. This is
* an S-shaped function with first and second derivatives y'(x0)=y'(x1)=0
* and y''(x0)=y''(x1)==0. The third derivative y''' exists and is continuous
* but we cannot guarantee anything about it at the end points.
*/
template <class T>
class Function_<T>::Step : public Function_<T> {
public:
/**
* Create a Function_::Step object that smoothly interpolates its output
* through a given range as its input moves through its range.
*
* @param y0 Output value when (x-x0)*sign(x1-x0) <= 0.
* @param y1 Output value when (x-x1)*sign(x1-x0) >= 0.
* @param x0 Start of switching interval.
* @param x1 End of switching interval.
*
* @tparam T The template type is the type of y0 and y1. This must
* be a type that supports subtraction and scalar
* multiplication by a double so that we can compute
* an expression like y=y0 + f*(y1-y0) for some double scalar f.
*
* Note that the numerical values of x0 and x1 can be in either order
* x0 < x1 or x0 > x1.
*/
Step(const T& y0, const T& y1, double x0, double x1)
: m_y0(y0), m_y1(y1), m_yr(y1-y0), m_zero(double(0)*y0),
m_x0(x0), m_x1(x1), m_ooxr(1/(x1-x0)), m_sign(copysign(1,m_ooxr))
{
/*
SimTK_ERRCHK1_ALWAYS(x0 != x1, "Function_<T>::Step::ctor()",
"A zero-length switching interval is illegal; both ends were %g.", x0);
*/
assert(x0 != x1);
std::printf( "Function_<T>::Step::ctor():"
"A zero-length switching interval "
"is illegal; both ends were %g.", x0);
}
T calcValue(const RigidBodyDynamics::Math::VectorNd& xin) const {
/*
SimTK_ERRCHK1_ALWAYS(xin.size() == 1,
"Function_<T>::Step::calcValue()",
"Expected just one input argument but got %d.", xin.size());
*/
assert(xin.size() == 1);
std::printf( "Function_<T>::Step::calcValue() "
"Expected just one input argument but got %d.",
xin.size());
const double x = xin[0];
if ((x-m_x0)*m_sign <= 0) return m_y0;
if ((x-m_x1)*m_sign >= 0) return m_y1;
// f goes from 0 to 1 as x goes from x0 to x1.
const double f = step01(m_x0,m_ooxr, x);
return m_y0 + f*m_yr;
}
T calcDerivative(const std::vector<int>& derivComponents,
const RigidBodyDynamics::Math::VectorNd& xin) const {
/*
SimTK_ERRCHK1_ALWAYS(xin.size() == 1,
"Function_<T>::Step::calcDerivative()",
"Expected just one input argument but got %d.", xin.size());
*/
assert(xin.size() == 1);
std::printf( "Function_<T>::Step::calcDerivative() "
"Expected just one input argument but got %d.",
xin.size());
const int derivOrder = (int)derivComponents.size();
/*
SimTK_ERRCHK1_ALWAYS(1 <= derivOrder && derivOrder <= 3,
"Function_<T>::Step::calcDerivative()",
"Only 1st, 2nd, and 3rd derivatives of the step are available,"
" but derivative %d was requested.", derivOrder);
*/
assert(1 <= derivOrder && derivOrder <= 3);
std::printf("Function_<T>::Step::calcDerivative() "
"Only 1st, 2nd, and 3rd derivatives of the step are available,"
" but derivative %d was requested.", derivOrder);
const double x = xin[0];
if ((x-m_x0)*m_sign <= 0) return m_zero;
if ((x-m_x1)*m_sign >= 0) return m_zero;
switch(derivOrder) {
case 1: return dstep01(m_x0,m_ooxr, x) * m_yr;
case 2: return d2step01(m_x0,m_ooxr, x) * m_yr;
case 3: return d3step01(m_x0,m_ooxr, x) * m_yr;
default: assert(!"impossible derivOrder");
}
return NAN*m_yr; /*NOTREACHED*/
}
virtual int getArgumentSize() const {return 1;}
int getMaxDerivativeOrder() const {return 3;}
/** This provides compatibility with std::vector without requiring any
copying. **/
/*
T calcDerivative(const std::vector<int>& derivComponents,
const RigidBodyDynamics::Math::VectorNd& x) const
{ return calcDerivative(ArrayViewConst_<int>(derivComponents),x); }
*/
private:
const T m_y0, m_y1, m_yr; // precalculate yr=(y1-y0)
const T m_zero; // precalculate T(0)
const double m_x0, m_x1, m_ooxr; // precalculate ooxr=1/(x1-x0)
const double m_sign; // sign(x1-x0) is 1 or -1
double step01(double x0, double x1, double x){
double u = (x-x0)/(x1-x0);
double u2 = u*u;
double u3 = u2*u;
return (3*u2 - 2*u3);
}
double dstep01(double x0, double x1, double x){
double u = (x-x0)/(x1-x0);
double du = (1)/(x1-x0);
double du2 = 2*u*du;
double du3 = 3*u*u*du;
return (3*du2 - 2*du3);
}
double d2step01(double x0, double x1, double x){
double u = (x-x0)/(x1-x0);
double du = (1)/(x1-x0);
//double ddu = 0;
double ddu2 = 2*du*du;// + 2*u*ddu since ddu=0;
double ddu3 = 3*du*u*du + 3*u*du*du;// + 3*u*u*du; ditto
return (3*ddu2 - 2*ddu3);
}
double d3step01(double x0, double x1, double x){
double u = (x-x0)/(x1-x0);
double du = (1)/(x1-x0);
//double ddu = 0;
//double dddu = 0;
double dddu2 = 0; //2*du*du;// since ddu=0;
double dddu3 = 3*du*du*du + 3*du*du*du;// ditto
return (3*dddu2 - 2*dddu3);
}
};
}
}
}
#endif // SimTK_SimTKCOMMON_FUNCTION_H_
Rigid Body Dynamics Library Geometry Addon -
Copyright (c) 2016 Matthew Millard <matthew.millard@iwr.uni-heidelberg.de>
(zlib license)
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.