molstar
Version:
A comprehensive macromolecular library.
203 lines • 11.3 kB
JavaScript
"use strict";
/**
* Copyright (c) 2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author Ludovic Autin <autin@scripps.edu>
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.getMatFromResamplePoints = void 0;
var linear_algebra_1 = require("../../mol-math/linear-algebra");
var a0Tmp = (0, linear_algebra_1.Vec3)();
var a1Tmp = (0, linear_algebra_1.Vec3)();
var a2Tmp = (0, linear_algebra_1.Vec3)();
var a3Tmp = (0, linear_algebra_1.Vec3)();
function CubicInterpolate(out, y0, y1, y2, y3, mu) {
var mu2 = mu * mu;
linear_algebra_1.Vec3.sub(a0Tmp, y3, y2);
linear_algebra_1.Vec3.sub(a0Tmp, a0Tmp, y0);
linear_algebra_1.Vec3.add(a0Tmp, a0Tmp, y1);
linear_algebra_1.Vec3.sub(a1Tmp, y0, y1);
linear_algebra_1.Vec3.sub(a1Tmp, a1Tmp, a0Tmp);
linear_algebra_1.Vec3.sub(a2Tmp, y2, y0);
linear_algebra_1.Vec3.copy(a3Tmp, y1);
out[0] = a0Tmp[0] * mu * mu2 + a1Tmp[0] * mu2 + a2Tmp[0] * mu + a3Tmp[0];
out[1] = a0Tmp[1] * mu * mu2 + a1Tmp[1] * mu2 + a2Tmp[1] * mu + a3Tmp[1];
out[2] = a0Tmp[2] * mu * mu2 + a1Tmp[2] * mu2 + a2Tmp[2] * mu + a3Tmp[2];
return out;
}
var cp0 = (0, linear_algebra_1.Vec3)();
var cp1 = (0, linear_algebra_1.Vec3)();
var cp2 = (0, linear_algebra_1.Vec3)();
var cp3 = (0, linear_algebra_1.Vec3)();
var currentPosition = (0, linear_algebra_1.Vec3)();
function ResampleControlPoints(points, segmentLength) {
var nP = points.length / 3;
// insert a point at the end and at the begining
// controlPoints.Insert(0, controlPoints[0] + (controlPoints[0] - controlPoints[1]) / 2.0f);
// controlPoints.Add(controlPoints[nP - 1] + (controlPoints[nP - 1] - controlPoints[nP - 2]) / 2.0f);
var resampledControlPoints = [];
// resampledControlPoints.Add(controlPoints[0]);
// resampledControlPoints.Add(controlPoints[1]);
var idx = 1;
// const currentPosition = Vec3.create(points[idx * 3], points[idx * 3 + 1], points[idx * 3 + 2])
linear_algebra_1.Vec3.fromArray(currentPosition, points, idx * 3);
var lerpValue = 0.0;
// Normalize the distance between control points
while (true) {
if (idx + 2 >= nP)
break;
linear_algebra_1.Vec3.fromArray(cp0, points, (idx - 1) * 3);
linear_algebra_1.Vec3.fromArray(cp1, points, idx * 3);
linear_algebra_1.Vec3.fromArray(cp2, points, (idx + 1) * 3);
linear_algebra_1.Vec3.fromArray(cp3, points, (idx + 2) * 3);
// const cp0 = Vec3.create(points[(idx-1)*3], points[(idx-1)*3+1], points[(idx-1)*3+2]) // controlPoints[currentPointId - 1];
// const cp1 = Vec3.create(points[idx*3], points[idx*3+1], points[idx*3+2]) // controlPoints[currentPointId];
// const cp2 = Vec3.create(points[(idx+1)*3], points[(idx+1)*3+1], points[(idx+1)*3+2]) // controlPoints[currentPointId + 1];
// const cp3 = Vec3.create(points[(idx+2)*3], points[(idx+2)*3+1], points[(idx+2)*3+2]); // controlPoints[currentPointId + 2];
var found = false;
for (; lerpValue <= 1; lerpValue += 0.01) {
// lerp?slerp
// let candidate:Vec3 = Vec3.lerp(Vec3.zero(), cp0, cp1, lerpValue);
// const candidate:Vec3 = Vec3.bezier(Vec3.zero(), cp0, cp1, cp2, cp3, lerpValue);
var candidate = CubicInterpolate((0, linear_algebra_1.Vec3)(), cp0, cp1, cp2, cp3, lerpValue);
var d = linear_algebra_1.Vec3.distance(currentPosition, candidate);
if (d > segmentLength) {
resampledControlPoints.push(candidate);
linear_algebra_1.Vec3.copy(currentPosition, candidate);
found = true;
break;
}
}
if (!found) {
lerpValue = 0;
idx += 1;
}
}
return resampledControlPoints;
}
var prevV = (0, linear_algebra_1.Vec3)();
var tmpV1 = (0, linear_algebra_1.Vec3)();
var tmpV2 = (0, linear_algebra_1.Vec3)();
var tmpV3 = (0, linear_algebra_1.Vec3)();
// easier to align to theses normals
function GetSmoothNormals(points) {
var nP = points.length;
var smoothNormals = [];
if (points.length < 3) {
for (var i = 0; i < points.length; ++i)
smoothNormals.push(linear_algebra_1.Vec3.normalize((0, linear_algebra_1.Vec3)(), points[i]));
return smoothNormals;
}
var p0 = points[0];
var p1 = points[1];
var p2 = points[2];
var p21 = linear_algebra_1.Vec3.sub(tmpV1, p2, p1);
var p01 = linear_algebra_1.Vec3.sub(tmpV2, p0, p1);
var p0121 = linear_algebra_1.Vec3.cross(tmpV3, p01, p21);
linear_algebra_1.Vec3.normalize(prevV, p0121);
smoothNormals.push(linear_algebra_1.Vec3.clone(prevV));
for (var i = 1; i < points.length - 1; ++i) {
p0 = points[i - 1];
p1 = points[i];
p2 = points[i + 1];
var t = linear_algebra_1.Vec3.normalize(tmpV1, linear_algebra_1.Vec3.sub(tmpV1, p2, p0));
var b = linear_algebra_1.Vec3.normalize(tmpV2, linear_algebra_1.Vec3.cross(tmpV2, t, prevV));
var n = linear_algebra_1.Vec3.normalize((0, linear_algebra_1.Vec3)(), linear_algebra_1.Vec3.cross(tmpV3, t, b));
linear_algebra_1.Vec3.negate(n, n);
linear_algebra_1.Vec3.copy(prevV, n);
smoothNormals.push(n);
}
var last = (0, linear_algebra_1.Vec3)();
linear_algebra_1.Vec3.normalize(last, linear_algebra_1.Vec3.cross(last, linear_algebra_1.Vec3.sub(tmpV1, points[nP - 3], points[nP - 2]), linear_algebra_1.Vec3.sub(tmpV2, points[nP - 2], points[nP - 1])));
smoothNormals.push(last);
return smoothNormals;
}
var frameTmpV1 = (0, linear_algebra_1.Vec3)();
var frameTmpV2 = (0, linear_algebra_1.Vec3)();
var frameTmpV3 = (0, linear_algebra_1.Vec3)();
function getFrame(reference, tangent) {
var t = linear_algebra_1.Vec3.normalize((0, linear_algebra_1.Vec3)(), tangent);
// make reference vector orthogonal to tangent
var proj_r_to_t = linear_algebra_1.Vec3.scale(frameTmpV1, tangent, linear_algebra_1.Vec3.dot(reference, tangent) / linear_algebra_1.Vec3.dot(tangent, tangent));
var r = linear_algebra_1.Vec3.normalize((0, linear_algebra_1.Vec3)(), linear_algebra_1.Vec3.sub(frameTmpV2, reference, proj_r_to_t));
// make bitangent vector orthogonal to the others
var s = linear_algebra_1.Vec3.normalize((0, linear_algebra_1.Vec3)(), linear_algebra_1.Vec3.cross(frameTmpV3, t, r));
return { t: t, r: r, s: s };
}
var mfTmpV1 = (0, linear_algebra_1.Vec3)();
var mfTmpV2 = (0, linear_algebra_1.Vec3)();
var mfTmpV3 = (0, linear_algebra_1.Vec3)();
var mfTmpV4 = (0, linear_algebra_1.Vec3)();
var mfTmpV5 = (0, linear_algebra_1.Vec3)();
var mfTmpV6 = (0, linear_algebra_1.Vec3)();
var mfTmpV7 = (0, linear_algebra_1.Vec3)();
var mfTmpV8 = (0, linear_algebra_1.Vec3)();
var mfTmpV9 = (0, linear_algebra_1.Vec3)();
// easier to align to theses normals
// https://github.com/bzamecnik/gpg/blob/master/rotation-minimizing-frame/rmf.py
function GetMiniFrame(points, normals) {
var frames = [];
var t0 = linear_algebra_1.Vec3.normalize(mfTmpV1, linear_algebra_1.Vec3.sub(mfTmpV1, points[1], points[0]));
frames.push(getFrame(normals[0], t0));
for (var i = 0; i < points.length - 2; ++i) {
var t2 = linear_algebra_1.Vec3.normalize(mfTmpV1, linear_algebra_1.Vec3.sub(mfTmpV1, points[i + 2], points[i + 1]));
var v1 = linear_algebra_1.Vec3.sub(mfTmpV2, points[i + 1], points[i]); // this is tangeant
var c1 = linear_algebra_1.Vec3.dot(v1, v1);
// compute r_i^L = R_1 * r_i
var v1r = linear_algebra_1.Vec3.scale(mfTmpV3, v1, (2.0 / c1) * linear_algebra_1.Vec3.dot(v1, frames[i].r));
var ref_L_i = linear_algebra_1.Vec3.sub(mfTmpV4, frames[i].r, v1r);
// compute t_i^L = R_1 * t_i
var v1t = linear_algebra_1.Vec3.scale(mfTmpV5, v1, (2.0 / c1) * linear_algebra_1.Vec3.dot(v1, frames[i].t));
var tan_L_i = linear_algebra_1.Vec3.sub(mfTmpV6, frames[i].t, v1t);
// # compute reflection vector of R_2
var v2 = linear_algebra_1.Vec3.sub(mfTmpV7, t2, tan_L_i);
var c2 = linear_algebra_1.Vec3.dot(v2, v2);
// compute r_(i+1) = R_2 * r_i^L
var v2l = linear_algebra_1.Vec3.scale(mfTmpV8, v1, (2.0 / c2) * linear_algebra_1.Vec3.dot(v2, ref_L_i));
var ref_next = linear_algebra_1.Vec3.sub(mfTmpV9, ref_L_i, v2l); // ref_L_i - (2 / c2) * v2.dot(ref_L_i) * v2
frames.push(getFrame(ref_next, t2)); // frames.append(Frame(ref_next, tangents[i+1]))
}
return frames;
}
var rpTmpVec1 = (0, linear_algebra_1.Vec3)();
function getMatFromResamplePoints(points, segmentLength, resample) {
var new_points = [];
if (resample)
new_points = ResampleControlPoints(points, segmentLength);
else {
for (var idx = 0; idx < points.length / 3; ++idx) {
new_points.push(linear_algebra_1.Vec3.fromArray(linear_algebra_1.Vec3.zero(), points, idx * 3));
}
}
var npoints = new_points.length;
var new_normal = GetSmoothNormals(new_points);
var frames = GetMiniFrame(new_points, new_normal);
var limit = npoints;
var transforms = [];
var pti = linear_algebra_1.Vec3.copy(rpTmpVec1, new_points[0]);
for (var i = 0; i < npoints - 2; ++i) {
var pti1 = new_points[i + 1]; // Vec3.create(points[(i+1)*3],points[(i+1)*3+1],points[(i+1)*3+2]);
var d = linear_algebra_1.Vec3.distance(pti, pti1);
if (d >= segmentLength) {
// use twist or random?
var quat = linear_algebra_1.Quat.rotationTo(linear_algebra_1.Quat.zero(), linear_algebra_1.Vec3.create(0, 0, 1), frames[i].t); // Quat.rotationTo(Quat.zero(), Vec3.create(0,0,1),new_normal[i]);//Quat.rotationTo(Quat.zero(), Vec3.create(0,0,1),direction);new_normal
var rq = linear_algebra_1.Quat.setAxisAngle(linear_algebra_1.Quat.zero(), frames[i].t, Math.random() * 3.60); // Quat.setAxisAngle(Quat.zero(),direction, Math.random()*3.60 );//Quat.identity();//
var m = linear_algebra_1.Mat4.fromQuat(linear_algebra_1.Mat4.zero(), linear_algebra_1.Quat.multiply(linear_algebra_1.Quat.zero(), rq, quat)); // Mat4.fromQuat(Mat4.zero(),Quat.multiply(Quat.zero(),quat1,quat2));//Mat4.fromQuat(Mat4.zero(),quat);//Mat4.identity();//Mat4.fromQuat(Mat4.zero(),Quat.multiply(Quat.zero(),rq,quat));
// let pos:Vec3 = Vec3.add(Vec3.zero(),pti1,pti)
// pos = Vec3.scale(pos,pos,1.0/2.0);
// Vec3.makeRotation(Mat4.zero(),Vec3.create(0,0,1),frames[i].t);//
linear_algebra_1.Mat4.setTranslation(m, pti1);
// let m2:Mat4 = GetTubePropertiesMatrix(pti,pti1);
// let q:Quat = Quat.rotationTo(Quat.zero(), Vec3.create(0,1,0),Vec3.create(0,0,1))
// m2=Mat4.mul(Mat4.identity(),Mat4.fromQuat(Mat4.zero(),q),m2);
transforms.push(m);
linear_algebra_1.Vec3.copy(pti, pti1);
}
if (transforms.length >= limit)
break;
}
return transforms;
}
exports.getMatFromResamplePoints = getMatFromResamplePoints;
//# sourceMappingURL=curve.js.map