📄 cubicsplinesegment.java
字号:
ds_pos.z = dsab * deltaP.z; // Scale ds_scale.x = dsab * deltaS.x; ds_scale.y = dsab * deltaS.y; ds_scale.z = dsab * deltaS.z; } else { float adj1 = (kf2.knot - kf1.knot)/(kf3.knot - kf1.knot); // Position ds_pos.x = adj1 * ((dsb * (kf3.position.x - kf2.position.x)) + (dsa * deltaP.x)); ds_pos.y = adj1 * ((dsb * (kf3.position.y - kf2.position.y)) + (dsa * deltaP.y)); ds_pos.z = adj1 * ((dsb * (kf3.position.z - kf2.position.z)) + (dsa * deltaP.z)); // Scale ds_scale.x = adj1 * ((dsb * (kf3.scale.x - kf2.scale.x)) + (dsa * deltaS.x)); ds_scale.y = adj1 * ((dsb * (kf3.scale.y - kf2.scale.y)) + (dsa * deltaS.y)); ds_scale.z = adj1 * ((dsb * (kf3.scale.z - kf2.scale.z)) + (dsa * deltaS.z)); } // Calculate the coefficients of the polynomial for position c0 = new Point3f(); c0.x = kf1.position.x; c0.y = kf1.position.y; c0.z = kf1.position.z; c1 = new Point3f(); c1.x = dd_pos.x; c1.y = dd_pos.y; c1.z = dd_pos.z; c2 = new Point3f(); c2.x = 3*deltaP.x - 2*dd_pos.x - ds_pos.x; c2.y = 3*deltaP.y - 2*dd_pos.y - ds_pos.y; c2.z = 3*deltaP.z - 2*dd_pos.z - ds_pos.z; c3 = new Point3f(); c3.x = -2*deltaP.x + dd_pos.x + ds_pos.x; c3.y = -2*deltaP.y + dd_pos.y + ds_pos.y; c3.z = -2*deltaP.z + dd_pos.z + ds_pos.z; // Calculate the coefficients of the polynomial for scale e0 = new Point3f(); e0.x = kf1.scale.x; e0.y = kf1.scale.y; e0.z = kf1.scale.z; e1 = new Point3f(); e1.x = dd_scale.x; e1.y = dd_scale.y; e1.z = dd_scale.z; e2 = new Point3f(); e2.x = 3*deltaS.x - 2*dd_scale.x - ds_scale.x; e2.y = 3*deltaS.y - 2*dd_scale.y - ds_scale.y; e2.z = 3*deltaS.z - 2*dd_scale.z - ds_scale.z; e3 = new Point3f(); e3.x = -2*deltaS.x + dd_scale.x + ds_scale.x; e3.y = -2*deltaS.y + dd_scale.y + ds_scale.y; e3.z = -2*deltaS.z + dd_scale.z + ds_scale.z; } /** * Computes the length of the curve at a given point between * key frames. * @param u specifies the point between keyframes where 0 <= u <= 1. */ public float computeLength (float u) { float result = 0f; // if linear interpolation if (linear == 1) { result = u*keyFrame[2].position.distance(keyFrame[1].position); } else { // Need to transform domain [0,u] to [-1,1]. If 0 <= x <= u // and -1 <= t <= 1, then x = u*(t+1)/2. int degree = 5; for (int i = 0; i < degree; i++) result += (float)modCoeff[i]*computeSpeed(u*(float)modRoot[i]); result *= u; } return result; } // Velocity along curve private float computeSpeed (float u) { Point3f v = new Point3f(); v.x = c1.x + u * (2 * c2.x + 3 * u * c3.x); v.y = c1.y + u * (2 * c2.y + 3 * u * c3.y); v.z = c1.z + u * (2 * c2.z + 3 * u * c3.z); return (float)(Math.sqrt(v.x*v.x + v.y*v.y + v.z*v.z)); } /** * Computes the interpolated quaternion along the curve at * a given point between key frames. This routine uses linear * interpolation if the (i+1)<sup>th</sup> key frame's linear * value is equal to 1. * * @param u specifies the point between keyframes where 0 <= u <= 1. * @param newQuat returns the value of the interpolated quaternion */ public void getInterpolatedQuaternion (float u, Quat4f newQuat) { // if linear interpolation if (this.linear == 1) { double quatDot; quatDot = keyFrame[1].quat.x * keyFrame[2].quat.x + keyFrame[1].quat.y * keyFrame[2].quat.y + keyFrame[1].quat.z * keyFrame[2].quat.z + keyFrame[1].quat.w * keyFrame[2].quat.w; if (quatDot < 0) { newQuat.x = keyFrame[1].quat.x + (-keyFrame[2].quat.x - keyFrame[1].quat.x) * u; newQuat.y = keyFrame[1].quat.y + (-keyFrame[2].quat.y - keyFrame[1].quat.y) * u; newQuat.z = keyFrame[1].quat.z + (-keyFrame[2].quat.z - keyFrame[1].quat.z) * u; newQuat.w = keyFrame[1].quat.w + (-keyFrame[2].quat.w - keyFrame[1].quat.w) * u; } else { newQuat.x = keyFrame[1].quat.x + (keyFrame[2].quat.x - keyFrame[1].quat.x) * u; newQuat.y = keyFrame[1].quat.y + (keyFrame[2].quat.y - keyFrame[1].quat.y) * u; newQuat.z = keyFrame[1].quat.z + (keyFrame[2].quat.z - keyFrame[1].quat.z) * u; newQuat.w = keyFrame[1].quat.w + (keyFrame[2].quat.w - keyFrame[1].quat.w) * u; } } else { // TODO: // Currently we just use the great circle spherical interpolation // for quaternions irrespective of the linear flag. Eventually // we might want to do cubic interpolation of quaternions newQuat.interpolate (keyFrame[1].quat, keyFrame[2].quat, u); } } /** * Computes the interpolated scale along the curve at a given point * between key frames and returns a Point3f with the interpolated * x, y, and z scale components. This routine uses linear * interpolation if the (i+1)<sup>th</sup> key frame's linear * value is equal to 1. * * @param u specifies the point between keyframes where 0 <= u <= 1. * @param newScale returns the interpolated x,y,z scale value in a Point3f */ public void getInterpolatedScale (float u, Point3f newScale) { // if linear interpolation if (this.linear == 1) { newScale.x = keyFrame[1].scale.x + ((keyFrame[2].scale.x - keyFrame[1].scale.x) * u); newScale.y = keyFrame[1].scale.y + ((keyFrame[2].scale.y - keyFrame[1].scale.y) * u); newScale.z = keyFrame[1].scale.z + ((keyFrame[2].scale.z - keyFrame[1].scale.z) * u); } else { newScale.x = e0.x + u * (e1.x + u * (e2.x + u * e3.x)); newScale.y = e0.y + u * (e1.y + u * (e2.y + u * e3.y)); newScale.z = e0.z + u * (e1.z + u * (e2.z + u * e3.z)); } } /** * Computes the interpolated position along the curve at a given point * between key frames and returns a Point3f with the interpolated * x, y, and z scale components. This routine uses linear * interpolation if the (i+1)<sup>th</sup> key frame's linear * value is equal to 1. * * @param u specifies the point between keyframes where 0 <= u <= 1. * @param newPos returns the interpolated x,y,z position in a Point3f */ public void getInterpolatedPosition (float u, Point3f newPos) { // if linear interpolation if (this.linear == 1) { newPos.x = keyFrame[1].position.x + ((keyFrame[2].position.x - keyFrame[1].position.x) * u); newPos.y = keyFrame[1].position.y + ((keyFrame[2].position.y - keyFrame[1].position.y) * u); newPos.z = keyFrame[1].position.z + ((keyFrame[2].position.z - keyFrame[1].position.z) * u); } else { newPos.x = c0.x + u * (c1.x + u * (c2.x + u * c3.x)); newPos.y = c0.y + u * (c1.y + u * (c2.y + u * c3.y)); newPos.z = c0.z + u * (c1.z + u * (c2.z + u * c3.z)); } } /** * Computes the interpolated position along the curve at a given point * between key frames and returns a Vector3f with the interpolated * x, y, and z scale components. This routine uses linear * interpolation if the (i+1)<sup>th</sup> key frame's linear * value is equal to 1. * * @param u specifies the point between keyframes where 0 <= u <= 1. * @param newPos returns the interpolated x,y,z position in a Vector3f. */ public void getInterpolatedPositionVector (float u, Vector3f newPos) { // if linear interpolation if (this.linear == 1) { newPos.x = keyFrame[1].position.x + ((keyFrame[2].position.x - keyFrame[1].position.x) * u); newPos.y = keyFrame[1].position.y + ((keyFrame[2].position.y - keyFrame[1].position.y) * u); newPos.z = keyFrame[1].position.z + ((keyFrame[2].position.z - keyFrame[1].position.z) * u); } else { newPos.x = c0.x + u * (c1.x + u * (c2.x + u * c3.x)); newPos.y = c0.y + u * (c1.y + u * (c2.y + u * c3.y)); newPos.z = c0.z + u * (c1.z + u * (c2.z + u * c3.z)); } } /** * Computes the ratio of the length of the spline from the i<sup>th</sup> * key frame to the position specified by u to the length of the entire * spline segment from the i<sup>th</sup> key frame to the (i+1) * <sup>th</sup> key frame. When the (i+1)<sup>th</sup> key frame's linear * value is equal to 1, this is meaninful otherwise it should return u. * * @param u specifies the point between keyframes where 0 <= u <= 1. * @return the interpolated ratio */ public float getInterpolatedValue (float u) { return (computeLength(u)/this.length); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -