Exemplo n.º 1
0
        // 点pから直線abに向かう垂線との交点を求める
        public static CrossInfo PerpCrossLine(Vector3d a, Vector3d b, Vector3d p)
        {
            CrossInfo ret = default;

            if (a.Equals(b))
            {
                return(ret);
            }

            Vector3d ab = b - a;
            Vector3d ap = p - a;

            // A-B 単位ベクトル
            Vector3d unit_ab = ab.UnitVector();

            // Aから交点までの距離
            double dist_ax = InnerProduct(unit_ab, ap);

            ret.CrossPoint.X = a.X + (unit_ab.X * dist_ax);
            ret.CrossPoint.Y = a.Y + (unit_ab.Y * dist_ax);
            ret.CrossPoint.Z = a.Z + (unit_ab.Z * dist_ax);

            ret.IsCross = true;

            return(ret);
        }
Exemplo n.º 2
0
        private void CheckFigPoint(DrawContext dc, Vector3d pt, CadLayer layer, CadFigure fig, int ptIdx)
        {
            Vector3d ppt = dc.WorldPointToDevPoint(pt);

            double dx = Math.Abs(ppt.X - Target.Pos.X);
            double dy = Math.Abs(ppt.Y - Target.Pos.Y);

            CrossInfo cix = CadMath.PerpCrossLine(Target.Pos, Target.Pos + Target.DirX, ppt);
            CrossInfo ciy = CadMath.PerpCrossLine(Target.Pos, Target.Pos + Target.DirY, ppt);

            double nx = (ppt - ciy.CrossPoint).Norm(); // Cursor Y軸からの距離
            double ny = (ppt - cix.CrossPoint).Norm(); // Cursor X軸からの距離

            if (nx <= Range)
            {
                if (nx < XMatch.DistanceX || (nx == XMatch.DistanceX && ny < XMatch.DistanceY))
                {
                    XMatch = GetMarkPoint(pt, ppt, nx, ny, layer, fig, ptIdx);
                }
            }

            if (ny <= Range)
            {
                if (ny < YMatch.DistanceY || (ny == YMatch.DistanceY && nx < YMatch.DistanceX))
                {
                    YMatch = GetMarkPoint(pt, ppt, nx, ny, layer, fig, ptIdx);
                }
            }

            if (dx <= Range && dy <= Range)
            {
                double minDist = (XYMatch.DistanceX * XYMatch.DistanceX) + (XYMatch.DistanceY * XYMatch.DistanceY);
                double curDist = (dx * dx) + (dy * dy);

                if (curDist <= minDist)
                {
                    MarkPoint t = GetMarkPoint(pt, ppt, dx, dy, layer, fig, ptIdx);

                    //t.dump();

                    XYMatch = t;

                    if (!XYMatchSet.Contains(t))
                    {
                        XYMatchList.Add(XYMatch);
                        XYMatchSet.Add(XYMatch);
                        //DOut.pl($"PointSearcher XYMatchList cnt:{XYMatchList.Count}");
                    }
                }
            }
        }
Exemplo n.º 3
0
        //
        // 点pを通り、a - b に平行で、a-bに垂直な線分を求める
        //
        //   +----------p------------+
        //   |                       |
        //   |                       |
        //   a                       b
        //
        public static CadSegment PerpSeg(CadVertex a, CadVertex b, CadVertex p)
        {
            CadSegment seg = default(CadSegment);

            seg.P0 = a;
            seg.P1 = b;

            CrossInfo ci = CadMath.PerpCrossLine(a.vector, b.vector, p.vector);

            if (ci.IsCross)
            {
                CadVertex nv = p - ci.CrossPoint;

                seg.P0 += nv;
                seg.P1 += nv;
            }

            return(seg);
        }
Exemplo n.º 4
0
        public static EditResult CutSegment(CadObjectDB db, MarkSegment seg, Vector3d p)
        {
            EditResult result = new EditResult();

            if (seg.Figure.Type != CadFigure.Types.POLY_LINES)
            {
                return(result);
            }

            CrossInfo ci = CadMath.PerpendicularCrossSeg(seg.pA.vector, seg.pB.vector, p);

            if (!ci.IsCross)
            {
                return(result);
            }

            CadFigure org = db.GetFigure(seg.FigureID);

            int a = Math.Min(seg.PtIndexA, seg.PtIndexB);
            int b = Math.Max(seg.PtIndexA, seg.PtIndexB);


            CadFigure fa = db.NewFigure(CadFigure.Types.POLY_LINES);
            CadFigure fb = db.NewFigure(CadFigure.Types.POLY_LINES);

            fa.AddPoints(org.PointList, 0, a + 1);
            fa.AddPoint(new CadVertex(ci.CrossPoint));

            fb.AddPoint(new CadVertex(ci.CrossPoint));
            fb.AddPoints(org.PointList, b);

            if (org.IsLoop)
            {
                fb.AddPoint(fa.GetPointAt(0));
            }

            result.AddList.Add(new EditResult.Item(seg.LayerID, fa));
            result.AddList.Add(new EditResult.Item(seg.LayerID, fb));
            result.RemoveList.Add(new EditResult.Item(org.LayerID, org));

            return(result);
        }
Exemplo n.º 5
0
        // 点pから直線abに向かう垂線との交点を求める2D
        public static CrossInfo PerpendicularCrossLine2D(Vector3d a, Vector3d b, Vector3d p)
        {
            CrossInfo ret = default;

            double t1;

            Vector3d ab = b - a;
            Vector3d ap = p - a;

            t1 = InnrProduct2D(ab, ap);

            double norm  = ab.Norm2D();
            double norm2 = norm * norm;

            ret.IsCross      = true;
            ret.CrossPoint.X = ab.X * t1 / norm2 + a.X;
            ret.CrossPoint.Y = ab.Y * t1 / norm2 + a.Y;

            return(ret);
        }
Exemplo n.º 6
0
        // 点pから線分abに向かう垂線との交点を求める2D
        public static CrossInfo PerpendicularCrossSeg2D(Vector3d a, Vector3d b, Vector3d p)
        {
            CrossInfo ret = default;

            double t1;

            Vector3d ab = b - a;
            Vector3d ap = p - a;

            t1 = InnrProduct2D(ab, ap);

            if (t1 < 0)
            {
                return(ret);
            }

            double t2;

            Vector3d ba = a - b;
            Vector3d bp = p - b;

            t2 = InnrProduct2D(ba, bp);

            if (t2 < 0)
            {
                return(ret);
            }

            double abl  = ab.Norm2D();
            double abl2 = abl * abl;

            ret.IsCross      = true;
            ret.CrossPoint.X = ab.X * t1 / abl2 + a.X;
            ret.CrossPoint.Y = ab.Y * t1 / abl2 + a.Y;

            return(ret);
        }
Exemplo n.º 7
0
        // 点pから線分abに向かう垂線との交点を求める
        public static CrossInfo PerpendicularCrossSeg(Vector3d a, Vector3d b, Vector3d p)
        {
            CrossInfo ret = default;

            Vector3d ab = b - a;
            Vector3d ap = p - a;

            Vector3d ba = a - b;
            Vector3d bp = p - b;

            // A-B 単位ベクトル
            Vector3d unit_ab = ab.UnitVector();

            // B-A 単位ベクトル (A-B単位ベクトルを反転) B側の中外判定に使用
            Vector3d unit_ba = unit_ab * -1.0;

            // Aから交点までの距離
            // A->交点->B or A->B->交点なら +
            // 交点<-A->B なら -
            double dist_ax = InnerProduct(unit_ab, ap);

            // Bから交点までの距離 B側の中外判定に使用
            double dist_bx = InnerProduct(unit_ba, bp);

            //Console.WriteLine("getNormCross dist_ax={0} dist_bx={1}" , dist_ax.ToString(), dist_bx.ToString());

            if (dist_ax > 0 && dist_bx > 0)
            {
                ret.IsCross = true;
            }

            ret.CrossPoint.X = a.X + (unit_ab.X * dist_ax);
            ret.CrossPoint.Y = a.Y + (unit_ab.Y * dist_ax);
            ret.CrossPoint.Z = a.Z + (unit_ab.Z * dist_ax);

            return(ret);
        }