public void Drag(Vector2d pt) { edPt = pt; edVec = MapToSphere(pt); double epsilon = 1.0e-5; Vector3d prep = stVec.Cross(edVec); if (prep.Length() > epsilon) quat = new Vector4d(prep, stVec.Dot(edVec)); else quat = new Vector4d(); }
public Quaternion(Matrix3d m) { double T = 1.0 + m.Trace(); double S, W, X, Y, Z; if (T > eps) { S = Math.Sqrt(T) * 2.0; X = (m[5] - m[7]) / S; Y = (m[6] - m[2]) / S; Z = (m[1] - m[3]) / S; W = 0.25 * S; } else if (m[0] > m[4] && m[0] > m[8]) { S = Math.Sqrt(1.0 + m[0] - m[4] - m[8]) * 2.0; X = 0.25 * S; Y = (m[1] + m[3]) / S; Z = (m[6] + m[2]) / S; W = (m[5] - m[7]) / S; } else if (m[4] > m[8]) { S = Math.Sqrt(1.0 + m[4] - m[0] - m[8]) * 2; X = (m[1] + m[3]) / S; Y = 0.25 * S; Z = (m[5] + m[7]) / S; W = (m[6] - m[2]) / S; } else { S = Math.Sqrt(1.0 + m[8] - m[0] - m[4]) * 2; X = (m[6] + m[2]) / S; Y = (m[5] + m[7]) / S; Z = 0.25 * S; W = (m[1] - m[3]) / S; } this.s = W; this.v = new Vector3d(X, Y, Z); }
public double Dot(Vector3d v) { return x*v.x + y*v.y + z*v.z; }
public double AverageFaceArea() { double tot = 0; for (int i = 0, j = 0; i < faceCount; i++, j += 3) { Vector3d v1 = new Vector3d(VertexPos, faceIndex[j] * 3); Vector3d v2 = new Vector3d(VertexPos, faceIndex[j + 1] * 3); Vector3d v3 = new Vector3d(VertexPos, faceIndex[j + 2] * 3); tot += ((v2 - v1).Cross(v3 - v1)).Length() / 2.0; } return (tot / faceCount); }
public Vector3d Cross(Vector3d v) { return new Vector3d( y * v.z - v.y * z, z * v.x - v.z * x, x * v.y - v.x * y ); }
private double Face_wij(int i, int j) { double[] normal = this.new_normals == null ? mesh.FaceNormal : this.new_normals; int b = i * 3, c = j * 3; Vector3d ni = new Vector3d(normal, b); Vector3d nj = new Vector3d(normal, c); Vector3d vi = new Vector3d(mesh.DualVertexPos, b); Vector3d vj = new Vector3d(mesh.DualVertexPos, c); Vector3d eij = (vj - vi).Normalize(); double d = (nj - ni).Length(); double e = Math.Abs((ni).Dot(eij)); return (1+e)*d; }
/*s is the \sigma*/ private void FilterFaceNormals(double s, int iterations) { // -- precompute normals based on NII, as a smoothing step -- int n = mesh.FaceCount; double denominator = s*s*2; old_normals = mesh.FaceNormal.Clone() as double[]; new_normals = new double[n*3]; for (int k = 0; k < iterations; ++k) { for (int i = 0; i < n; ++i) { // -- get two-ring neighbors Set<int> nbrs = this.neighbors[i]; nbrs.Remove(i); int count = nbrs.Count, b = i * 3; Vector3d ni = new Vector3d(mesh.FaceNormal, b); Vector3d nn = new Vector3d(); foreach (int f in nbrs) { Vector3d nj = new Vector3d(mesh.FaceNormal, f * 3); double d = (ni - nj).Length(); double w = Math.Exp(-d * d / denominator); nn = nn + w * nj; } nn = nn.Normalize(); new_normals[b] = nn.x; new_normals[b + 1] = nn.y; new_normals[b + 2] = nn.z; } //mesh.FaceNormal = new_normals.Clone() as double[]; } }
public void ComputeFaceNormal() { for (int i=0,j=0; i<faceCount; i++,j+=3) { int c1 = faceIndex[j] * 3; int c2 = faceIndex[j+1] * 3; int c3 = faceIndex[j+2] * 3; Vector3d v1 = new Vector3d(vertexPos, c1); Vector3d v2 = new Vector3d(vertexPos, c2); Vector3d v3 = new Vector3d(vertexPos, c3); Vector3d normal = (v2-v1).Cross(v3-v1).Normalize(); faceNormal[j] = normal.x; faceNormal[j+1] = normal.y; faceNormal[j+2] = normal.z; } }
private void ApplyHarmonicSolver_Cholmod() { // --- build up lefthand side matrix A int vn = mesh.VertexCount; int fn = mesh.FaceCount; int bn = this.sourceVertices.Count + this.sinkVertices.Count; int m = vn+bn; if (this.sparseSolver != null) this.sparseSolver.Release(); this.sparseSolver = new CholmodSolver(); this.sparseSolver.InitializeMatrixA(m, vn); for (int i = 0, j = 0; i < fn; i++, j += 3) { int c1 = mesh.FaceIndex[j]; int c2 = mesh.FaceIndex[j + 1]; int c3 = mesh.FaceIndex[j + 2]; Vector3d v1 = new Vector3d(mesh.VertexPos, c1 * 3); Vector3d v2 = new Vector3d(mesh.VertexPos, c2 * 3); Vector3d v3 = new Vector3d(mesh.VertexPos, c3 * 3); double cot1 = (v2 - v1).Dot(v3 - v1) / (v2 - v1).Cross(v3 - v1).Length(); double cot2 = (v3 - v2).Dot(v1 - v2) / (v3 - v2).Cross(v1 - v2).Length(); double cot3 = (v1 - v3).Dot(v2 - v3) / (v1 - v3).Cross(v2 - v3).Length(); sparseSolver.Add_Coef(c2, c2, -cot1); sparseSolver.Add_Coef(c2, c3, cot1); sparseSolver.Add_Coef(c3, c3, -cot1); sparseSolver.Add_Coef(c3, c2, cot1); sparseSolver.Add_Coef(c3, c3, -cot2); sparseSolver.Add_Coef(c3, c1, cot2); sparseSolver.Add_Coef(c1, c1, -cot2); sparseSolver.Add_Coef(c1, c3, cot2); sparseSolver.Add_Coef(c1, c1, -cot3); sparseSolver.Add_Coef(c1, c2, cot3); sparseSolver.Add_Coef(c2, c2, -cot3); sparseSolver.Add_Coef(c2, c1, cot3); } // add positional weights int index = 0; foreach (int v in sourceVertices) { sparseSolver.Add_Coef(vn + index, v, 1.0 * ConstantWeight); ++index; } foreach (int v in sinkVertices) { sparseSolver.Add_Coef(vn + index, v, 1.0 * ConstantWeight); ++index; } if (!opt.UseAtb) m = vn; double[] b = new double[m]; double[] x = new double[vn]; // -- assign values to the right hand side b,-- Ax=b if (opt.UseAtb) { for (int j = 0; j < b.Length; j++) b[j] = 0; int count = 0; for (int j = 0; j < sourceVertices.Count; ++j, ++count) b[vn + j] = 1.0 * ConstantWeight; for (int j = 0; j < sinkVertices.Count; ++j) b[vn + count + j] = 0.0; } else // set by user.. { foreach (int v in this.sourceVertices) b[v] = 1.0 * ConstantWeight * ConstantWeight; } fixed (double* _b = b) { sparseSolver.InitializeMatrixB(_b, m, 1); } sparseSolver.InitializeSolver(); sparseSolver.SetFinalPack(0); sparseSolver.Factorize(); fixed (double* _x = x) { sparseSolver.Linear_Solve(_x, !opt.UseAtb); } this.harmonicField = x; }
public void Click(Vector2d pt, MotionType type) { this.stPt = pt; this.stVec = MapToSphere(pt); this.type = type; }
public Vector4d(Vector3d v) { this.x = v.x; this.y = v.y; this.z = v.z; this.w = 0; }
public Vector3d MinCoord() { Vector3d minCoord = new Vector3d(double.MaxValue, double.MaxValue, double.MaxValue); for (int i=0,j=0; i<vertexCount; i++,j+=3) { Vector3d v = new Vector3d(vertexPos, j); minCoord = Vector3d.Min(minCoord, v); } return minCoord; }
public double Volume() { double totVolume = 0; for (int i = 0, j = 0; i < faceCount; i++, j += 3) { int c1 = faceIndex[j] * 3; int c2 = faceIndex[j + 1] * 3; int c3 = faceIndex[j + 2] * 3; Vector3d a = new Vector3d(vertexPos, c1); Vector3d b = new Vector3d(vertexPos, c2); Vector3d c = new Vector3d(vertexPos, c3); totVolume += a.x * b.y * c.z - a.x * b.z * c.y - a.y * b.x * c.z + a.y * b.z * c.x + a.z * b.x * c.y - a.z * b.y * c.x; } return totVolume; }
public void ComputeVertexNormal() { Array.Clear(vertexNormal, 0, vertexNormal.Length); for (int i=0,j=0; i<faceCount; i++,j+=3) { int c1 = faceIndex[j] * 3; int c2 = faceIndex[j+1] * 3; int c3 = faceIndex[j+2] * 3; vertexNormal[c1] += faceNormal[j]; vertexNormal[c2] += faceNormal[j]; vertexNormal[c3] += faceNormal[j]; vertexNormal[c1+1] += faceNormal[j+1]; vertexNormal[c2+1] += faceNormal[j+1]; vertexNormal[c3+1] += faceNormal[j+1]; vertexNormal[c1+2] += faceNormal[j+2]; vertexNormal[c2+2] += faceNormal[j+2]; vertexNormal[c3+2] += faceNormal[j+2]; } for (int i=0,j=0; i<vertexCount; i++,j+=3) { Vector3d n = new Vector3d(vertexNormal, j); n = n.Normalize(); vertexNormal[j] = n.x; vertexNormal[j+1] = n.y; vertexNormal[j+2] = n.z; } }
public void ComputeNormals2Ring() { int nf = faceCount; Vector3d[] vnormals = new Vector3d[VertexCount]; for (int i = 0, j = 0; i < nf; i++, j += 3) { int v0 = faceIndex[j]; int v1 = faceIndex[j + 1]; int v2 = faceIndex[j + 2]; Vector3d p0 = new Vector3d(vertexPos, v0 * 3); Vector3d p1 = new Vector3d(vertexPos, v1 * 3); Vector3d p2 = new Vector3d(vertexPos, v2 * 3); Vector3d a = p0 - p1, b = p1 - p2, c = p2 - p0; double l2a = a.Dot(a), l2b = b.Dot(b), l2c = c.Dot(c); Vector3d facenormal = a.Cross(b); // assign face normals facenormal = facenormal.Normalize(); faceNormal[j] = facenormal.x; faceNormal[j + 1] = facenormal.y; faceNormal[j + 2] = facenormal.z; } for (int i = 0, j = 0; i < vertexCount; ++i, j += 3) { Set<int> fset = new Set<int>(); foreach (int adj in adjVV[i]) { foreach (int f in adjVF[adj]) { fset.Add(f); } } vnormals[i] = new Vector3d(); foreach (int f in fset) { Vector3d fnormal = new Vector3d(faceNormal, f * 3); double s = ComputeFaceArea(f); vnormals[i] = vnormals[i] + s*fnormal; } vnormals[i] = vnormals[i].Normalize(); vertexNormal[j] = vnormals[i].x; vertexNormal[j + 1] = vnormals[i].y; vertexNormal[j + 2] = vnormals[i].z; } }
// compute both face normals and vertex normals, from trimesh2. public void ComputeNormals() { int nf = faceCount; Vector3d[] vnormals = new Vector3d[VertexCount]; for (int i = 0, j = 0; i < nf; i++, j+=3) { int v0 = faceIndex[j]; int v1 = faceIndex[j+1]; int v2 = faceIndex[j+2]; Vector3d p0 = new Vector3d(vertexPos, v0*3); Vector3d p1 = new Vector3d(vertexPos, v1*3); Vector3d p2 = new Vector3d(vertexPos, v2*3); Vector3d a = p0-p1, b = p1-p2, c = p2-p0; double l2a = a.Dot(a), l2b = b.Dot(b), l2c = c.Dot(c); Vector3d facenormal = a.Cross(b); // assign vertex normals vnormals[v0] = vnormals[v0] + facenormal * (1.0 / (l2a * l2c)); vnormals[v1] = vnormals[v1] + facenormal * (1.0 / (l2b * l2a)); vnormals[v2] = vnormals[v2] + facenormal * (1.0 / (l2c * l2b)); // assign face normals facenormal = facenormal.Normalize(); faceNormal[j] = facenormal.x; faceNormal[j+1] = facenormal.y; faceNormal[j+2] = facenormal.z; } for (int i = 0, j = 0; i < vertexCount; ++i, j += 3) { vnormals[i] = vnormals[i].Normalize(); vertexNormal[j] = vnormals[i].x; vertexNormal[j+1] = vnormals[i].y; vertexNormal[j+2] = vnormals[i].z; } }
public Matrix3d OuterCross(Vector3d v) { Matrix3d m = new Matrix3d(); m[0, 0] = x * v.x; m[0, 1] = x * v.y; m[0, 2] = x * v.z; m[1, 0] = y * v.x; m[1, 1] = y * v.y; m[1, 2] = y * v.z; m[2, 0] = z * v.x; m[2, 1] = z * v.y; m[2, 2] = z * v.z; return m; }
private void LocateFacesIsoPosition(double[] f, double[] isovals) { if (f == null) throw new ArgumentException(); // initialize isofaces this.isofaces = new IsoFaceRec[mesh.FaceCount]; for (int i = 0; i < mesh.FaceCount; ++i) this.isofaces[i] = new IsoFaceRec(); for (int i = 0; i < isovalues.Length; ++i) { double v = isovals[i]; for (int k = 0, m = 0; k < this.mesh.FaceCount; ++k, m += 3) { int c1 = this.mesh.FaceIndex[m]; int c2 = this.mesh.FaceIndex[m + 1]; int c3 = this.mesh.FaceIndex[m + 2]; PQPairs r = null; if ((f[c1] <= v && f[c2] >= v) || (f[c2] <= v && f[c1] >= v)) { if (r == null) { r = new PQPairs(); r.findex = k; } if (r.e1 == -1) { r.e1 = 0; r.ratio1 = (v - f[c1]) / (f[c2] - f[c1]); } else { r.e2 = 0; r.ratio2 = (v - f[c1]) / (f[c2] - f[c1]); } } if ((f[c2] <= v && f[c3] >= v) || (f[c3] <= v && f[c2] >= v)) { if (r == null) { r = new PQPairs(); r.findex = k; } if (r.e1 == -1) { r.e1 = 1; r.ratio1 = (v - f[c2]) / (f[c3] - f[c2]); } else { r.e2 = 1; r.ratio2 = (v - f[c2]) / (f[c3] - f[c2]); } } if ((f[c3] <= v && f[c1] >= v) || (f[c1] <= v && f[c3] >= v)) { if (r == null) { r = new PQPairs(); r.findex = k; } if (r.e1 == -1) { r.e1 = 2; r.ratio1 = (v - f[c3]) / (f[c1] - f[c3]); } else { r.e2 = 2; r.ratio2 = (v - f[c3]) / (f[c1] - f[c3]); } } if (r == null) continue; if (r.e1 == -1 || r.e2 == -1) continue; r.isovalue = v; r.lindex = i; Vector3d v1 = new Vector3d(mesh.VertexPos, c1 * 3); Vector3d v2 = new Vector3d(mesh.VertexPos, c2 * 3); Vector3d v3 = new Vector3d(mesh.VertexPos, c3 * 3); Vector3d n1 = new Vector3d(mesh.FaceNormal, k * 3); Vector3d p = new Vector3d(), q = new Vector3d(); switch (r.e1) { case 0: p = v2 * r.ratio1 + v1 * (1.0 - r.ratio1); break; case 1: p = v3 * r.ratio1 + v2 * (1.0 - r.ratio1); break; case 2: p = v1 * r.ratio1 + v3 * (1.0 - r.ratio1); break; } switch (r.e2) { case 0: q = v2 * r.ratio2 + v1 * (1.0 - r.ratio2); break; case 1: q = v3 * r.ratio2 + v2 * (1.0 - r.ratio2); break; case 2: q = v1 * r.ratio2 + v3 * (1.0 - r.ratio2); break; } r.n = n1; r.p = p; r.q = q; isofaces[k].pqPairs.Add(r); isofaces[k].index = k; isofaces[k].valid = true; } } }
public Vector3d Rotate(Vector3d axis, double cos, double sin) { return this * cos + (axis.Cross(this)) * sin + axis * ((1.0 - cos) * (axis.Dot(this))); }
public double ComputeFaceArea(int fIndex) { int b = fIndex * 3; Vector3d v1 = new Vector3d(VertexPos, faceIndex[b] * 3); Vector3d v2 = new Vector3d(VertexPos, faceIndex[b+1] * 3); Vector3d v3 = new Vector3d(VertexPos, faceIndex[b+2] * 3); return ((v2-v1).Cross(v3-v1)).Length() / 2.0; }
public Vector4d(Vector3d v, double w) { this.x = v.x; this.y = v.y; this.z = v.z; this.w = w; }
public static void Print3DText(Vector3d pos, string s) { FormMain f = FormMain.ActiveForm as FormMain; if (f != null) f.Print3DText(pos, s); }
private double Vrt_wij(int i, int j) { int b = i * 3, c = j * 3; Vector3d s = new Vector3d(mesh.VertexPos, b); Vector3d t = new Vector3d(mesh.VertexPos, c); Vector3d e = t-s; Vector3d ns = new Vector3d(mesh.VertexNormal, b); Vector3d nt = new Vector3d(mesh.VertexNormal, c); double w = (1 + ns.Dot(e) / e.Length()) * (1 + ns.Cross(nt).Length()); return w; }
public Quaternion(double s, Vector3d v) { this.s = s; this.v = v; }
private double Face_dij(int i, int j) { Vector3d ci = new Vector3d(mesh.DualVertexPos, i * 3); Vector3d cj = new Vector3d(mesh.DualVertexPos, j * 3); double d = (cj - ci).Length(); return d; }
public static Vector3d Max(Vector3d v1, Vector3d v2) { return new Vector3d( (v1.x > v2.x) ? v1.x : v2.x, (v1.y > v2.y) ? v1.y : v2.y, (v1.z > v2.z) ? v1.z : v2.z ); }
private double Face_wij1(int i, int j) { Vector3d ns = new Vector3d(mesh.FaceNormal, i * 3); Vector3d nt = new Vector3d(mesh.FaceNormal, j * 3); return -ns.Dot(nt); }
public static Vector3d Min(Vector3d v1, Vector3d v2) { return new Vector3d( (v1.x < v2.x) ? v1.x : v2.x, (v1.y < v2.y) ? v1.y : v2.y, (v1.z < v2.z) ? v1.z : v2.z ); }
private bool IsTheSamePosition(Vector3d s, Vector3d t) { if ((s - t).Length() < 1e-08) return true; return false; }
public void Print3DText(Vector3d pos, string s) { GL.glRasterPos3d(pos.x, pos.y, pos.z); GL.glPushAttrib(GL.GL_LIST_BIT); // Pushes The Display List Bits GL.glListBase(this.meshView1.fontBase); // Sets The Base Character to 32 GL.glCallLists(s.Length, GL.GL_UNSIGNED_SHORT, s); // Draws The Display List Text GL.glPopAttrib(); // Pops The Display List Bits }