Exemple #1
0
        public CPointControl(CPoint point)
        {
            InitializeComponent();

            StrCoordX = point.m_dX.ToString();
            StrCoordY = point.m_dY.ToString();

            IsArc          = (point.m_emLineKind == EMLineKind.ARC) ? true : false;
            IsArcDirection = (point.m_emDirectionArc == EMDirectionArc.BACKWARD) ? true : false;
        }
Exemple #2
0
        public CPointUI(CPoint point)
        {
            InitializeComponent();

            StrCoordX = point.X.ToString();
            StrCoordZ = point.Y.ToString();

            IsArc          = (point.LineKind == EMLineKind.ARC) ? true : false;
            IsArcDirection = (point.DirectionArc == EMDirectionArc.BACKWARD) ? true : false;
        }
Exemple #3
0
        public CLine(CPoint start, CPoint end)
        {
            m_startPoint.X = start.X;
            m_startPoint.Y = start.Y;
            m_endPoint.X   = end.X;
            m_endPoint.Y   = end.Y;

            /// Line 정보는 Start 점에 담겨있는 정보를 사용한다.
            m_startPoint.LineKind     = start.LineKind;
            m_startPoint.DirectionArc = start.DirectionArc;
        }
Exemple #4
0
        /// <summary>
        /// 경계조건의 부여되는 외각 Region 을 그리고 경계조건을 부여한다.
        /// </summary>
        /// <param name="femm">FEMM</param>
        /// <param name="x1">사각형 첫점의 X 좌표</param>
        /// <param name="y1">사각형 첫점의 Y 좌표</param>
        /// <param name="x2">사각형 둘째점의 X 좌표</param>
        /// <param name="y2">사각형 둘째점의 Y 좌표</param>
        /// <param name="dMeshSize"></param>
        public void setOutsideBoundary(CScriptFEMM femm, double x1, double y1, double x2, double y2, double dMeshSize = 0)
        {
            femm.addBoundaryConditon();

            setRectanglePoints(x1, y1, x2, y2);

            double maxX   = (x1 > x2) ? x1 : x2;
            double maxY   = (y1 > y2) ? y1 : y2;
            double width  = Math.Abs(x2 - x1);
            double height = Math.Abs(y2 - y1);

            CPoint blockPoint = new CPoint();

            // 좌상단 구석에 block point 좌표를 얻어낸다.
            // Region 은 무조건 직사각형이기 때문에 촤상단 점의 근접점이 내부점이 될 수 있다.
            blockPoint.X = maxX - width / 1000.0f;
            blockPoint.Y = maxY - height / 1000.0f;

            femm.setRegionBlockProp(blockPoint, dMeshSize);

            double sx, sy, ex, ey;

            /// 매번 생성하는 Property 이기 때문에
            /// LineList 는 새로운 List에  담는 동작 한번만 호출하고, 사용은 새로운 List 를 사용한다.
            List <CPoint> listAbsolutePoint = new List <CPoint>();

            listAbsolutePoint = AbsolutePointList;

            // 좌변을 제외하고 하변, 상변, 우변에만 경계조건이 부여된다.
            for (int i = 0; i < listAbsolutePoint.Count; i++)
            {
                // 마지막 Point 만 제외한다.
                if (i < listAbsolutePoint.Count - 1)
                {
                    sx = listAbsolutePoint[i].X;
                    sy = listAbsolutePoint[i].Y;
                    ex = listAbsolutePoint[i + 1].X;
                    ey = listAbsolutePoint[i + 1].Y;

                    femm.drawBoundaryLine(sx, sy, ex, ey);
                }
                /// 마지막 선은 끝점과 첫점을 있는다
                /// 마지막 선은 좌변 라인으로 경계조건이 필요 없다.
                else
                {
                    sx = listAbsolutePoint[i].X;
                    sy = listAbsolutePoint[i].Y;
                    ex = listAbsolutePoint[0].X;
                    ey = listAbsolutePoint[0].Y;

                    femm.drawLine(sx, sy, ex, ey);
                }
            }
        }
Exemple #5
0
        public CLine(CPoint start, CPoint end)
        {
            m_startPoint.m_dX = start.m_dX;
            m_startPoint.m_dY = start.m_dY;
            m_endPoint.m_dX   = end.m_dX;
            m_endPoint.m_dY   = end.m_dY;

            /// Line 정보는 Start 점에 담겨있는 정보를 사용한다.
            m_startPoint.m_emLineKind     = start.m_emLineKind;
            m_startPoint.m_emDirectionArc = start.m_emDirectionArc;
        }
Exemple #6
0
        /// <summary>
        /// 경계조건의 부여되지 않는 내부 Region 을 그린다. (단, 경계조건은 부여하지 않음)
        /// </summary>
        /// <param name="femm">FEMM</param>
        /// <param name="x1">사각형 첫점의 X 좌표</param>
        /// <param name="y1">사각형 첫점의 Y 좌표</param>
        /// <param name="x2">사각형 둘째점의 X 좌표</param>
        /// <param name="y2">사각형 둘째점의 Y 좌표</param>
        /// <param name="dMeshSize">Mesh Size (0 이면 Auto Mesh)</param>
        public void setInsideRegion(CScriptFEMM femm, double x1, double y1, double x2, double y2, double dMeshSize = 0)
        {
            setRectanglePoints(x1, y1, x2, y2);

            double maxX   = (x1 > x2) ? x1 : x2;
            double maxY   = (y1 > y2) ? y1 : y2;
            double width  = Math.Abs(x2 - x1);
            double height = Math.Abs(y2 - y1);

            CPoint blockPoint = new CPoint();

            // 좌상단 구석에 block point 좌표를 얻어낸다.
            blockPoint.m_dX = maxX - width / 100.0f;
            blockPoint.m_dY = maxY - height / 100.0f;

            femm.setRegionBlockProp(blockPoint, dMeshSize);

            double sx, sy, ex, ey;

            /// 매번 생성하는 Property 이기 때문에
            /// LineList 는 새로운 List에  담는 동작 한번만 호출하고, 사용은 새로운 List 를 사용한다.
            List <CPoint> listAbsolutePoint = new List <CPoint>();

            listAbsolutePoint = AbsolutePointList;

            // 좌변을 제외하고 하변, 상변, 우변에만 경계조건이 부여된다.
            for (int i = 0; i < listAbsolutePoint.Count; i++)
            {
                // 마지막 Point 만 제외한다.
                if (i < listAbsolutePoint.Count - 1)
                {
                    sx = listAbsolutePoint[i].m_dX;
                    sy = listAbsolutePoint[i].m_dY;
                    ex = listAbsolutePoint[i + 1].m_dX;
                    ey = listAbsolutePoint[i + 1].m_dY;

                    /// 경계조건은 부여하지 않음
                    femm.drawLine(sx, sy, ex, ey);
                }
                // 마지막 선은 끝점과 첫점을 있는다
                else
                {
                    sx = listAbsolutePoint[i].m_dX;
                    sy = listAbsolutePoint[i].m_dY;
                    ex = listAbsolutePoint[0].m_dX;
                    ey = listAbsolutePoint[0].m_dY;

                    femm.drawLine(sx, sy, ex, ey);
                }
            }
        }
Exemple #7
0
        /// <summary>
        /// Face 안의 부품의 속성을 입력하기 위한 BlockPoint 를 얻어낸다.
        ///
        /// 절대좌표의 내부 블럭점을 찾는 것이기 때문에 절대 좌표를 사용해야 한다.
        /// </summary>
        /// <returns>Block Point</returns>
        public CPoint getBlockPoint()
        {
            CPoint blockPoint = new CPoint();

            double sumX = 0;
            double sumY = 0;

            /// Rectangle 은 4 좌표의 평균점을 사용한다.
            if (FaceType == EMFaceType.RECTANGLE)
            {
                /// 매번 생성하는 Property 이기 때문에
                /// LineList 는 새로운 List에  담는 동작 한번만 호출하고, 사용은 새로운 List 를 사용한다.
                List <CPoint> listAbsolutePoint = new List <CPoint>();
                listAbsolutePoint = AbsolutePointList;

                foreach (CPoint point in listAbsolutePoint)
                {
                    sumX += point.X;
                    sumY += point.Y;
                }

                blockPoint.X = sumX / listAbsolutePoint.Count;
                blockPoint.Y = sumY / listAbsolutePoint.Count;
            }
            else
            {
                double minX, maxX, minY, maxY;
                minX = maxX = minY = maxY = 0;

                getMinMaxX(ref minX, ref maxX);
                getMinMaxY(ref minY, ref maxY);

                CPoint retBlockPoint = m_shapeTools.findInsidePoint(this, minX, maxX, minY, maxY);

                if (retBlockPoint != null)
                {
                    blockPoint = retBlockPoint;
                }
                else
                {
                    // 예외 처리를 한다.
                    blockPoint.X = 0;
                    blockPoint.Y = 0;
                }
            }

            return(blockPoint);
        }
Exemple #8
0
        /// <summary>
        /// Face 안의 부품의 속성을 입력하기 위한 BlockPoint 를 얻어낸다.
        ///
        /// 절대좌표의 내부 블럭점을 찾는 것이기 때문에 절대 좌표를 사용해야 한다.
        /// </summary>
        /// <returns>Block Point</returns>
        public CPoint getBlockPoint()
        {
            CPoint blockPoint = new CPoint();

            double sumX = 0;
            double sumY = 0;

            /// Rectangle 은 4 좌표의 평균점을 사용한다.
            if (FaceType == EMFaceType.RECTANGLE)
            {
                /// 매번 생성하는 Property 이기 때문에
                /// LineList 는 새로운 List에  담는 동작 한번만 호출하고, 사용은 새로운 List 를 사용한다.
                List <CPoint> listAbsolutePoint = new List <CPoint>();
                listAbsolutePoint = AbsolutePointList;

                foreach (CPoint point in listAbsolutePoint)
                {
                    sumX += point.m_dX;
                    sumY += point.m_dY;
                }

                blockPoint.m_dX = sumX / listAbsolutePoint.Count;
                blockPoint.m_dY = sumY / listAbsolutePoint.Count;
            }
            else
            {
                double minX, maxX, minY, maxY;
                minX = maxX = minY = maxY = 0;

                getMinMaxX(ref minX, ref maxX);
                getMinMaxY(ref minY, ref maxY);

                blockPoint = m_shapeTools.findInsidePoint(this, minX, maxX, (minY + maxY) / 2.0f);

                /// 기준 높이 Base Y 에 Face 의 절점이 위치하면,
                /// 내부점을 찾지 못해서 null 이 넘어오면 Base Y 값을 변경하여 다시 한번 시도해 본다.
                /// 만약, 두번째의 시도에도 null 이 넘어오면 Block Point 의 재질을 입력하지 않도록 null 을 그대로 리턴한다.
                if (blockPoint == null)
                {
                    blockPoint = m_shapeTools.findInsidePoint(this, minX, maxX, (minY + maxY) / 2.0f + (minY - maxY) / 10.0f);
                }
            }

            return(blockPoint);
        }
        /// <summary>
        /// 형상 입력때나 수정때 형상을 다시 그린다
        ///  - 수정 부품만 빼고 타 부품들은 다시 그리고, 수정 부품은 창에 기록된 값을 그린다.
        /// </summary>
        /// <param name="pointControl">좌표점 PointControl</param>
        /// <param name="bRedraw">형상 수정이 없어도 강제로 ARC 변경때 강제로 수정함</param>
        internal void drawTemporaryFace(CPointUI pointControl, bool bRedraw = false)
        {
            try
            {
                /// [문제]
                ///  - Form 에서는 Parent를 사용할 수 없어 Owner 속성을 사용하지만
                ///    종종 Owner 가 null 로 넘어오는 문제가 발생한다.
                /// [해결]
                ///  - PopupShape 창을 생성하기 전에 Owner 속성을 FormMain 으로 초기화 해 두어야
                ///    확실하게 FormMain 을 얻을 수 있다.
                FormMain formMain = ((FormMain)this.Owner);

                if (formMain == null)
                {
                    CNotice.printLogID("CNGM");
                    return;
                }

                CScriptFEMM femm = formMain.m_femm;

                CDataNode nodeParts = formMain.m_design.getNode(m_strPartName);

                /// 0. 해당 좌표점의 수정이 있었는지를 판단한다.
                ///  - 수정이 있는 경우만 다시 그리기 위해서이다.
                bool retCheck = false;

                /// 초기 생성때는 이전 nodeParts 가 없음으로 사용하지 않고, 기존 노드의 수정때만 사용한다.
                if (nodeParts != null)
                {
                    /// 좌표 Control 에 빈칸이 존재하는 지를 확인함
                    for (int i = 0; i < ListPointUI.Count; i++)
                    {
                        /// 해당 좌표점만 비교한다.
                        /// 만약, Parts 의 모든 좌표점을 비교하면 다른 좌표점이 수정되었을때 나머지 좌표점의 수정이 없어도 다시 그리기가 된다.
                        if (ListPointUI[i] == pointControl)
                        {
                            if (((CShapeParts)nodeParts).Face.RelativePointList[i].X != Double.Parse(ListPointUI[i].StrCoordX.Trim()))
                            {
                                retCheck = true;
                            }

                            if (((CShapeParts)nodeParts).Face.RelativePointList[i].Y != Double.Parse(ListPointUI[i].StrCoordZ.Trim()))
                            {
                                retCheck = true;
                            }
                        }
                    }
                }

                // Arc 관련 이벤트 호출이면 강제로 다시그리기를 한다.
                if (bRedraw == true)
                {
                    retCheck = true;
                }

                if (retCheck == true)
                {
                    femm.deleteAll();

                    /// 1. 혹시 수정중이라면, 현재 작업 중인 Face 를 제외하고 형상 그리기
                    foreach (CDataNode node in formMain.m_design.GetNodeList)
                    {
                        if (node.GetType().BaseType.Name == "CShapeParts")
                        {
                            if (node.NodeName != m_strPartName)
                            {
                                ((CShapeParts)node).Face.drawFace(femm);
                            }
                        }
                    }
                }

                /// 2. 현재 수정중이거나 생성중인 Face 의 형상 그리기
                retCheck = true;

                /// 좌표 Control 에 빈칸이 존재하는 지를 확인함
                for (int i = 0; i < ListPointUI.Count; i++)
                {
                    if (ListPointUI[i].StrCoordX.Trim().Length == 0)
                    {
                        retCheck = false;
                    }

                    if (ListPointUI[i].StrCoordZ.Trim().Length == 0)
                    {
                        retCheck = false;
                    }
                }

                double dBase_X, dBase_Y;
                dBase_X = dBase_Y = 0;

                dBase_X = Double.Parse(textBoxBaseX.Text.Trim());
                dBase_Y = Double.Parse(textBoxBaseY.Text.Trim());

                // 모든 데이터가 입력된 경우는 폐곡선의 정상적인 Face 를 그린다.
                if (retCheck == true)
                {
                    CFace faceTemp = makeFaceInPopup();

                    if (null != faceTemp)
                    {
                        faceTemp.drawFace(femm);
                    }
                    else
                    {
                        CNotice.printLogID("TSWN");
                    }
                }
                // 모든 데이터가 아직 입력되지 않은 상태는 입력중인 데이터만으로 그림을 그린다.
                else
                {
                    double dP1_X, dP1_Y, dP2_X, dP2_Y;

                    bool bArc, bArcDirection;

                    dP1_X = dP1_Y = dP2_X = dP2_Y = 0;
                    bArc  = bArcDirection = false;

                    for (int i = 0; i < ListPointUI.Count; i++)
                    {
                        retCheck = true;

                        if (ListPointUI[i].StrCoordX.Trim().Length == 0)
                        {
                            retCheck = false;
                        }
                        else
                        {
                            dP1_X = Double.Parse(ListPointUI[i].StrCoordX.Trim()) + dBase_X;
                        }

                        if (ListPointUI[i].StrCoordZ.Trim().Length == 0)
                        {
                            retCheck = false;
                        }
                        else
                        {
                            dP1_Y = Double.Parse(ListPointUI[i].StrCoordZ.Trim()) + dBase_Y;
                        }

                        /// X, Y 값이 모두 입력된 Point Control 인 경우
                        if (retCheck == true)
                        {
                            if (i == 0)
                            {
                                /// 사각형, 다각형 모두 적용된다.
                                femm.drawPoint(dP1_X, dP1_Y);
                            }
                            else
                            {
                                if (this.FaceType == EMFaceType.RECTANGLE)
                                {
                                    CNotice.printLogID("ATTW");
                                }
                                /// 다각형만 적용된다.
                                /// 만약 사각형의 경우 i = 1 까지 모두 채워지면 모두 입력된 상태로 if 문의 위에처 처리되기 때문이다.
                                bArc          = ListPointUI[i].IsArc;
                                bArcDirection = ListPointUI[i].IsArcDirection;

                                if (bArc == true)
                                {
                                    femm.drawArc(dP2_X, dP2_Y, dP1_X, dP1_Y, bArcDirection);
                                }
                                else
                                {
                                    femm.drawLine(dP2_X, dP2_Y, dP1_X, dP1_Y);
                                }
                            }

                            // 이번 점을 이전 점으로 저장한다.
                            dP2_X = dP1_X;
                            dP2_Y = dP1_Y;
                        }
                        /// 채워지지 않은 좌표값을 발견하면 바로 빠져 나간다
                        else
                        {
                            break;
                        }
                    }
                }

                /// 선택된 좌표점을 붉은 색으로 표시한다.
                ///
                /// Base X, Y 변경 할때나 Leave 이벤트는 제외해야 함으로 null 을 넘겨오도록 되어 있다.
                if (pointControl != null)
                {
                    /// XY 값 모두 들어 있는 경우에만 표시를 한다.
                    if (pointControl.StrCoordX != "" && pointControl.StrCoordZ != "")
                    {
                        CPoint selectedPoint = new CPoint();

                        selectedPoint.X = Double.Parse(pointControl.StrCoordX) + dBase_X;
                        selectedPoint.Y = Double.Parse(pointControl.StrCoordZ) + dBase_Y;

                        femm.clearSelected();

                        femm.selectPoint(selectedPoint);
                    }
                }
            }
            catch (Exception ex)
            {
                CNotice.printLog(ex.Message);
            }
        }
        // Base Point 와 상대좌표로 좌표값이 저장되는 Face 가 생성된다.
        public CFace makeFaceInPopup()
        {
            try
            {
                CFace face = new CFace();

                face.BasePoint.X = Double.Parse(textBoxBaseX.Text);
                face.BasePoint.Y = Double.Parse(textBoxBaseY.Text);

                if (FaceType == EMFaceType.RECTANGLE)
                {
                    if (ListPointUI.Count != 2)
                    {
                        CNotice.printLogID("TATP1");
                        return(null);
                    }

                    double x1, y1, x2, y2;

                    x1 = Double.Parse(ListPointUI[0].StrCoordX);
                    y1 = Double.Parse(ListPointUI[0].StrCoordZ);
                    x2 = Double.Parse(ListPointUI[1].StrCoordX);
                    y2 = Double.Parse(ListPointUI[1].StrCoordZ);

                    face.setRectanglePoints(x1, y1, x2, y2);
                }
                else
                {
                    if (ListPointUI.Count < 4)
                    {
                        CNotice.printLogID("TANM");
                        return(null);
                    }

                    // PartType 가 코일이고 Polygon 형상을 가지고 있는 경우라면 (DXF로 읽어드리고 코일로 지정하는 경우)
                    // Rectangle 로 바꾸어 저장한다.
                    // 만약, Retangle 조건이 아니라면 지나쳐서 Polygon 으로 저장한다.
                    if (PartType == EMKind.COIL)
                    {
                        CFace retFace = makeRectangleFaceInPopup();

                        if (retFace != null)
                        {
                            return(retFace);
                        }
                    }

                    List <CPoint> listPoint = new List <CPoint>();

                    foreach (CPointUI pointControl in ListPointUI)
                    {
                        // 매번 신규로 생성을 해야 한다.
                        CPoint point = new CPoint();

                        point.X = Double.Parse(pointControl.StrCoordX);
                        point.Y = Double.Parse(pointControl.StrCoordZ);

                        if (pointControl.IsArc == true)
                        {
                            point.LineKind = EMLineKind.ARC;
                        }
                        else
                        {
                            point.LineKind = EMLineKind.STRAIGHT;
                        }

                        if (pointControl.IsArcDirection == true)
                        {
                            point.DirectionArc = EMDirectionArc.BACKWARD;
                        }
                        else
                        {
                            point.DirectionArc = EMDirectionArc.FORWARD;
                        }

                        listPoint.Add(point);
                    }

                    face.setPolygonPoints(listPoint);
                }

                return(face);
            }
            catch (Exception ex)
            {
                CNotice.printLog(ex.Message);
                return(null);
            }
        }
Exemple #11
0
        /// <summary>
        /// 선 위에 다른 점이 올라가 있는 지를 검사한다.
        /// </summary>
        public bool isPerchedOnLine(CLine line, CPoint point)
        {
            double dL_P1_X = line.m_startPoint.X;
            double dL_P1_Y = line.m_startPoint.Y;

            double dL_P2_X = line.m_endPoint.X;
            double dL_P2_Y = line.m_endPoint.Y;

            double dP_X = point.X;
            double dP_Y = point.Y;

            /// 라인의 X 구간
            double dBigX   = Math.Max(dL_P1_X, dL_P2_X);
            double dSmallX = Math.Min(dL_P1_X, dL_P2_X);

            /// 라인의 Y 구간
            double dBigY   = Math.Max(dL_P1_Y, dL_P2_Y);
            double dSmallY = Math.Min(dL_P1_Y, dL_P2_Y);

            /// 직선이 수직선인 경우는 예외 처리한다.
            if (isEqual(dL_P2_X, dL_P1_X))
            {
                /// 점의 X 좌표가 직선의 X 좌표와 일치하면 라인 위의 점이다.
                if (isEqual(dL_P1_X, dP_X))
                {
                    if (roundDigitOfShape(dBigY) >= roundDigitOfShape(dP_Y) && roundDigitOfShape(dSmallY) <= roundDigitOfShape(dP_Y))
                    {
                        return(true);
                    }
                }
            }
            /// 직선이 수평선인 경우는 예외 처리한다.
            else if (isEqual(dL_P2_Y, dL_P1_Y))
            {
                /// 점의 Y 좌표가 직선의 Y 좌표와 일치하면 라인 위의 점이다.
                if (isEqual(dL_P1_Y, dP_Y))
                {
                    if (roundDigitOfShape(dBigX) >= roundDigitOfShape(dP_X) && roundDigitOfShape(dSmallX) <= roundDigitOfShape(dP_X))
                    {
                        return(true);
                    }
                }
            }
            else
            {
                /// 라인의 직선방정식 기울기와 Y 절편을 계산한다.
                double dL_A = (dL_P2_Y - dL_P1_Y) / (dL_P2_X - dL_P1_X);
                double dL_B = dL_P1_Y - dL_A * (dL_P1_X);

                /// 라인의 직선방정식에 점의 X 값을 입력하여 Y 값을 계산한다.
                double dP_Calc_Y = dL_A * dP_X + dL_B;

                /// 계산된 Y 값과 좌표 Y 값이 일치하면 직선의 방정식위에 있는 점이다.
                if (isEqual(dP_Calc_Y, dP_Y))
                {
                    /// 직선의 방정식 위에 있는 점 중에서 실제 라인 위에 있는 점인지를 판단한다.
                    if ((roundDigitOfShape(dBigX) >= roundDigitOfShape(dP_X) && roundDigitOfShape(dSmallX) <= roundDigitOfShape(dP_X)) && (roundDigitOfShape(dBigY) >= roundDigitOfShape(dP_Y) && roundDigitOfShape(dSmallY) <= roundDigitOfShape(dP_Y)))
                    {
                        return(true);
                    }
                }
            }

            return(false);
        }
Exemple #12
0
        public bool readObject(List <string> listStringLines)
        {
            string strTemp;

            string[] arrayString;

            try
            {
                CPoint point = null;

                // 형상 라인을 처리한다.
                foreach (string strLine in listStringLines)
                {
                    strTemp = strLine.Trim('\t');

                    arrayString = strTemp.Split('=');

                    /// 각 줄의 String 배열은 항상 2개이여야 한다.
                    if (arrayString.Length != 2)
                    {
                        CNotice.noticeWarningID("TIAP5");
                        return(false);
                    }

                    switch (arrayString[0])
                    {
                    case "BasePointX":
                        BasePoint.X = Double.Parse(arrayString[1]);
                        break;

                    case "BasePointY":
                        BasePoint.Y = Double.Parse(arrayString[1]);
                        break;

                    case "FaceType":
                        FaceType = (EMFaceType)Enum.Parse(typeof(EMFaceType), arrayString[1]);
                        break;

                    case "PointX":
                        // PointX 키워드를 만날때 새로운 CPoint 생성하고,
                        // ArcDriction 키워드를 만날때 생성된 CPoint 를 Face 에 추가한다.
                        // 따라서 저장될때 X, Y, LineKind, ArcDriction 의 순서로 꼭 저장 되어야 한다.
                        point   = new CPoint();
                        point.X = Double.Parse(arrayString[1]);
                        break;

                    case "PointY":
                        if (point != null)
                        {
                            point.Y = Double.Parse(arrayString[1]);
                        }
                        else
                        {
                            CNotice.noticeWarningID("YCWX");
                            return(false);
                        }
                        break;

                    case "LineKind":
                        if (point != null)
                        {
                            point.LineKind = (EMLineKind)Enum.Parse(typeof(EMLineKind), arrayString[1]);
                        }
                        else
                        {
                            CNotice.noticeWarningID("TIAP9");
                            return(false);
                        }
                        break;

                    case "ArcDriction":
                        if (point != null)
                        {
                            point.DirectionArc = (EMDirectionArc)Enum.Parse(typeof(EMDirectionArc), arrayString[1]);
                        }
                        else
                        {
                            CNotice.noticeWarningID("TIAP10");
                            return(false);
                        }

                        // ArcDriction 에서 point 을 저장한다.
                        addPoint(point);
                        break;

                    default:
                        break;
                    }
                }
            }
            catch (Exception ex)
            {
                CNotice.printLog(ex.Message);
                return(false);
            }

            return(true);
        }
Exemple #13
0
        public bool addPoint(CPoint point)
        {
            m_listRelativePoint.Add(point);

            return(true);
        }
Exemple #14
0
        /// <summary>
        /// 재귀호출을 사용해서 FACE 내부점을 찾아낸다.
        /// 재질 블럭점을 찾는 것이기 때문에 절대좌표를 사용해야 한다.
        ///
        /// 참고 사이트 : http://bowbowbow.tistory.com/24
        /// </summary>
        /// <param name="minX">내부점을 찾는 구간의 X 점 최소값</param>
        /// <param name="maxX">내부점을 찾는 구간의 X 점 최대값</param>
        /// <param name="baseY">내부 좌표값을 찾은 Y 위치 </param>
        /// <returns></returns>
        public CPoint findInsidePoint(CFace face, double minX, double maxX, double minY, double maxY)
        {
            int nRightIntersection = 0;
            int nLeftIntersection  = 0;

            int nRightPerchedPointOnCheckLine = 0;
            int nLeftPerchedPointOnCheckLine  = 0;

            int nPerchedCenterPointOnFaceLine = 0;

            CLine rightCheckLine = new CLine();
            CLine leftCheckLine  = new CLine();

            CPoint centerPoint = new CPoint();

            double baseY   = (minY + maxY) / 2.0f;
            double centerX = (minX + maxX) / 2.0f;

            //// 너무 작은 소수점 이하는 정리한다.
            minX  = roundDigitOfShape(minX);
            maxX  = roundDigitOfShape(maxX);
            baseY = roundDigitOfShape(baseY);

            // 중심점을 만든다.
            centerPoint.X = centerX;
            centerPoint.Y = baseY;

            /// create a right check line
            rightCheckLine.m_startPoint.X = centerX;
            rightCheckLine.m_startPoint.Y = baseY;
            rightCheckLine.m_endPoint.X   = maxX + 10.0f;  // 오른 검색선의 끝을 maxX 보다 10 크게 한다.
            rightCheckLine.m_endPoint.Y   = baseY;

            /// create a left check line
            leftCheckLine.m_startPoint.X = centerX;
            leftCheckLine.m_startPoint.Y = baseY;
            leftCheckLine.m_endPoint.X   = minX - 10.0f;  // 오른 검색선의 끝을 minX 보다 10 작게 한다.
            leftCheckLine.m_endPoint.Y   = baseY;

            /// 매번 생성하는 Property 이기 때문에
            /// LineList 는 새로운 List에  담는 동작 한번만 호출하고, 사용은 새로운 List 를 사용한다.
            List <CLine> listAbsoluteLine = new List <CLine>();

            listAbsoluteLine = face.AbsoluteLineList;

            foreach (CLine line in listAbsoluteLine)
            {
                /// Face 선들과 검색 선의 교차 횟수 확인
                if (true == isIntersected(line, rightCheckLine))
                {
                    nRightIntersection++;
                }

                if (true == isIntersected(line, leftCheckLine))
                {
                    nLeftIntersection++;
                }

                /// Face 선의 양점이 검색 선 위에 올라가 있는지 확인
                if (true == isPerchedOnLine(rightCheckLine, line.m_startPoint))
                {
                    nRightPerchedPointOnCheckLine++;
                }

                if (true == isPerchedOnLine(rightCheckLine, line.m_endPoint))
                {
                    nRightPerchedPointOnCheckLine++;
                }

                if (true == isPerchedOnLine(leftCheckLine, line.m_startPoint))
                {
                    nLeftPerchedPointOnCheckLine++;
                }

                if (true == isPerchedOnLine(leftCheckLine, line.m_endPoint))
                {
                    nLeftPerchedPointOnCheckLine++;
                }

                /// Face 선위에 중심점이 올라가 있는지 확인
                if (true == isPerchedOnLine(line, centerPoint))
                {
                    nPerchedCenterPointOnFaceLine++;
                }
            }


            //-------------------------------------------------------------------
            // 내부점 판단
            //
            // 내부점을 만족하면 Point 를 리턴하고,
            // 만족하지 못하면 측정 면적을 수정하고 재귀호출을 통해 Point 를 찾아낸다.
            //------------------------------------------------------------------
            //
            CPoint point = new CPoint();

            // Center 점이 Face Line 위에 올라가 있으면 우측 1/2 사각형에서 내부점을 찾는다.
            if (nPerchedCenterPointOnFaceLine > 0)
            {
                return(findInsidePoint(face, centerX, maxX, minY, maxY));
            }

            // Face Line 의 양점이 우측 검색 라인에 올라가는 경우는 상측 1/2 사각형에서 내부점을 찾는다.
            if (nRightPerchedPointOnCheckLine > 0 || nLeftPerchedPointOnCheckLine > 0)
            {
                return(findInsidePoint(face, minX, maxX, baseY, maxY));
            }

            // 양측이 홀수이면 Inside Point 이다.
            if (EMNumberKind.ODD == getNumberKind(nRightIntersection) && EMNumberKind.ODD == getNumberKind(nLeftIntersection))
            {
                point.X = centerX;
                point.Y = baseY;

                return(point);
            }
            /// 왼쪽이 짝수이면 X 값의 최소값과 중심값 사이의 중점을 다시 확인한다.
            else if (EMNumberKind.EVEN == getNumberKind(nLeftIntersection))
            {
                return(findInsidePoint(face, minX, centerX, minY, maxY));
            }
            /// 오른쪽이 짝수이면 X 값의 중심값과 최대값 사이의 중점을 다시 확인한다.
            else if (EMNumberKind.EVEN == getNumberKind(nRightIntersection))
            {
                return(findInsidePoint(face, centerX, maxX, minY, maxY));
            }
            else
            {
                /// Block Point 를 찾기 위해서 findInsidePoint() 를 호출할 때
                /// Face 형상의 문제로 오류가 발생하여 Face 바깥의 지점으로 계산이 리턴되면
                /// Block Point 가 추가되지 못해서
                /// FEMM 에서 Block Point 에 재질 인가 할 때 다른 Block Point 에 인가되는 문제가 발생한다.
                ///
                /// 따라서 findInsidePoint() 에서 내부점을 찾지 못할 때는
                /// 중심의 좌표값을 넘기지 않고 null 을 리턴하여 Block Point 재질 설정 동작을 막는다.
                CNotice.noticeWarningID("FTCT");
                return(null);
            }
        }
Exemple #15
0
        // Base Point 와 상대좌표로 좌표값이 저장되는 Face 가 생성된다.
        public CFace makeFace()
        {
            try
            {
                CFace face = new CFace();

                face.BasePoint.m_dX = Double.Parse(textBoxBaseX.Text);
                face.BasePoint.m_dY = Double.Parse(textBoxBaseY.Text);

                if (FaceType == EMFaceType.RECTANGLE)
                {
                    if (ListPointControl.Count != 2)
                    {
                        CNotice.printTraceID("TATP1");
                        return(null);
                    }

                    double x1, y1, x2, y2;

                    x1 = Double.Parse(ListPointControl[0].StrCoordX);
                    y1 = Double.Parse(ListPointControl[0].StrCoordY);
                    x2 = Double.Parse(ListPointControl[1].StrCoordX);
                    y2 = Double.Parse(ListPointControl[1].StrCoordY);

                    face.setRectanglePoints(x1, y1, x2, y2);
                }
                else
                {
                    if (ListPointControl.Count < 4)
                    {
                        CNotice.printTraceID("TANM");
                        return(null);
                    }

                    List <CPoint> listPoint = new List <CPoint>();

                    foreach (CPointControl pointControl in ListPointControl)
                    {
                        // 매번 신규로 생성을 해야 한다.
                        CPoint point = new CPoint();

                        point.m_dX = Double.Parse(pointControl.StrCoordX);
                        point.m_dY = Double.Parse(pointControl.StrCoordY);

                        if (pointControl.IsArc == true)
                        {
                            point.m_emLineKind = EMLineKind.ARC;
                        }
                        else
                        {
                            point.m_emLineKind = EMLineKind.STRAIGHT;
                        }

                        if (pointControl.IsArcDirection == true)
                        {
                            point.m_emDirectionArc = EMDirectionArc.BACKWARD;
                        }
                        else
                        {
                            point.m_emDirectionArc = EMDirectionArc.FORWARD;
                        }

                        listPoint.Add(point);
                    }

                    face.setPolygonPoints(listPoint);
                }

                return(face);
            }
            catch (Exception ex)
            {
                CNotice.printTrace(ex.Message);
                return(null);
            }
        }
Exemple #16
0
        /// <summary>
        /// 재귀호출을 사용해서 FACE 내부점을 찾아낸다.
        /// 재질 블럭점을 찾는 것이기 때문에 절대좌표를 사용해야 한다.
        ///
        /// 참고 사이트 : http://bowbowbow.tistory.com/24
        /// </summary>
        /// <param name="minX">내부점을 찾는 구간의 X 점 최소값</param>
        /// <param name="maxX">내부점을 찾는 구간의 X 점 최대값</param>
        /// <param name="baseY">내부 좌표값을 찾은 Y 위치 </param>
        /// <returns></returns>
        public CPoint findInsidePoint(CFace face, double minX, double maxX, double baseY)
        {
            int nRightIntersection = 0;
            int nLeftIntersection  = 0;

            int nRightPerchedPoint = 0;
            int nLeftPerchedPoint  = 0;

            // 자리수 정리
            minX  = round(minX);
            maxX  = round(maxX);
            baseY = round(baseY);

            double centerX = (minX + maxX) / 2.0f;

            CLine rightLine = new CLine();
            CLine leftLine  = new CLine();

            /// create a right check line
            rightLine.m_startPoint.m_dX = centerX;
            rightLine.m_startPoint.m_dY = baseY;
            rightLine.m_endPoint.m_dX   = maxX + 10.0f;  // 오른 검색선의 끝을 maxX 보다 10 크게 한다.
            rightLine.m_endPoint.m_dY   = baseY;

            /// create a left check line
            leftLine.m_startPoint.m_dX = centerX;
            leftLine.m_startPoint.m_dY = baseY;
            leftLine.m_endPoint.m_dX   = minX - 10.0f;  // 오른 검색선의 끝을 minX 보다 10 작게 한다.
            leftLine.m_endPoint.m_dY   = baseY;

            /// 매번 생성하는 Property 이기 때문에
            /// LineList 는 새로운 List에  담는 동작 한번만 호출하고, 사용은 새로운 List 를 사용한다.
            List <CLine> listAbsoluteLine = new List <CLine>();

            listAbsoluteLine = face.AbsoluteLineList;

            /// Face 의 선과 검색선의 교차점을 찾는다.
            foreach (CLine line in listAbsoluteLine)
            {
                if (true == isIntersected(line, rightLine))
                {
                    nRightIntersection++;
                }

                if (true == isIntersected(line, leftLine))
                {
                    nLeftIntersection++;
                }
            }

            /// 교차를 검사할때 Face 선의 양점은 고려하지 않는다.
            /// 따라서 검색선에 Face 선의 점을 지나치는 경우는 교차점이 인식되지 못한다.
            /// 라인의 양점이 검색선에 올가가는지도 추가로 검색한다.
            ///
            foreach (CLine line in listAbsoluteLine)
            {
                // 만약 시작과 끝이 같이 올라간 경우라면 검색선에 Face 선이 올라간 경우로 검색에서 제외한다.
                // 라인의 한점만 올라간 경우를 Perched Point 로 사용한다.
                if (true == isPerchedOnLine(rightLine, line.m_startPoint) && true == isPerchedOnLine(rightLine, line.m_endPoint))
                {
                    nRightPerchedPoint += 0;
                }
                else if (true == isPerchedOnLine(rightLine, line.m_startPoint))
                {
                    nRightPerchedPoint++;
                }
                else if (true == isPerchedOnLine(rightLine, line.m_endPoint))
                {
                    nRightPerchedPoint++;
                }

                if (true == isPerchedOnLine(leftLine, line.m_startPoint) && true == isPerchedOnLine(leftLine, line.m_endPoint))
                {
                    nLeftPerchedPoint += 0;
                }
                else if (true == isPerchedOnLine(leftLine, line.m_startPoint))
                {
                    nLeftPerchedPoint++;
                }
                else if (true == isPerchedOnLine(leftLine, line.m_endPoint))
                {
                    nLeftPerchedPoint++;
                }
            }

            if ((nRightPerchedPoint % 2 != 0) || (nLeftPerchedPoint % 2 != 0))
            {
                CNotice.printTrace("findInsidePoint 에서 PerchedPoint 값이 홀수가 되었습니다.");
            }

            /// 점이 올라가는 경우 두점이 같이 올라가기 때문에 한번 교차에 두번 카운팅이 된다.
            /// 따라서 1/2 로 처리한다.
            ///
            nRightIntersection += (int)(nRightPerchedPoint / 2.0f);
            nLeftIntersection  += (int)(nLeftPerchedPoint / 2.0f);

            CPoint point = new CPoint();

            /// 양측이 홀수이면 Inside Point 이다.
            if (EMNumberKind.ODD == getNumberKind(nRightIntersection) && EMNumberKind.ODD == getNumberKind(nLeftIntersection))
            {
                point.m_dX = centerX;
                point.m_dY = baseY;

                return(point);
            }
            /// 왼쪽이 짝수이면 X 값의 최소값과 중심값 사이의 중점을 다시 확인한다.
            else if (EMNumberKind.EVEN == getNumberKind(nLeftIntersection))
            {
                return(findInsidePoint(face, minX, centerX, baseY));
            }
            /// 오른쪽이 짝수이면 X 값의 중심값과 최대값 사이의 중점을 다시 확인한다.
            else if (EMNumberKind.EVEN == getNumberKind(nRightIntersection))
            {
                return(findInsidePoint(face, centerX, maxX, baseY));
            }
            else
            {
                /// Block Point 를 찾기 위해서 findInsidePoint() 를 호출할 때
                /// Face 형상의 문제로 오류가 발생하여 Face 바깥의 지점으로 계산이 리턴되면
                /// Block Point 가 추가되지 못해서
                /// FEMM 에서 Block Point 에 재질 인가 할 때 다른 Block Point 에 인가되는 문제가 발생한다.
                ///
                /// 따라서 findInsidePoint() 에서 내부점을 찾지 못할 때는
                /// 중심의 좌표값을 넘기지 않고 null 을 리턴하여 Block Point 재질 설정 동작을 막는다.
                CNotice.noticeWarningID("FTCT");
                return(null);
            }
        }