public override void AddPointInCreating(DrawContext dc, CadVertex p) { if (Figure.mPointList.Count == 0) { Figure.mPointList.Add(p); } else { Vector3d p0 = Figure.PointList[0].vector; Vector3d p2 = p.vector; Vector3d hv = CadMath.CrossProduct(dc.UpVector, dc.ViewDir).Normalized(); Vector3d uv = dc.UpVector; Vector3d crossV = p2 - p0; Vector3d v1 = CadMath.InnerProduct(crossV, hv) * hv; Vector3d p1 = v1 + p0; Vector3d v3 = CadMath.InnerProduct(crossV, uv) * uv; Vector3d p3 = v3 + p0; Figure.mPointList.Add(new CadVertex(p3)); Figure.mPointList.Add(new CadVertex(p2)); Figure.mPointList.Add(new CadVertex(p1)); Figure.IsLoop = true; } }
public void DrawHarfEdgeModel( DrawBrush brush, DrawPen pen, DrawPen edgePen, double edgeThreshold, HeModel model) { for (int i = 0; i < model.FaceStore.Count; i++) { HeFace f = model.FaceStore[i]; HalfEdge head = f.Head; HalfEdge c = head; HalfEdge pair; for (; ;) { bool edge = false; pair = c.Pair; if (pair == null) { edge = true; } else { double s = CadMath.InnerProduct(model.NormalStore[c.Normal], model.NormalStore[pair.Normal]); if (Math.Abs(s) < edgeThreshold) { edge = true; } } HalfEdge next = c.Next; DrawPen dpen = edge ? edgePen : pen; DrawLine(dpen, model.VertexStore.Ref(c.Vertex).vector, model.VertexStore.Ref(next.Vertex).vector ); c = next; if (c == head) { break; } } } }
public override void MoveSelectedPointsFromStored(DrawContext dc, Vector3d delta) { //base.MoveSelectedPoints(dc, delta); if (Locked) { return; } Vector3d d; if (!IsSelectedAll() && mPointList.Count > 2 && RestrictionByNormal) { Vector3d vdir = dc.ViewDir; Vector3d a = delta; Vector3d b = delta + vdir; d = CadMath.CrossPlane(a, b, StoreList[0].vector, Normal); if (!d.IsValid()) { Vector3d nvNormal = CadMath.Normal(Normal, vdir); double ip = CadMath.InnerProduct(nvNormal, delta); d = nvNormal * ip; } } else { d = delta; } FigUtil.MoveSelectedPointsFromStored(this, dc, d); mChildList.ForEach(c => { c.MoveSelectedPointsFromStored(dc, delta); }); }
private void DrawDim(DrawContext dc, DrawPen linePen, DrawBrush textBrush) { dc.Drawing.DrawLine(linePen, PointList[0].vector, PointList[3].vector); dc.Drawing.DrawLine(linePen, PointList[1].vector, PointList[2].vector); Vector3d cp = CadMath.CenterPoint(PointList[3].vector, PointList[2].vector); double arrowW = ARROW_W; double arrowL = ARROW_LEN; double ww = (PointList[1] - PointList[0]).Norm() / 4.0; if (ww > arrowL) { dc.Drawing.DrawArrow(linePen, cp, PointList[3].vector, ArrowTypes.CROSS, ArrowPos.END, arrowL, arrowW); dc.Drawing.DrawArrow(linePen, cp, PointList[2].vector, ArrowTypes.CROSS, ArrowPos.END, arrowL, arrowW); } else { Vector3d v0 = cp - PointList[3].vector; Vector3d v1 = cp - PointList[2].vector; v0 = -(v0.Normalized() * (arrowL * 1.5)) / dc.WorldScale + PointList[3].vector; v1 = -(v1.Normalized() * (arrowL * 1.5)) / dc.WorldScale + PointList[2].vector; dc.Drawing.DrawArrow(linePen, v0, PointList[3].vector, ArrowTypes.CROSS, ArrowPos.END, arrowL, arrowW); dc.Drawing.DrawArrow(linePen, v1, PointList[2].vector, ArrowTypes.CROSS, ArrowPos.END, arrowL, arrowW); dc.Drawing.DrawLine(linePen, PointList[2].vector, PointList[3].vector); } CadVertex lineV = PointList[2] - PointList[3]; double len = lineV.Norm(); string lenStr = CadUtil.ValToString(len); CadVertex p = PointList[3] + (lineV / 2); p += (PointList[3] - PointList[0]).UnitVector() * (arrowW); CadVertex up = PointList[3] - PointList[0]; // 裏返しになる場合は、反転する // If it turns over, reverse it Vector3d normal = CadMath.Normal(lineV.vector, up.vector); double scala = CadMath.InnerProduct(normal, dc.ViewDir); if (scala > 0) { lineV = -lineV; } // --- lineV ---> // 3<------------ p ----------->2 // ^ | | // | | | // up 0 1 // dc.Drawing.DrawText(FontID, textBrush, p.vector, lineV.vector, up.vector, new DrawTextOption(DrawTextOption.H_CENTER), lenStr); }
public override void MoveSelectedPointsFromStored(DrawContext dc, Vector3d delta) { if (PointList[0].Selected && PointList[1].Selected && PointList[2].Selected && PointList[3].Selected) { PointList[0] = StoreList[0] + delta; PointList[1] = StoreList[1] + delta; PointList[2] = StoreList[2] + delta; PointList[3] = StoreList[3] + delta; return; } if (PointList[2].Selected || PointList[3].Selected) { Vector3d v0 = StoreList[3].vector - StoreList[0].vector; if (v0.IsZero()) { // 移動方向が不定の場合 MoveSelectedPointWithHeight(dc, delta); return; } Vector3d v0u = v0.UnitVector(); double d = CadMath.InnerProduct(v0u, delta); Vector3d vd = v0u * d; CadVertex nv3 = StoreList[3] + vd; CadVertex nv2 = StoreList[2] + vd; if (nv3.EqualsThreshold(StoreList[0], 0.001) || nv2.EqualsThreshold(StoreList[1], 0.001)) { return; } PointList[3] = nv3; PointList[2] = nv2; return; } if (PointList[0].Selected || PointList[1].Selected) { Vector3d v0 = StoreList[0].vector; Vector3d v1 = StoreList[1].vector; Vector3d v2 = StoreList[2].vector; Vector3d v3 = StoreList[3].vector; Vector3d lv = v3 - v0; double h = lv.Norm(); Vector3d planeNormal = CadMath.Normal(v0, v1, v2); Vector3d cp0 = v0; Vector3d cp1 = v1; if (PointList[0].Selected) { cp0 = CadMath.CrossPlane(v0 + delta, v0, planeNormal); } if (PointList[1].Selected) { cp1 = CadMath.CrossPlane(v1 + delta, v1, planeNormal); } if (cp0.EqualsThreshold(cp1, 0.001)) { return; } if (PointList[0].Selected) { PointList[0] = PointList[0].SetVector(cp0); } if (PointList[1].Selected) { PointList[1] = PointList[1].SetVector(cp1); } Vector3d normal = CadMath.Normal(cp0, cp0 + planeNormal, cp1); Vector3d d = normal * h; PointList[3] = PointList[3].SetVector(PointList[0] + d); PointList[2] = PointList[2].SetVector(PointList[1] + d); } }
private void DrawHeEdges(DrawPen borderPen, DrawPen edgePen, double edgeThreshold, HeModel model) { bool drawBorder = !borderPen.IsNullPen; bool drawEdge = !edgePen.IsNullPen; if (!drawBorder && !drawEdge) { return; } DisableLight(); GL.LineWidth(1.0f); Color4 color = borderPen.Color4(); Color4 edgeColor = edgePen.Color4(); Vector3d shift = GetShiftForOutLine(); Vector3d p0; Vector3d p1; for (int i = 0; i < model.FaceStore.Count; i++) { HeFace f = model.FaceStore[i]; HalfEdge head = f.Head; HalfEdge c = head; HalfEdge pair; p0 = model.VertexStore.Ref(c.Vertex).vector *DC.WorldScale + shift; for (; ;) { bool drawAsEdge = false; pair = c.Pair; if (drawEdge) { if (pair == null) { drawAsEdge = true; } else { if (edgeThreshold != 0) { double s = CadMath.InnerProduct(model.NormalStore[c.Normal], model.NormalStore[pair.Normal]); if (Math.Abs(s) <= edgeThreshold) { drawAsEdge = true; } } } } p1 = model.VertexStore.Ref(c.Next.Vertex).vector *DC.WorldScale + shift; if (drawAsEdge) { GL.Color4(edgeColor); GL.Begin(PrimitiveType.Lines); GL.Vertex3(p0); GL.Vertex3(p1); GL.End(); } else { if (drawBorder) { GL.Color4(color); GL.Begin(PrimitiveType.Lines); GL.Vertex3(p0); GL.Vertex3(p1); GL.End(); } } p0 = p1; c = c.Next; if (c == head) { break; } } } }
// 図形は凸である public static bool IsConvex(VertexList points) { int cnt = points.Count; if (cnt < 3) { return(false); } int i = 0; Vector3d n = default; Vector3d cn = default; double scala = 0; for (; i < cnt - 2;) { n = CadMath.Normal(points[i].vector, points[i + 1].vector, points[i + 2].vector); i++; if (!n.IsZero()) { break; } } if (n.IsZero()) { return(false); } for (; i < cnt - 2;) { cn = CadMath.Normal(points[i].vector, points[i + 1].vector, points[i + 2].vector); i++; scala = CadMath.InnerProduct(cn, n); if (Math.Abs(scala) < CadMath.Epsilon) { continue; } if (scala < CadMath.RP1Min) { return(false); } } cn = CadMath.Normal(points[i].vector, points[i + 1].vector, points[0].vector); scala = CadMath.InnerProduct(cn, n); if (Math.Abs(scala) < 0.000001) { return(true); } if (scala < 0.999999) { return(false); } return(true); }
public static List <CadFigure> Split(CadFigure fig, int curveSplitNum = 32) { CadVertex p0 = default(CadVertex); var triangles = new List <CadFigure>(); int i1 = -1; int state = 0; CadFigure triangle; VertexList pointList = fig.GetPoints(curveSplitNum); i1 = CadUtil.FindMaxDistantPointIndex(p0, pointList); if (i1 == -1) { return(triangles); } triangle = GetTriangleWithCenterPoint(pointList, i1); Vector3d tp0 = triangle.PointList[0].vector; Vector3d tp1 = triangle.PointList[1].vector; Vector3d tp2 = triangle.PointList[2].vector; Vector3d dir = CadMath.Normal(tp1, tp0, tp2); Vector3d currentDir = Vector3d.Zero; while (pointList.Count > 3) { if (state == 0) { i1 = CadUtil.FindMaxDistantPointIndex(p0, pointList); if (i1 == -1) { return(triangles); } } triangle = GetTriangleWithCenterPoint(pointList, i1); tp0 = triangle.PointList[0].vector; tp1 = triangle.PointList[1].vector; tp2 = triangle.PointList[2].vector; currentDir = CadMath.Normal(tp1, tp0, tp2); bool hasIn = ListContainsPointInTriangle(pointList, triangle); double scala = CadMath.InnerProduct(dir, currentDir); if (!hasIn && (scala > 0)) { triangles.Add(triangle); pointList.RemoveAt(i1); state = 0; continue; } if (state == 0) { state = 1; i1 = 0; } else if (state == 1) { i1++; if (i1 >= pointList.Count) { break; } } } if (pointList.Count == 3) { triangle = CadFigure.Create(CadFigure.Types.POLY_LINES); triangle.AddPoints(pointList, 0, 3); triangle.IsLoop = true; triangles.Add(triangle); } return(triangles); }