Beispiel #1
0
        // 法線の代表値を求める
        //public static CadVertex RepresentativeNormal(VertexList points)
        //{
        //    if (points.Count < 3)
        //    {
        //        return CadVertex.Zero;
        //    }

        //    int idx = FindMaxDistantPointIndex(points[0], points);

        //    int idxA = idx - 1;
        //    int idxB = idx + 1;

        //    if (idxA < 0)
        //    {
        //        idxA = points.Count - 1;
        //    }

        //    if (idxB >= points.Count)
        //    {
        //        idxB = idxB - points.Count;
        //    }

        //    CadVertex normal = CadMath.Normal(points[idx], points[idxA], points[idxB]);

        //    return normal;
        //}

        public static Vector3d TypicalNormal(VertexList points)
        {
            if (points.Count < 3)
            {
                return(Vector3d.Zero);
            }

            int idx = FindMaxDistantPointIndex(points[0], points);

            int idxA = idx - 1;
            int idxB = idx + 1;

            if (idxA < 0)
            {
                idxA = points.Count - 1;
            }

            if (idxB >= points.Count)
            {
                idxB = idxB - points.Count;
            }

            Vector3d normal = CadMath.Normal(points[idx].vector, points[idxA].vector, points[idxB].vector);

            return(normal);
        }
Beispiel #2
0
        private void drawCircle(DrawContext dc, DrawPen pen)
        {
            if (PointList.Count == 0)
            {
                return;
            }

            if (PointList.Count == 1)
            {
                dc.Drawing.DrawCross(pen, PointList[0].vector, 2);
                if (PointList[0].Selected)
                {
                    dc.Drawing.DrawSelectedPoint(PointList[0].vector, dc.GetPen(DrawTools.PEN_SELECT_POINT));
                }
                return;
            }

            Vector3d normal = CadMath.Normal(PointList[0].vector, PointList[2].vector, PointList[1].vector);

            CircleExpander.Draw(PointList[0], PointList[1], PointList[2], 32, dc, pen);

            double size = dc.DevSizeToWoldSize(4);

            dc.Drawing.DrawCross(pen, PointList[0].vector, size);
        }
Beispiel #3
0
        public void RotateEyePoint(Vector2 prev, Vector2 current)
        {
            Vector2 d = current - prev;

            double ry = (d.X / 10.0) * (Math.PI / 20);
            double rx = (d.Y / 10.0) * (Math.PI / 20);

            CadQuaternion q;
            CadQuaternion r;
            CadQuaternion qp;

            q = CadQuaternion.RotateQuaternion(Vector3d.UnitY, ry);

            r = q.Conjugate();

            qp   = CadQuaternion.FromVector(mEye);
            qp   = r * qp;
            qp   = qp * q;
            mEye = qp.ToVector3d();

            qp        = CadQuaternion.FromVector(mUpVector);
            qp        = r * qp;
            qp        = qp * q;
            mUpVector = qp.ToVector3d();

            Vector3d ev = mLookAt - mEye;

            Vector3d a = new Vector3d(ev);
            Vector3d b = new Vector3d(mUpVector);

            Vector3d axis = CadMath.Normal(a, b);

            if (!axis.IsZero())
            {
                q = CadQuaternion.RotateQuaternion(axis, rx);

                r = q.Conjugate();

                qp = CadQuaternion.FromVector(mEye);
                qp = r * qp;
                qp = qp * q;

                mEye = qp.ToVector3d();

                qp        = CadQuaternion.FromVector(mUpVector);
                qp        = r * qp;
                qp        = qp * q;
                mUpVector = qp.ToVector3d();
            }

            CalcViewMatrix();
            CalcViewDir();
            CalcProjectionZW();
        }
Beispiel #4
0
        public void PanCamera(DrawContext dc, Vector2 prev, Vector2 current)
        {
            Vector2 d = current - prev;

            double rx = d.X * (Math.PI / 1000);
            double ry = d.Y * (Math.PI / 1000);

            CadQuaternion q;
            CadQuaternion r;
            CadQuaternion qp;

            Vector3d lookv = dc.LookAt - dc.Eye;
            Vector3d upv   = dc.UpVector;

            q = CadQuaternion.RotateQuaternion(upv, rx);
            r = q.Conjugate();

            qp    = CadQuaternion.FromVector(lookv);
            qp    = r * qp;
            qp    = qp * q;
            lookv = qp.ToVector3d();

            Vector3d ev = dc.LookAt - dc.Eye;

            Vector3d a = new Vector3d(ev);
            Vector3d b = new Vector3d(upv);

            Vector3d axis = CadMath.Normal(a, b);

            if (!axis.IsZero())
            {
                q = CadQuaternion.RotateQuaternion(axis, ry);
                r = q.Conjugate();

                qp = CadQuaternion.FromVector(lookv);
                qp = r * qp;
                qp = qp * q;

                lookv = qp.ToVector3d();

                qp  = CadQuaternion.FromVector(upv);
                qp  = r * qp;
                qp  = qp * q;
                upv = qp.ToVector3d();
            }

            dc.SetCamera(dc.Eye, lookv + dc.Eye, upv);
        }
Beispiel #5
0
        public static void ForEachSegs(
            CadVertex cp, CadVertex pa, CadVertex pb,
            int splitCnt,
            Action <CadVertex, CadVertex> action)
        {
            CadVertex va = pa - cp;
            CadVertex vb = pb - cp;

            if (va.Norm() < 0.01)
            {
                return;
            }


            double dt = (2.0 * Math.PI) / (double)splitCnt;

            int div = splitCnt;

            Vector3d normal = CadMath.Normal(va.vector, vb.vector);

            CadQuaternion q = CadQuaternion.RotateQuaternion(normal, dt);
            CadQuaternion r = q.Conjugate();

            CadVertex p   = va;
            CadVertex tp1 = pa;
            CadVertex tp2 = pa;


            int i = 0;

            for (; i < div - 1; i++)
            {
                CadQuaternion qp = CadQuaternion.FromPoint(p.vector);
                qp = r * qp;
                qp = qp * q;

                p.vector = qp.ToPoint();

                tp2 = p + cp;

                action(tp1, tp2);
                tp1 = tp2;
            }

            action(tp1, pa);
        }
Beispiel #6
0
        public static void Draw(
            CadVertex cp, CadVertex pa, CadVertex pb,
            int splitCnt,
            DrawContext dc, DrawPen pen)
        {
            CadVertex va = pa - cp;
            CadVertex vb = pb - cp;

            if (va.Norm() < 0.01)
            {
                return;
            }

            double dt = (2.0 * Math.PI) / (double)splitCnt;

            int div = splitCnt;

            Vector3d normal = CadMath.Normal(va.vector, vb.vector);

            CadQuaternion q = CadQuaternion.RotateQuaternion(normal, dt);
            CadQuaternion r = q.Conjugate();

            CadVertex p   = va;
            CadVertex tp1 = pa;
            CadVertex tp2 = pa;


            int i = 0;

            for (; i < div - 1; i++)
            {
                CadQuaternion qp = CadQuaternion.FromPoint(p.vector);
                qp = r * qp;
                qp = qp * q;

                p.vector = qp.ToPoint();

                tp2 = p + cp;

                dc.Drawing.DrawLine(pen, tp1.vector, tp2.vector);
                tp1 = tp2;
            }

            dc.Drawing.DrawLine(pen, tp1.vector, pa.vector);
        }
Beispiel #7
0
        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);
            });
        }
Beispiel #8
0
        public static void DrawArrow(
            Action <DrawPen, Vector3d, Vector3d> DrawLine,
            DrawPen pen,
            Vector3d pt0,
            Vector3d pt1,
            ArrowTypes type,
            ArrowPos pos,
            double len,
            double width)
        {
            DrawLine(pen, pt0, pt1);

            Vector3d d = pt1 - pt0;

            double dl = d.Length;

            if (dl < 0.00001)
            {
                return;
            }


            Vector3d tmp = new Vector3d(dl, 0, 0);

            double angle = Vector3d.CalculateAngle(tmp, d);

            Vector3d normal = CadMath.CrossProduct(tmp, d);  // 回転軸

            if (normal.Length < 0.0001)
            {
                normal = new Vector3d(0, 0, 1);
            }
            else
            {
                normal = normal.UnitVector();
                normal = CadMath.Normal(tmp, d);
            }

            CadQuaternion q = CadQuaternion.RotateQuaternion(normal, -angle);
            CadQuaternion r = q.Conjugate();

            ArrowHead a;

            if (pos == ArrowPos.END || pos == ArrowPos.START_END)
            {
                a = ArrowHead.Create(type, ArrowPos.END, len, width);

                a.Rotate(q, r);

                a += pt1;

                DrawLine(pen, a.p0.vector, a.p1.vector);
                DrawLine(pen, a.p0.vector, a.p2.vector);
                DrawLine(pen, a.p0.vector, a.p3.vector);
                DrawLine(pen, a.p0.vector, a.p4.vector);
            }

            if (pos == ArrowPos.START || pos == ArrowPos.START_END)
            {
                a = ArrowHead.Create(type, ArrowPos.START, len, width);

                a.Rotate(q, r);

                a += pt0;

                DrawLine(pen, a.p0.vector, a.p1.vector);
                DrawLine(pen, a.p0.vector, a.p2.vector);
                DrawLine(pen, a.p0.vector, a.p3.vector);
                DrawLine(pen, a.p0.vector, a.p4.vector);
            }
        }
Beispiel #9
0
        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);
        }
Beispiel #10
0
        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);
            }
        }
Beispiel #11
0
        private void DrawCompassOrtho()
        {
            PushMatrixes();

            double size = 40;

            double vw = DC.ViewWidth;
            double vh = DC.ViewHeight;

            double cx = size / 2 + 24;
            double cy = size / 2 + 40;

            double left   = -cx;
            double right  = vw - cx;
            double top    = cy;
            double bottom = -(vh - cy);

            double arrowLen = 10;
            double arrowW2  = 5;

            Matrix4d prjm = Matrix4d.CreateOrthographicOffCenter(left, right, bottom, top, 100, 10000);

            GL.MatrixMode(MatrixMode.Projection);
            GL.LoadMatrix(ref prjm);

            GL.MatrixMode(MatrixMode.Modelview);
            Vector3d lookAt = Vector3d.Zero;
            Vector3d eye    = -DC.ViewDir * 300;

            Matrix4d mdlm = Matrix4d.LookAt(eye, lookAt, DC.UpVector);

            GL.LoadMatrix(ref mdlm);

            Vector3d p0;
            Vector3d p1;

            GL.LineWidth(2);

            p0 = Vector3d.UnitX * -size;
            p1 = Vector3d.UnitX * size;
            DrawArrow(DC.GetPen(DrawTools.PEN_AXIS_X), p0, p1, ArrowTypes.CROSS, ArrowPos.END, arrowLen, arrowW2);

            p0 = Vector3d.UnitY * -size;
            p1 = Vector3d.UnitY * size;
            DrawArrow(DC.GetPen(DrawTools.PEN_AXIS_Y), p0, p1, ArrowTypes.CROSS, ArrowPos.END, arrowLen, arrowW2);

            p0 = Vector3d.UnitZ * -size;
            p1 = Vector3d.UnitZ * size;
            DrawArrow(DC.GetPen(DrawTools.PEN_AXIS_Z), p0, p1, ArrowTypes.CROSS, ArrowPos.END, arrowLen, arrowW2);

            GL.LineWidth(1);

            FontTex tex;

            Vector3d xv = CadMath.Normal(DC.ViewDir, DC.UpVector);
            Vector3d yv = CadMath.Normal(DC.ViewDir, DC.UpVector);
            double   fs = 0.6;

            tex = mFontFaceW.CreateTexture("X");
            p1  = Vector3d.UnitX * size;
            GL.Color4(DC.GetBrush(DrawTools.BRUSH_COMPASS_LABEL_X).Color4());
            mFontRenderer.Render(tex, p1, xv * tex.ImgW * fs, DC.UpVector * tex.ImgH * fs);

            tex = mFontFaceW.CreateTexture("Y");
            p1  = Vector3d.UnitY * size;
            GL.Color4(DC.GetBrush(DrawTools.BRUSH_COMPASS_LABEL_Y).Color4());
            mFontRenderer.Render(tex, p1, xv * tex.ImgW * fs, DC.UpVector * tex.ImgH * fs);

            tex = mFontFaceW.CreateTexture("Z");
            p1  = Vector3d.UnitZ * size;
            GL.Color4(DC.GetBrush(DrawTools.BRUSH_COMPASS_LABEL_Z).Color4());
            mFontRenderer.Render(tex, p1, xv * tex.ImgW * fs, DC.UpVector * tex.ImgH * fs);

            PopMatrixes();
        }
Beispiel #12
0
        // 図形は凸である
        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);
        }
Beispiel #13
0
        private void CheckCircle(DrawContext dc, CadLayer layer, CadFigure fig)
        {
            if (fig.PointCount < 3)
            {
                return;
            }

            VertexList vl = fig.PointList;

            if (fig.StoreList != null)
            {
                vl = fig.StoreList;
            }

            Vector3d c      = vl[0].vector;
            Vector3d a      = vl[1].vector;
            Vector3d b      = vl[2].vector;
            Vector3d normal = CadMath.Normal(a - c, b - c);

            Vector3d tw = Target.Pos;

            tw.Z = 0;
            tw   = dc.DevPointToWorldPoint(tw);

            Vector3d crossP = CadMath.CrossPlane(tw, tw + dc.ViewDir, c, normal);

            if (crossP.IsInvalid())
            {
                // 真横から見ている場合
                // viewed edge-on
                //DOut.tpl("crossP is invalid");
                return;
            }

            double r  = (a - c).Norm();
            double tr = (crossP - c).Norm();

            Vector3d cirP = c + (crossP - c) * (r / tr);

            Vector3d dcirP   = dc.WorldPointToDevPoint(cirP);
            Vector3d dcrossP = dc.WorldPointToDevPoint(crossP);

            dcirP.Z   = 0;
            dcrossP.Z = 0;

            double dist = (dcirP - Target.Pos).Norm();

            if (dist > Range)
            {
                //DOut.tpl($"dist:{dist} Range:{Range}");
                return;
            }

            if (dist < MinDist)
            {
                FigureSegment fseg = new FigureSegment(fig, 0, 0, 0);

                MarkSeg.Layer          = layer;
                MarkSeg.FigSeg         = fseg;
                MarkSeg.CrossPoint     = cirP;
                MarkSeg.CrossPointScrn = dc.WorldPointToDevPoint(cirP);
                MarkSeg.Distance       = dist;

                MinDist = dist;
            }
        }
Beispiel #14
0
        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);
        }