座標自動計算

①マーキング処理１

        public void marking()                                                                   
        {
            if (pictureBox1.Image == null)
            {
                return;
            }

            //図面のサイズに合わせる
            if (numericUpDown1.Value == 100)
            {
                gridbmp = new Bitmap(drawbmp.Width, drawbmp.Height);
            }
            else
            {
                gridbmp = new Bitmap(drawbmpResize.Width, drawbmpResize.Height);
            }


            //データグリッドから描画した画像を表示
            for (int i = 0; i < dataGridView1.RowCount; i++)
            {
                string x = dataGridView1[4, i].Value.ToString();
                decimal dx = Convert.ToDecimal(x) * (numericUpDown1.Value / 100);
                float fx = (float)dx;

                string y = dataGridView1[5, i].Value.ToString();
                decimal dy = Convert.ToDecimal(y) * (numericUpDown1.Value / 100);
                float fy = (float)dy;

                string size = dataGridView1[6, i].Value.ToString();
                decimal dsize = Convert.ToDecimal(size) * (numericUpDown1.Value / 100);
                float fsize = (float)dsize;

                string markflag = dataGridView1[7, i].Value.ToString();

                //半径分ずらす
                float px = fx - fsize / 2;
                float py = fy - fsize / 2;

                using (Graphics g = Graphics.FromImage(gridbmp))
                {
                    if (markflag == "1")
                    {
                        g.DrawEllipse(bluePen, px, py, fsize, fsize);
                    }
                    else if (markflag == "2")
                    {
                        g.DrawRectangle(bluePen, px, py, fsize, fsize);
                    }
                }

                //製品センターマーキング
                string center = dataGridView1[16, i].Value.ToString();
                if (center.Contains("面ｾﾝﾀｰ"))
                {
                    decimal.TryParse(dataGridView1[4, i].Value.ToString(), out decimal centerX);
                    decimal dcx = Convert.ToDecimal(centerX) * (numericUpDown1.Value / 100);
                    float fcx = (float)dcx;

                    decimal.TryParse(dataGridView1[5, i].Value.ToString(), out decimal centerY);
                    decimal dcy = Convert.ToDecimal(centerY) * (numericUpDown1.Value / 100);
                    float fcy = (float)dcy;


                    using (Graphics g = Graphics.FromImage(gridbmp))
                    {
                        g.DrawLine(centerPen1, 0, fcy, gridbmp.Width, fcy);
                        g.DrawLine(centerPen1, fcx, 0, fcx, gridbmp.Height);
                        dataGridView1[16, i].Style.ForeColor = Color.Red;

                    }
                }
            }

            if (pictureBox2.Image != null)
            {
                pictureBox2.Image.Dispose();
            }

            pictureBox2.Image = gridbmp;
            pictureBox13.Visible = false;
            断面登録btn.BackColor = Color.White;
            ﾏｰｸ修正btn.BackColor = Color.White;

            GC.Collect();
        }


②マーキング処理２

        public void marking2(int rowIndex)                                                      //  グリッド１で選択したNoのマーキングを強調するメソッド、図面位置割り出しスクロール
        {
            if (pictureBox1.Image == null)
            {
                return;
            }

            //図面のサイズに合わせる
            if (numericUpDown1.Value == 100)
            {
                gridbmp = new Bitmap(drawbmp.Width, drawbmp.Height);
            }
            else
            {
                gridbmp = new Bitmap(drawbmpResize.Width, drawbmpResize.Height);
            }

            //データグリッドから描画した画像を表示
            for (int i = 0; i < dataGridView1.RowCount; i++)
            {
                string x = dataGridView1[4, i].Value.ToString();
                decimal dx = Convert.ToDecimal(x) * (numericUpDown1.Value / 100);
                float fx = (float)dx;

                string y = dataGridView1[5, i].Value.ToString();
                decimal dy = Convert.ToDecimal(y) * (numericUpDown1.Value / 100);
                float fy = (float)dy;

                string size = dataGridView1[6, i].Value.ToString();
                decimal dsize = Convert.ToDecimal(size) * (numericUpDown1.Value / 100);
                float fsize = (float)dsize;

                string markflag = dataGridView1[7, i].Value.ToString();

                //半径分ずらす
                float px = fx - fsize / 2;
                float py = fy - fsize / 2;

                using (Graphics g = Graphics.FromImage(gridbmp))
                {
                    if (i == rowIndex)
                    {
                        if (markflag == "1")
                        {
                            g.FillEllipse(semiTransBrush, px, py, fsize, fsize);
                        }
                        else if (markflag == "2")
                        {
                            g.FillRectangle(semiTransBrush, px, py, fsize, fsize);
                        }
                        continue;
                    }

                    if (markflag == "1")
                    {
                        g.DrawEllipse(bluePen, px, py, fsize, fsize);
                    }
                    else if (markflag == "2")
                    {
                        g.DrawRectangle(bluePen, px, py, fsize, fsize);
                    }
                }

                //製品センターマーキング
                string center = dataGridView1[16, i].Value.ToString();
                if (center.Contains("面ｾﾝﾀｰ"))
                {
                    decimal.TryParse(dataGridView1[4, i].Value.ToString(), out decimal centerX);
                    decimal dcx = Convert.ToDecimal(centerX) * (numericUpDown1.Value / 100);
                    float fcx = (float)dcx;

                    decimal.TryParse(dataGridView1[5, i].Value.ToString(), out decimal centerY);
                    decimal dcy = Convert.ToDecimal(centerY) * (numericUpDown1.Value / 100);
                    float fcy = (float)dcy;


                    using (Graphics g = Graphics.FromImage(gridbmp))
                    {
                        g.DrawLine(centerPen1, 0, fcy, gridbmp.Width, fcy);
                        g.DrawLine(centerPen1, fcx, 0, fcx, gridbmp.Height);
                        dataGridView1[16, i].Style.ForeColor = Color.Red;

                    }
                }

            }

            if (pictureBox2.Image != null)
            {
                pictureBox2.Image.Dispose();
            }

            pictureBox2.Image = gridbmp;
            pictureBox13.Visible = false;
            断面登録btn.BackColor = Color.White;
            ﾏｰｸ修正btn.BackColor = Color.White;

            //選択した加工要素の位置に図面をジャンプ
            string alx = dataGridView1[4, rowIndex].Value.ToString();
            decimal jpx = Convert.ToDecimal(alx) * (numericUpDown1.Value / 100);
            int jx = Convert.ToInt32((decimal)jpx) - (panel1.Width / 2);
            string aly = dataGridView1[5, rowIndex].Value.ToString();
            decimal jpy = Convert.ToDecimal(aly) * (numericUpDown1.Value / 100);
            int jy = Convert.ToInt32((decimal)jpy) - (panel1.Height / 2);





            Point point = new Point(jx, jy);

            panel1.AutoScrollPosition = point;

            GC.Collect();
        }

③製品センター自動登録処理

        private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
        {
            // クリックされたセルの行インデックスと列インデックスを取得します。
            var rowIndex = e.RowIndex;
            var columnIndex = e.ColumnIndex;
            DataGridView dgv = (DataGridView)sender;

            // ヘッダ行またはヘッダ列がクリックされた場合
            if ((rowIndex < 0) || (columnIndex < 0))
            {
                // 何もしません。
                return;
            }

            //断面の列がクリックされた時の処理
            if (dgv.Columns[e.ColumnIndex].Name == "断面")
            {
                if (dataGridView1[columnIndex, rowIndex].Value.ToString() == "有")
                {
                    //選択した加工要素の断面位置に図面をジャンプ
                    string alx = dataGridView1[14, rowIndex].Value.ToString();
                    decimal px = Convert.ToDecimal(alx) * (numericUpDown1.Value / 100);
                    int x = Convert.ToInt32((decimal)px) - (panel1.Width / 2);
                    string aly = dataGridView1[15, rowIndex].Value.ToString();
                    decimal py = Convert.ToDecimal(aly) * (numericUpDown1.Value / 100);
                    int y = Convert.ToInt32((decimal)py) - (panel1.Height / 2);

                    Point point = new Point(x, y);

                    panel1.AutoScrollPosition = point;
                }
            }

            //製品センター登録
            if (dgv.Columns[e.ColumnIndex].Name == "製品センター")
            {
                string kakoumen = null;
                kakoumen = dataGridView1[2, rowIndex].Value.ToString();

                if(kakoumen != "100面" && kakoumen != "200面")
                {
                    MessageBox.Show("製品センターが登録できるのは100面か200面のみです");
                    return;
                }

                //既に登録されている場合の解除
                if (dataGridView1[columnIndex, rowIndex].Value.ToString().Contains("面ｾﾝﾀｰ"))
                {
                    DialogResult dialog = MessageBox.Show("センター登録を解除しますか？", "確認メッセージ", MessageBoxButtons.YesNo);
                    if (dialog == DialogResult.No)
                    {
                        return;
                    }

                    //全行の加工面を取得する
                    List<string> list = new List<string>();
                    for (int i = 0; i < dataGridView1.Rows.Count; i++)
                    {
                        list.Add(dataGridView1[2, i].Value.ToString());
                    }

                    //クリックした行と同じ加工面の全インデックスを取得
                    var result = list.Select((item, index) => new { Index = index, Value = item }).Where(item => item.Value == kakoumen).Select(item => item.Index);

                    //全インデックスの〇を消去
                    foreach (var test in result)
                    {
                        dataGridView1[16, test].Value = "";
                    }
                }

                //製品センターの登録、変更
                else 
                {
                    if (dataGridView1[columnIndex, rowIndex].Value.ToString() != "")
                    {
                        DialogResult dialog = MessageBox.Show("製品センターを変更しますか？", "確認メッセージ", MessageBoxButtons.YesNo);
                        if (dialog == DialogResult.No)
                        {
                            return;
                        }
                    }

                    //製品センターの座標を取得
                    decimal.TryParse(dataGridView1[4, rowIndex].Value.ToString(), out decimal centerX);
                    decimal.TryParse(dataGridView1[5, rowIndex].Value.ToString(), out decimal centerY);

                    //全行の加工面を取得する
                    List<string> list = new List<string>();
                    for (int i = 0; i < dataGridView1.Rows.Count; i++)
                    {
                        list.Add(dataGridView1[2, i].Value.ToString());
                    }

                    //クリックした行と同じ加工面の全インデックスを取得
                    var result = list.Select((item, index) => new { Index = index, Value = item }).Where(item => item.Value == kakoumen).Select(item => item.Index);

                    //全インデックスの〇を消去
                    foreach (var test in result)
                    {
                        dataGridView1[16, test].Value = "";
                        decimal.TryParse(dataGridView1[4, test].Value.ToString(), out decimal testX);
                        decimal.TryParse(dataGridView1[5, test].Value.ToString(), out decimal testY);


                        //各象限の自動付与
                        if(testX >= centerX && testY >= centerY)
                        {
                            dataGridView1[16, test].Value = "4";
                        }

                        if (testX <= centerX && testY >= centerY)
                        {
                            dataGridView1[16, test].Value = "3";
                        }

                        if (testX <= centerX && testY <= centerY)
                        {
                            dataGridView1[16, test].Value = "2";
                        }

                        if (testX >= centerX && testY <= centerY)
                        {
                            dataGridView1[16, test].Value = "1";
                        }
                    }

                    //クリックしたところに面ｾﾝﾀｰを表示
                    dataGridView1[columnIndex, rowIndex].Value = kakoumen + "ｾﾝﾀｰ";
                }

                marking();

            }

        }


④座標自動計算処理

        private void dataGridView2_CellContentClick_1(object sender, DataGridViewCellEventArgs e)
        {
            // クリックされたセルの行インデックスと列インデックスを取得します。
            var rowIndex = e.RowIndex;
            var columnIndex = e.ColumnIndex;
            DataGridView dgv = (DataGridView)sender;

            // ヘッダ行またはヘッダ列がクリックされた場合
            if ((rowIndex < 0) || (columnIndex < 0))
            {
                // 何もしません。
                return;
            }

            //一般公差の列がクリックされた時の処理
            if (dgv.Columns[e.ColumnIndex].Name == "一般公差")
            {
                //製品寸法が設定されてない場合は終了
                if (dataGridView2[11, rowIndex].Value.ToString() == "")
                {
                    MessageBox.Show("製品寸法を登録してください");
                    return;
                }

                //製品上限公差または製品下限公差に値がある場合は、メッセージ確認
                if (dataGridView2[13, rowIndex].Value.ToString() != "" || dataGridView2[14, rowIndex].Value.ToString() != "")
                {
                    DialogResult result = MessageBox.Show("既に製品公差が設定されています。変更しますか？", "変更確認", MessageBoxButtons.YesNo);

                    if (result == System.Windows.Forms.DialogResult.Yes)
                    {

                    }
                    else if (result == System.Windows.Forms.DialogResult.No)
                    {
                        return;
                    }
                }

                //10列目の精度項目の内容と照らし合わせて、一般公差参照先を決める
                string name = dataGridView2[10, rowIndex].Value.ToString();


                //①長さ
                List<string> nagasa = new List<string>();
                for (int i = 0; i < 長さリスト.Items.Count; i++)
                {
                    nagasa.Add(長さリスト.Items[i].ToString());
                }

                if (nagasa.Contains(name))
                {
                    //一般公差内径というコントロールを探して、Control型の配列に代入
                    Control[] cs = Controls.Find("一般公差長さ", true);
                    General_Tol(rowIndex, cs);
                }

                //②穴の直径
                List<string> naikei = new List<string>();
                for (int i = 0; i < 穴の直径リスト.Items.Count; i++)
                {
                    naikei.Add(穴の直径リスト.Items[i].ToString());
                }
                if (naikei.Contains(name))
                {
                    //一般公差内径というコントロールを探して、Control型の配列に代入
                    Control[] cs = Controls.Find("一般公差内径", true);
                    General_Tol(rowIndex, cs);
                }

                //③穴深さ
                List<string> fukasa = new List<string>();
                for (int i = 0; i < 穴深さリスト.Items.Count; i++)
                {
                    fukasa.Add(穴深さリスト.Items[i].ToString());
                }
                if (fukasa.Contains(name))
                {
                    //一般公差内径というコントロールを探して、Control型の配列に代入
                    Control[] cs = Controls.Find("一般公差穴深さ", true);
                    General_Tol(rowIndex, cs);
                }

                //④面取り
                List<string> mentori = new List<string>();
                for (int i = 0; i < 面取りリスト.Items.Count; i++)
                {
                    mentori.Add(面取りリスト.Items[i].ToString());
                }
                if (mentori.Contains(name))
                {
                    //一般公差内径というコントロールを探して、Control型の配列に代入
                    Control[] cs = Controls.Find("一般公差面取り", true);
                    General_Tol(rowIndex, cs);
                }

                //⑤隅部
                List<string> sumibu = new List<string>();
                for (int i = 0; i < 隅部リスト.Items.Count; i++)
                {
                    sumibu.Add(隅部リスト.Items[i].ToString());
                }
                if (sumibu.Contains(name))
                {
                    //一般公差内径というコントロールを探して、Control型の配列に代入
                    Control[] cs = Controls.Find("一般公差隅部", true);
                    General_Tol(rowIndex, cs);
                }
            }

            //コピーの列がクリックされた時の処理
            if (dgv.Columns[e.ColumnIndex].Name == "コピー")
            {
                //自動計算の下準備　dataGridView1からデータムリストとセンターリストを格納
                List<string> centerlist = new List<string>();
                List<string> datumlist = new List<string>();
                List<string> nolist = new List<string>();
                for (int i = 0; i < dataGridView1.RowCount; i++)
                {
                    centerlist.Add(dataGridView1["製品センター", i].Value.ToString());
                    datumlist.Add(dataGridView1["データム１", i].Value.ToString());
                    nolist.Add(dataGridView1[0, i].Value.ToString());
                }

                //位置XY自動計算にチェックが入っている
                //【分岐１】精度寸法の名称に位置Xが含まれるか確認し、自動計算するか聞く
                string seido = dataGridView2["精度項目", rowIndex].Value.ToString();
                //加工面を記憶
                string kakoumen = dataGridView2["加工面", rowIndex].Value.ToString();
                if (位置XY自動計算.Checked && seido.Contains("位置X") && kakoumen ==　"100面" || kakoumen == "200面")
                {
                    DialogResult result = MessageBox.Show("穴位置を自動計算しますか？", "自動計算", MessageBoxButtons.YesNo);

                    if (result == DialogResult.No)
                    {
                        return;
                    }

                    //最新状態を保存しておく
                    button4.PerformClick();

                    //【分岐２】製品センターが登録されているか確認
                    string kakoumencenter = dataGridView2["加工面", rowIndex].Value.ToString() + "ｾﾝﾀｰ";
                    if (centerlist.Contains(kakoumencenter) == false)
                    {
                        dataGridView1.ClearSelection();
                        dataGridView1[16, 0].Selected = true;
                        MessageBox.Show("加工要素で製品センターを登録して下さい");
                        return;
                    }



                    //【分岐３】管理基準１が設定されているか確認
                    if (dataGridView2["管理基準１", rowIndex].Value.ToString() == "")
                    {
                        dataGridView2.ClearSelection();
                        dataGridView2["管理基準１", rowIndex].Selected = true;
                        MessageBox.Show("管理基準１を登録して下さい");
                        return;
                    }

                    //管理基準１を記憶
                    string datum1 = dataGridView2["管理基準１", rowIndex].Value.ToString();

                    //【分岐４】管理基準１がdataGridView1に登録されているか確認
                    if (datumlist.Contains(datum1) == false)
                    {
                        dataGridView1.ClearSelection();
                        dataGridView1["データム１", 0].Selected = true;
                        MessageBox.Show("データムを登録して下さい");
                        return;
                    }

                    //【分岐５】ワーク姿勢が登録されているか確認用、登録されていたら角度を代入
                    if (dataGridView2["ワーク姿勢", rowIndex].Value.ToString() == "")
                    {
                        dataGridView2.ClearSelection();
                        for(int i = 0; i < dataGridView2.RowCount; i++)
                        {
                            if (dataGridView2["ワーク姿勢", rowIndex - i].ReadOnly != true)
                            {
                                dataGridView2["ワーク姿勢", rowIndex - i].Selected = true;
                                break;
                            }
                        }
                        MessageBox.Show("ワーク姿勢を登録して下さい");
                        return;
                    }

                    //ワーク姿勢を記憶
                    double.TryParse(dataGridView2["ワーク姿勢", rowIndex].Value.ToString(), out double angle);

                    //【分岐６】製品寸法が登録されているか確認用
                    if (dataGridView2["製品寸法", rowIndex].Value.ToString() == "")
                    {
                        dataGridView2.ClearSelection();
                        dataGridView2["製品寸法", rowIndex].Selected = true;
                        MessageBox.Show("製品寸法Xを登録して下さい");
                        return;
                    }

                    //製品寸法Xを記憶
                    double.TryParse(dataGridView2["製品寸法", rowIndex].Value.ToString(), out double x1);

                    //【分岐７】位置Yの有無を確認
                    string check = dataGridView2["精度項目", rowIndex + 1].Value.ToString();
                    if (check.Contains("位置Y") == false)
                    {
                        dataGridView2.ClearSelection();
                        dataGridView2["精度項目", rowIndex + 1].Selected = true;
                        MessageBox.Show("位置Xの１行下に位置Yを設定して下さい");
                        return;
                    }

                    //製品寸法Yを記憶
                    bool y1bool = double.TryParse(dataGridView2["製品寸法", rowIndex + 1].Value.ToString(), out double y1);

                    //【分岐８】製品寸法Yが登録されているか確認
                    if (y1bool == false)
                    {
                        dataGridView2.ClearSelection();
                        dataGridView2["製品寸法", rowIndex + 1].Selected = true;
                        MessageBox.Show("製品寸法Yを登録して下さい");
                        return;
                    }

                    //ここから本命の処理

                    //データム穴の加工要素Noを取得
                    int index = datumlist.IndexOf(datum1);
                    string datumno = dataGridView1[0, index].Value.ToString();

                    //加工穴の加工要素Noを取得
                    string originalno = dataGridView2[0, 0].Value.ToString();
                    int originalindex = nolist.IndexOf(originalno);

                    //データム穴、加工穴の象限を取得
                    string shougen = dataGridView1["製品センター", originalindex].Value.ToString();
                    string shougen2 = dataGridView1["製品センター", index].Value.ToString();

                    //ファイルが存在する場合は、ファイルを読み込み、製品寸法があるか確認
                    string pathcheck = path + "\\" + datumno + ".csv";
                    if (File.Exists(pathcheck) == false)
                    {
                        dataGridView1.ClearSelection();
                        dataGridView1["詳細登録", index].Selected = true;
                        MessageBox.Show("データムの詳細情報登録がありません");
                        return;
                    }

                    //ファイル読み込み
                    Control[] abc = this.Controls.Find("dataGridView" + 2.ToString(), true);
                    open_grid(pathcheck, abc, false);
                    datainputdisable(abc);
                    dataGridView1.ClearSelection();

                    //精度項目をリスト化し穴位置Xを探す
                    List<string> seidolist = new List<string>();
                    for (int i = 0; i < dataGridView2.RowCount; i++)
                    {
                        seidolist.Add(dataGridView2["精度項目", i].Value.ToString());
                    }

                    //データム穴の穴位置Xの確認
                    int xindex = seidolist.FindLastIndex(item => item.Contains("位置X"));
                    if (xindex == -1)
                    {
                        MessageBox.Show("データムに穴位置Xがありません");
                        return;
                    }

                    //データム穴の穴位置Yを確認
                    string check2 = dataGridView2["精度項目", xindex + 1].Value.ToString();
                    if (check2.Contains("位置Y") == false)
                    {
                        dataGridView2.ClearSelection();
                        dataGridView2.Focus();
                        dataGridView2["精度項目", xindex + 1].Selected = true;
                        MessageBox.Show("データムの位置Xの１行下に位置Yを設定して下さい");
                        return;
                    }

                    //データム穴の穴位置XYを取得
                    double x2 = 0;
                    double y2 = 0;

                    bool x2bool = double.TryParse(dataGridView2["製品寸法", xindex].Value.ToString(), out x2);
                    bool y2bool = double.TryParse(dataGridView2["製品寸法", xindex + 1].Value.ToString(), out y2);

                    //製品寸法Xが登録されていない場合は処理終了
                    if (x2bool == false)
                    {
                        dataGridView2.ClearSelection();
                        dataGridView2["製品寸法", xindex].Selected = true;
                        MessageBox.Show("製品寸法Xを登録して下さい");
                        return;
                    }

                    //製品寸法Yが登録されていない場合は処理終了
                    if (y2bool == false)
                    {
                        dataGridView2.ClearSelection();
                        dataGridView2["製品寸法", xindex + 1].Selected = true;
                        MessageBox.Show("製品寸法Yを登録して下さい");
                        return;
                    }

                    if (shougen == "")
                    {
                        dataGridView1.ClearSelection();
                        dataGridView1["製品センター", originalindex].Selected = true;
                        MessageBox.Show("象限を登録して下さい");
                        return;
                    }

                    if (shougen2 == "")
                    {
                        dataGridView1.ClearSelection();
                        dataGridView1["製品センター", index].Selected = true;
                        MessageBox.Show("象限を登録して下さい");
                        return;
                    }

                    //加工穴の象限を判別し、符号を変換
                    if (shougen == "2" || shougen == "3")
                    {
                        x1 = x1 * -1;
                    }
                    if (shougen == "3" || shougen == "4")
                    {
                        y1 = y1 * -1;
                    }

                    //データムの象限を判別し、符号を変換
                    string kakoumen2 = dataGridView2["加工面", rowIndex].Value.ToString();
                    if (kakoumen == kakoumen2)
                    {
                        if (shougen2 == "2" || shougen2 == "3")
                        {
                            x2 = x2 * -1;
                        }
                        if (shougen2 == "3" || shougen2 == "4")
                        {
                            y2 = y2 * -1;
                        }
                    }

                    //データムの加工面が裏側の時にXの符号を反転する
                    else
                    {
                        if (shougen2 == "1" || shougen2 == "4")
                        {
                            x2 = x2 * -1;
                        }
                        if (shougen2 == "3" || shougen2 == "4")
                        {
                            y2 = y2 * -1;
                        }
                    }


                    //加工穴の座標変換
                    double x3 = x1 * Math.Cos(angle * Math.PI / 180) - y1 * Math.Sin(angle * Math.PI / 180);
                    double y3 = x1 * Math.Sin(angle * Math.PI / 180) + y1 * Math.Cos(angle * Math.PI / 180);

                    //データム穴の座標変換

                    double x4 = 0;
                    double y4 = 0;
                    if(kakoumen == kakoumen2)
                    {
                        x4 = x2 * Math.Cos(angle * Math.PI / 180) - y2 * Math.Sin(angle * Math.PI / 180);
                        y4 = x2 * Math.Sin(angle * Math.PI / 180) + y2 * Math.Cos(angle * Math.PI / 180);
                    }
                    else
                    {
                        x4 = x2 * Math.Cos(angle * Math.PI / 180) - y2 * Math.Sin(angle * Math.PI / 180);
                        y4 = x2 * Math.Sin(angle * Math.PI / 180) + y2 * Math.Cos(angle * Math.PI / 180);
                    }

                    //最終XY座標
                    double finalx = Math.Abs(x3 - x4);
                    double finaly = Math.Abs(y3 - y4);

                    string pathcheck2 = path + "\\" + originalno + ".csv";
                    open_grid(pathcheck2, abc, false);
                    datainputdisable(abc);
                    dataGridView1.ClearSelection();

                    //最終寸法とデータムを設定する
                    dataGridView2["工程寸法", rowIndex].Value = Math.Round(finalx, 3, MidpointRounding.AwayFromZero);
                    dataGridView2["工程寸法", rowIndex + 1].Value = Math.Round(finaly, 3, MidpointRounding.AwayFromZero);
                    dataGridView2["管理基準１", rowIndex + 1].Value = datum1;

                    //製品公差が設定されている場合は、工程公差計算後の寸法で一般公差を自動設定する

                    if (dataGridView2[13,rowIndex].Value.ToString() != "")
                    {
                        //Xの一般公差設定
                        string name = dataGridView2[10, rowIndex].Value.ToString();
                        List<string> nagasa = new List<string>();
                        for (int i = 0; i < 長さリスト.Items.Count; i++)
                        {
                            nagasa.Add(長さリスト.Items[i].ToString());
                        }
                        if (nagasa.Contains(name))
                        {
                            //一般公差内径というコントロールを探して、Control型の配列に代入
                            Control[] cs = Controls.Find("一般公差長さ", true);
                            General_Tol2(rowIndex, cs);
                        }
                        //Yの一般公差設定
                        int rowIndex2 = rowIndex + 1;
                        string name2 = dataGridView2[10, rowIndex].Value.ToString();
                        if (nagasa.Contains(name2))
                        {
                            //一般公差内径というコントロールを探して、Control型の配列に代入
                            Control[] cs = Controls.Find("一般公差長さ", true);
                            General_Tol2(rowIndex2, cs);
                        }
                    }

                    //設定した値を選択して表示する
                    dataGridView2.ClearSelection();
                    dataGridView2["工程寸法", rowIndex].Selected = true;
                    dataGridView2["工程寸法", rowIndex + 1].Selected = true;

                    //保存処理
                    button4.PerformClick();
                    return;

                }
                else
                {
                    //工程寸法または工程上限公差または工程下限公差に値がある場合は、メッセージ確認
                    if (dataGridView2[18, rowIndex].Value.ToString() != "" || dataGridView2[19, rowIndex].Value.ToString() != "" || dataGridView2[20, rowIndex].Value.ToString() != "")
                    {
                        DialogResult result = MessageBox.Show("既に工程寸法または公差が設定されています。コピーしますか？", "変更確認", MessageBoxButtons.YesNo);

                        //通常コピーの処理
                        if (result == System.Windows.Forms.DialogResult.Yes)
                        {

                        }
                        else
                        {
                            return;
                        }
                    }
                }

                //通常のコピー処理
                dataGridView2[18, rowIndex].Value = dataGridView2[11, rowIndex].Value;
                dataGridView2[19, rowIndex].Value = dataGridView2[13, rowIndex].Value;
                dataGridView2[20, rowIndex].Value = dataGridView2[14, rowIndex].Value;
                dataGridView2[21, rowIndex].Value = dataGridView2[15, rowIndex].Value;
                dataGridView2[22, rowIndex].Value = dataGridView2[16, rowIndex].Value;
                dataGridView2[32, rowIndex].Value = dataGridView2[31, rowIndex].Value;
            }
        }

⑤マーク修正時の象限自動変更

        private void pictureBox13_MouseClick(object sender, MouseEventArgs e)                   //  マーク位置、断面登録時の新マーキングの描画処理
        {
            //クリック座標を取得
            int x = e.X;
            int y = e.Y;

            //選択中の行インデックスを取得
            int rowIndex = dataGridView1.CurrentCell.RowIndex;


            //★断面登録のロジック
            if (断面登録btn.BackColor == Color.Blue)
            {
                //クリックした座標に仮描画処理
                marking5(x, y);

                //メッセージ確認
                DialogResult result2 =
                    MessageBox.Show("No." + (dataGridView1[0, rowIndex].Value) + "の断面を登録しますか？", "断面登録確認", MessageBoxButtons.YesNo, MessageBoxIcon.Question);

                //イエスなら断面座標を登録
                if (result2 == DialogResult.Yes)
                {
                    dataGridView1[13, rowIndex].Value = "有";
                    dataGridView1[14, rowIndex].Value = x / (numericUpDown1.Value / 100);
                    dataGridView1[15, rowIndex].Value = y / (numericUpDown1.Value / 100);
                }

                marking2(rowIndex);
                button4.PerformClick();
                GC.Collect();
                return;
            }

            //★マーク修正のロジック
            //クリックした座標に仮描画処理
            marking4(x, y);

            //メッセージ確認
            DialogResult result =
                MessageBox.Show("No." + (dataGridView1[0, rowIndex].Value) + "のマークを修正しますか？", "ﾏｰｸ修正確認", MessageBoxButtons.YesNo, MessageBoxIcon.Question);

            //イエスなら座標とマークサイズとマーク種類を更新
            if (result == DialogResult.Yes)
            {
                dataGridView1[4, rowIndex].Value = x / (numericUpDown1.Value / 100);
                dataGridView1[5, rowIndex].Value = y / (numericUpDown1.Value / 100);
                dataGridView1[6, rowIndex].Value = numUD1.Value;
                if (radioButton1.Checked == true)
                {
                    dataGridView1[7, rowIndex].Value = "1";
                }
                else if (radioButton2.Checked == true)
                {
                    dataGridView1[7, rowIndex].Value = "2";
                }
            }

            //象限の変更
            if (dataGridView1["製品センター", rowIndex].Value.ToString() != "")
            {

                string kakoumen = dataGridView1[2, rowIndex].Value.ToString();
                string center = kakoumen + "ｾﾝﾀｰ";
                int centerIndex = 0;

                //製品センターのインデックスサーチ
                for (int i = 0; i < dataGridView1.RowCount; i++)
                {
                    if(center == dataGridView1["製品センター", i].Value.ToString())
                    {
                        centerIndex = i;
                        break;
                    }
                }

                //製品センターの座標を取得
                decimal.TryParse(dataGridView1[4, centerIndex].Value.ToString(), out decimal centerX);
                decimal.TryParse(dataGridView1[5, centerIndex].Value.ToString(), out decimal centerY);

                //全行の加工面を取得する
                List<string> list = new List<string>();
                for (int i = 0; i < dataGridView1.Rows.Count; i++)
                {
                    list.Add(dataGridView1[2, i].Value.ToString());
                }

                //クリックした行と同じ加工面の全インデックスを取得
                var result2= list.Select((item, index) => new { Index = index, Value = item }).Where(item => item.Value == kakoumen).Select(item => item.Index);

                //全インデックスの象限を消去
                foreach (var test in result2)
                {
                    dataGridView1[16, test].Value = "";
                    decimal.TryParse(dataGridView1[4, test].Value.ToString(), out decimal testX);
                    decimal.TryParse(dataGridView1[5, test].Value.ToString(), out decimal testY);


                    //各象限の自動付与
                    if (testX >= centerX && testY >= centerY)
                    {
                        dataGridView1[16, test].Value = "4";
                    }

                    if (testX <= centerX && testY >= centerY)
                    {
                        dataGridView1[16, test].Value = "3";
                    }

                    if (testX <= centerX && testY <= centerY)
                    {
                        dataGridView1[16, test].Value = "2";
                    }

                    if (testX >= centerX && testY <= centerY)
                    {
                        dataGridView1[16, test].Value = "1";
                    }
                }

                //クリックしたところに面ｾﾝﾀｰを表示
                dataGridView1["製品センター", centerIndex].Value = center;
            }

            marking2(rowIndex);
            button4.PerformClick();
            GC.Collect();
        }


⑥加工要素追加時の象限自動設定

        private void pictureBox2_Click(object sender, EventArgs e)                              //  ★★図面クリックした箇所に円を描画し、要素登録★★
        {
            //ｸﾘｯｸ登録有効にチェックがない時、終了
            if (ｸﾘｯｸ登録有効.Checked == false)
            {
                return;
            }

            //背景図面がない場合、背景図面の登録を促してクリックイベントを終了する
            if (pictureBox1.Image == null)
            {
                MessageBox.Show("図面を登録して下さい");
                return;
            }

            //マウスの位置座標の取得
            Point p = pictureBox2.PointToClient(Cursor.Position);
            int x = p.X;
            int y = p.Y;

            //マークサイズをテキストボックス入力とし、入力された文字列の数字をint型に変換
            decimal dSize = numUD1.Value;
            int iSize = decimal.ToInt32(dSize);

            //倍率が100%の場合
            if (numericUpDown1.Value == 100)
            {
                clickbmp = new Bitmap(drawbmp.Width, drawbmp.Height);

                //円描画位置を半径分ずらす
                int px = x - iSize / 2;
                int py = y - iSize / 2;

                using (Graphics g = Graphics.FromImage(clickbmp))
                {
                    if (radioButton1.Checked == true)
                    {
                        g.DrawEllipse(redPen, px, py, iSize, iSize);
                    }
                    else if (radioButton2.Checked == true)
                    {
                        g.DrawRectangle(redPen, px, py, iSize, iSize);
                    }
                }

                if (pictureBox2.Image != null)
                {
                    pictureBox2.Image.Dispose();
                }
                pictureBox2.Image = clickbmp;

                int maxNo = maxNoGet();

                //要素登録フォームを表示
                using (Form2 form2 = new Form2(this))
                {

                    //フォーム２へ値渡し
                    form2.label4.Text = x.ToString();              //マークX座標
                    form2.label5.Text = y.ToString();              //マークY座標
                    form2.label8.Text = iSize.ToString();          //マークサイズ

                    //マーク種類、丸なら１、四角なら２
                    if (radioButton1.Checked == true)
                    {
                        form2.label9.Text = "1";
                    }
                    else if (radioButton2.Checked == true)
                    {
                        form2.label9.Text = "2";
                    }

                    form2.label10.Text = "";                        //データ有無
                    form2.label12.Text = (maxNo + 1).ToString();
                    form2.StartPosition = FormStartPosition.CenterParent;
                    DialogResult dr = form2.ShowDialog();

                    if (dr == DialogResult.OK)
                    {
                        button4.PerformClick();
                    }
                }
            }

            //倍率が異なる場合
            else
            {
                clickbmp = new Bitmap(drawbmpResize.Width, drawbmpResize.Height);     //登録済み用の描画を引数としてクリックした時用の描画にする

                //マークサイズの倍率を計算
                decimal Resize = iSize * (numericUpDown1.Value / 100);
                float Resizef = (float)Resize;

                //マークサイズの倍率を考慮して、円描画位置を半径分ずらす
                float px = x - Resizef / 2;
                float py = y - Resizef / 2;

                using (Graphics g = Graphics.FromImage(clickbmp))
                {
                    if (radioButton1.Checked == true)
                    {
                        g.DrawEllipse(redPen, px, py, Resizef, Resizef);
                    }
                    else if (radioButton2.Checked == true)
                    {
                        g.DrawRectangle(redPen, px, py, Resizef, Resizef);
                    }
                }

                if (pictureBox2.Image != null)
                {
                    pictureBox2.Image.Dispose();
                }
                pictureBox2.Image = clickbmp;

                int maxNo = maxNoGet();

                //倍率を考慮した座標に変換し、登録
                decimal xResize = x / (numericUpDown1.Value / 100);
                decimal yResize = y / (numericUpDown1.Value / 100);

                //要素登録フォームを表示
                using (Form2 form2 = new Form2(this))
                {
                    //フォーム２へ値渡し
                    form2.label4.Text = xResize.ToString();        //マークX座標（変換後）
                    form2.label5.Text = yResize.ToString();        //マークY座標（変換後）
                    form2.label8.Text = iSize.ToString();    //マークサイズ

                    //マーク種類、丸なら１、四角なら２
                    if (radioButton1.Checked == true)
                    {
                        form2.label9.Text = "1";
                    }
                    else if (radioButton2.Checked == true)
                    {
                        form2.label9.Text = "2";
                    }
                    form2.label10.Text = "";                        //データ有無
                    form2.label12.Text = (maxNo + 1).ToString();
                    form2.StartPosition = FormStartPosition.CenterParent;
                    DialogResult dr = form2.ShowDialog();

                    if (dr == DialogResult.OK)
                    {
                        button4.PerformClick();
                    }
                }
            }

            //象限の付与
            int rowIndex = dataGridView1.RowCount - 1;
            string kakoumen = dataGridView1[2, rowIndex].Value.ToString();
            string center = kakoumen + "ｾﾝﾀｰ";
            int centerIndex = 0;
            int flag = 0;

            //製品センターのインデックスサーチ
            for (int i = 0; i < dataGridView1.RowCount; i++)
            {
                if (center == dataGridView1["製品センター", i].Value.ToString())
                {
                    centerIndex = i;
                    flag = 1;
                    break;
                }
            }
            
            if(flag == 0)
            {
                return;
            }

            //製品センターの座標を取得
            decimal.TryParse(dataGridView1[4, centerIndex].Value.ToString(), out decimal centerX);
            decimal.TryParse(dataGridView1[5, centerIndex].Value.ToString(), out decimal centerY);

            //全行の加工面を取得する
            List<string> list = new List<string>();
            for (int i = 0; i < dataGridView1.Rows.Count; i++)
            {
                list.Add(dataGridView1[2, i].Value.ToString());
            }

            //クリックした行と同じ加工面の全インデックスを取得
            var result2 = list.Select((item, index) => new { Index = index, Value = item }).Where(item => item.Value == kakoumen).Select(item => item.Index);

            //全インデックスの象限を消去
            foreach (var test in result2)
            {
                dataGridView1[16, test].Value = "";
                decimal.TryParse(dataGridView1[4, test].Value.ToString(), out decimal testX);
                decimal.TryParse(dataGridView1[5, test].Value.ToString(), out decimal testY);


                //各象限の自動付与
                if (testX >= centerX && testY >= centerY)
                {
                    dataGridView1[16, test].Value = "4";
                }

                if (testX <= centerX && testY >= centerY)
                {
                    dataGridView1[16, test].Value = "3";
                }

                if (testX <= centerX && testY <= centerY)
                {
                    dataGridView1[16, test].Value = "2";
                }

                if (testX >= centerX && testY <= centerY)
                {
                    dataGridView1[16, test].Value = "1";
                }
            }

            //クリックしたところに面ｾﾝﾀｰを表示
            dataGridView1["製品センター", centerIndex].Value = center;




            marking();

            GC.Collect();
        }


⑦追加必要なコントロール
・dataGridView1に製品センターの列追加
・穴位置自動計算のチェックボックス