public static Vector2d Min(Vector2d v1, Vector2d v2) { return new Vector2d( (v1.x < v2.x) ? v1.x : v2.x, (v1.y < v2.y) ? v1.y : v2.y ); }
// using column vectors public Matrix2d(Vector2d v1, Vector2d v2) { a = v1.x; b = v2.x; c = v1.y; d = v2.y; }
public static Vector2d Max(Vector2d v1, Vector2d v2) { return new Vector2d( (v1.x > v2.x) ? v1.x : v2.x, (v1.y > v2.y) ? v1.y : v2.y ); }
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(); }
protected override void OnMouseUp(MouseEventArgs e) { base.OnMouseUp(e); this.currMousePosition = new Vector2d(e.X, this.Height - e.Y); this.isMouseDown = false; if (currMeshRecord == null) return; switch (Program.currentMode) { case Program.EnumOperationMode.Viewing: if (currMousePosition.Equals(mouseDownPosition)) break; Matrix4d m = ball.GetMatrix(); this.currTransformation = m * currTransformation; // this.currInverseTransformation = this.currTransformation.Inverse(); this.ball.End(); this.Refresh(); break; case Program.EnumOperationMode.Selection: switch (Program.toolsProperty.SelectionMethod) { case ToolsProperty.EnumSelectingMethod.Rectangle: SelectVertexByRect(); break; case ToolsProperty.EnumSelectingMethod.Point: //SelectVertexByPoint(); break; } currMeshRecord.Mesh.GroupingFlags(); this.Refresh(); break; case Program.EnumOperationMode.Sketching: if (e.Button == MouseButtons.Left && currMeshRecord.CrossBoundaryBrushes != null) { this.Project2Mesh(); this.faces_on_strokes.Add(curr_f_stroke); this.strokes.Add(curr_v_stroke); this.strokes_on_Srceen.Add(strokeScreenPos); if (currMeshRecord.CrossBoundaryBrushes != null && this.curr_v_stroke.Count >= 2) { if (!this.multi_stroke) { this.Cut(); this.Refresh(); } else { currMeshRecord.CrossBoundaryBrushes.RemovePrevCut(); this.Cut(); this.Refresh(); } } this.Refresh(); } break; case Program.EnumOperationMode.Moving: this.Refresh(); break; } }
public Vector4d(Vector2d v, double z, double w) { this.x = v.x; this.y = v.y; this.z = z; this.w = w; }
public Vector4d(Vector2d v) { this.x = v.x; this.y = v.y; this.z = 0; this.w = 0; }
public Vector3d(Vector2d v, double z) { this.x = v.x; this.y = v.y; this.z = z; }
private bool PointInTriangle(Vector2d p, Vector2d a, Vector2d b, Vector2d c) { if (SameSide(p,a,b,c) && SameSide(p,b,a,c) && SameSide(p,c, a,b)) return true; return false; }
public void Click(Vector2d pt, MotionType type) { this.stPt = pt; this.stVec = MapToSphere(pt); this.type = type; }
protected override void OnMouseMove(MouseEventArgs e) { base.OnMouseMove(e); this.currMousePosition = new Vector2d(e.X, this.Height - e.Y); if (currMeshRecord == null) return; switch (Program.currentMode) { case Program.EnumOperationMode.Viewing: switch (e.Button) { case MouseButtons.Left: ball.Drag(currMousePosition); break; case MouseButtons.Middle: ball.Drag(currMousePosition / this.scaleRatio); break; case MouseButtons.Right: ball.Drag(currMousePosition); break; } this.Refresh(); break; case Program.EnumOperationMode.Selection: if (isMouseDown) this.Refresh(); break; case Program.EnumOperationMode.Sketching: if (e.Button == MouseButtons.Left && currMeshRecord.CrossBoundaryBrushes != null) { if ((currMousePosition - prevMousePosition).Length() > 1) { this.strokeScreenPos.Add(currMousePosition); prevMousePosition.x = currMousePosition.x; prevMousePosition.y = currMousePosition.y; } this.Refresh(); } break; case Program.EnumOperationMode.Moving: if (isMouseDown) { Vector2d p = currMousePosition - new Vector2d(projectedCenter.x, projectedCenter.y); int d = 0; p.x += 100; p.y += 100; switch (e.Button) { case MouseButtons.Right: movingBall.Drag(p); break; case MouseButtons.Left: movingBall.Drag(p / this.scaleRatio); d = 1; break; case MouseButtons.Middle: movingBall.Drag(p); break; } Matrix4d currInverseTransformation = this.currTransformation.Inverse(); Matrix4d tran = currInverseTransformation * this.movingBall.GetMatrix() * currTransformation; //Matrix4d tran = currTransformation * this.movingBall.GetMatrix() * currInverseTransformation; double[] pos = this.currMeshRecord.Mesh.VertexPos; for (int i = 0; i < handleIndex.Count; i++) { int j = handleIndex[i] * 3; Vector4d q = new Vector4d((Vector3d)this.oldHandlePos[i], d); q = tran * (q - this.handleCenter) + this.handleCenter; pos[j] = q.x; pos[j + 1] = q.y; pos[j + 2] = q.z; } this.Refresh(); } break; } }
public double Dot(Vector2d v) { return x*v.x + y*v.y; }
protected override void OnMouseDown(MouseEventArgs e) { base.OnMouseDown(e); this.currMousePosition = new Vector2d(e.X, this.Height - e.Y); this.mouseDownPosition = currMousePosition; this.isMouseDown = true; if (currMeshRecord == null) return; switch (Program.currentMode) { case Program.EnumOperationMode.Viewing: switch (e.Button) { case MouseButtons.Left: ball.Click(currMousePosition, Trackball.MotionType.Rotation); break; case MouseButtons.Middle: ball.Click(currMousePosition / this.scaleRatio, Trackball.MotionType.Pan); break; case MouseButtons.Right: ball.Click(currMousePosition, Trackball.MotionType.Scale); break; } break; case Program.EnumOperationMode.Selection: break; case Program.EnumOperationMode.Sketching: if (e.Button == MouseButtons.Left && currMeshRecord.CrossBoundaryBrushes != null) { if (!this.multi_stroke) { this.strokes.Clear(); this.faces_on_strokes.Clear(); this.strokes_on_Srceen.Clear(); } this.curr_f_stroke = new List<int>(); this.curr_v_stroke = new List<int>(); this.strokeScreenPos = new List<Vector2d>(); this.strokeScreenPos.Add(currMousePosition); prevMousePosition.x = currMousePosition.x; prevMousePosition.y = currMousePosition.y; } break; case Program.EnumOperationMode.Moving: break; } }
public void Project2Mesh() { if (this.strokeScreenPos.Count < 1) return; Rectangle viewport = new Rectangle(0, 0, this.Width, this.Height); OpenGLProjector projector = new OpenGLProjector(); Mesh m = currMeshRecord.Mesh; bool laser = Program.toolsProperty.Laser; double eps = Program.toolsProperty.DepthTolerance; foreach (Vector2d pos in this.strokeScreenPos) { double minDis = double.MaxValue; int minIndex = -1; for (int i = 0, j = 0; i < m.VertexCount; i++, j += 3) { Vector3d v = projector.Project(m.VertexPos, j); Vector2d u = new Vector2d(v.x, v.y); if (!viewport.Contains((int)v.x, (int)v.y)) continue; if (projector.GetDepthValue((int)v.x, (int)v.y) - v.z < eps) continue; double dis = (u - pos).Length(); if (dis < minDis) { minIndex = i; minDis = dis; } } if (minIndex != -1) { this.curr_v_stroke.Add(minIndex); } minIndex = -1; for (int i = 0, j = 0; i < m.FaceCount; i++, j += 3) { int c0 = m.FaceIndex[j]*3; int c1 = m.FaceIndex[j + 1]*3; int c2 = m.FaceIndex[j + 2]*3; Vector3d v0 = projector.Project(m.VertexPos, c0); Vector3d v1 = projector.Project(m.VertexPos, c1); Vector3d v2 = projector.Project(m.VertexPos, c2); Vector2d u0 = new Vector2d(v0.x, v0.y); Vector2d u1 = new Vector2d(v1.x, v1.y); Vector2d u2 = new Vector2d(v2.x, v2.y); if (!viewport.Contains((int)v0.x, (int)v0.y)) continue; if (projector.GetDepthValue((int)v0.x, (int)v0.y) - v0.z < eps) continue; if (PointInTriangle(pos, u0, u1, u2)) { minIndex = i; this.curr_f_stroke.Add(minIndex); break; } } } }
private int SelectVertexByPoint(Vector2d currPos) { Rectangle viewport = new Rectangle(0, 0, this.Width, this.Height); OpenGLProjector projector = new OpenGLProjector(); Mesh m = currMeshRecord.Mesh; bool laser = Program.toolsProperty.Laser; double eps = Program.toolsProperty.DepthTolerance; double minDis = double.MaxValue; int minIndex = -1; for (int i = 0, j = 0; i < m.VertexCount; i++, j += 3) { Vector3d v = projector.Project(m.VertexPos, j); Vector2d u = new Vector2d(v.x, v.y); if (!viewport.Contains((int)v.x, (int)v.y)) continue; if (projector.GetDepthValue((int)v.x, (int)v.y) - v.z < eps) continue; double dis = (u - currPos).Length(); if (dis < minDis) { minIndex = i; minDis = dis; } } if (minIndex == -1) return -1; //FormMain.CurrForm.OutputText("selected vertex: " + minIndex.ToString()); if ((Control.ModifierKeys & Keys.Shift) == Keys.Shift) m.Flag[minIndex] = (byte)1; else if ((Control.ModifierKeys & Keys.Control) == Keys.Control) m.Flag[minIndex] = (byte)0; else { for (int i = 0; i < m.VertexCount; i++) m.Flag[i] = (byte)0; m.Flag[minIndex] = (byte)1; } return minIndex; }
private int SelectFaceByPoint(Vector2d screen_pos) { Rectangle viewport = new Rectangle(0, 0, this.Width, this.Height); OpenGLProjector projector = new OpenGLProjector(); Mesh m = currMeshRecord.Mesh; bool laser = Program.toolsProperty.Laser; double eps = Program.toolsProperty.DepthTolerance; int minIndex = -1; for (int i = 0, j = 0; i < m.FaceCount; i++, j += 3) { int c0 = m.FaceIndex[j]*3; int c1 = m.FaceIndex[j + 1]*3; int c2 = m.FaceIndex[j + 2]*3; Vector3d v0 = projector.Project(m.VertexPos, c0); Vector3d v1 = projector.Project(m.VertexPos, c1); Vector3d v2 = projector.Project(m.VertexPos, c2); Vector2d u0 = new Vector2d(v0.x, v0.y); Vector2d u1 = new Vector2d(v1.x, v1.y); Vector2d u2 = new Vector2d(v2.x, v2.y); if (!viewport.Contains((int)v0.x, (int)v0.y)) continue; if (projector.GetDepthValue((int)v0.x, (int)v0.y) - v0.z < eps) continue; if (PointInTriangle(screen_pos, u0, u1, u2)) { minIndex = i; break; } } return minIndex; }
// -- whether two points p1 and p2 are on the same side of edge ab -- private bool SameSide(Vector2d p1, Vector2d p2, Vector2d a, Vector2d b) { Vector3d A = new Vector3d(a); Vector3d B = new Vector3d(b); Vector3d P = new Vector3d(p1); Vector3d Q = new Vector3d(p2); Vector3d E = B-A; Vector3d cp1 = E.Cross(P-A); Vector3d cp2 = E.Cross(Q-A); if (cp1.Dot(cp2) >= 0) return true; return false; }
public bool Equals(Vector2d v) { return (this.x == v.x) && (this.y == v.y) ? true : false; }
private Vector3d MapToSphere(Vector2d pt) { Vector2d v = new Vector2d(); v.x = (w - pt.x) * adjustWidth; v.y = (h - pt.y) * adjustHeight; double lenSq = v.Dot(v); if (lenSq > 1.0) { double norm = 1.0 / Math.Sqrt(lenSq); return new Vector3d(v.x * norm, v.y * norm, 0); } else { return new Vector3d(v.x, v.y, Math.Sqrt(1.0 - lenSq)); } }