Logo Search packages:      
Sourcecode: sagcad version File versions  Download package

TrimFunc.c

/* ====================================================================
 * ===  Copyright (C) 1998-2007 Yutaka Sagiya. All rights reserved. ===
 * ====================================================================
 * 
 *    Project              : SagCAD
 *    Description          : CAD/CAM
 *    Source               : TrimFunc.c
 * 
 *    ----------------------------------
 * 
 *    License              : GNU General Public License (GPL)
 *    Copyright            : (C) 1998-2007 by Yutaka Sagiya
 *    email                : kappa@a6s.highway.ne.jp
 *                         : yutaka@sagiya.com
 *    Begin                : 2001/01/18
 *    Last                 : 2007/11/08
 * ====================================================================
 */

#ifdef HAVE_CONFIG_H
#  include "config.h"
#endif

#include <gtk/gtk.h>
#include <unistd.h>
//#include <pwd.h>
#include <sys/types.h>
#include <sys/stat.h>

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "intl.h"

#include "MemoryLeak.h"
#include "List_cad.h"
#include "List_Dimension.h"
#include "List_PolyLine.h"
#include "List_Block.h"
#include "List_Undo.h"
#include "List_Select.h"
#include "culcfunc.h"
#include "Ellipse.h"
#include "Dimension.h"
#include "etc.h"
#include "global.h"
#include "Draw.h"
#include "Select.h"
#include "Dimension.h"
#define _TRIMFUNC_
#include "TrimFunc.h"





/* -------------------------------------------------------------------
 * トリム判別
 *    
 */
int TrimMain(struct TrimDat *a)
{
//#define TRIMMAIN
      struct TrimDat Both;
      int Ret;
      double x1, y1, x2, y2, dumy_x, dumy_y;
      int debug = 0;


#ifdef TRIMMAIN
      debug = 1;
#endif

      /* トリム図形が楕円または円ならトリム実行 */
      if ((a->TraceData[1].code == 16 && a->ellipse[1].code == 0) || a->TraceData[1].code == 4) {
            /* トリム図形が楕円 */
            if (a->TraceData[1].code == 16) {
                  if (debug > 0) g_print("トリム図形が楕円\n");
                  Ret = TrimE(a, &x1, &y1, &x2, &y2);
                  TrimE_Run(a, &x1, &y1, &x2, &y2);
            }
            /* トリム図形が円 */
            else if (a->TraceData[1].code == 4) {
                  if (debug > 0) g_print("トリム図形が円\n");
                  Ret = TrimC(a, &x1, &y1, &x2, &y2);
                  TrimC_Run(a, &x1, &y1, &x2, &y2);
            }


            /* 両方トリム1 */
            if (a->Index == 2 && a->TraceData[2].code != 4) {
                  Both.Index              = 1;
                  Both.TraceData[1] = a->TraceData[2];
                  Both.ellipse[1] = Both.ellipse[2];
                  Both.PicX[1]            = a->PicX[2];
                  Both.PicY[1]            = a->PicY[2];
                  Both.TraceData[2] = a->TraceData[1];
                  Both.ellipse[2] = Both.ellipse[1];
                  Both.PicX[2]            = a->PicX[1];
                  Both.PicY[2]            = a->PicY[1];

                  if (Both.TraceData[1].code == 1) {
                        TrimL_Run(&Both, x1, y1);
                  }
                  if (Both.TraceData[1].code == 2) {
                        Ret = TrimA(&Both, &dumy_x, &dumy_y);
                        if (Ret == 1) {
                              TrimA_Run(&Both, x1, y1);
                        }
                        else if (Ret == 2) {
                              TrimA_Pull(&Both, x1, y1);
                        }
                  }
                  if (Both.TraceData[1].code == 16) {
                        if (Both.ellipse[1].code == 1) {
                              Ret = TrimEA(&Both, &dumy_x, &dumy_y);
                              if (Ret == 1) {
                                    TrimEA_Run(&Both, x1, y1);
                              }
                              else if (Ret == 2) {
                                    TrimEA_Pull(&Both, x1, y1);
                              }
                        }
                  }
                  /* 戻す */
                  a->TraceData[2]         = Both.TraceData[1];
                  a->ellipse[2]           = Both.ellipse[1];
                  a->PicX[2]              = Both.PicX[1];
                  a->PicY[2]              = Both.PicY[1];
            }


            /* 両方トリム2 */
            if (a->Index == 2 && a->TraceData[3].code != 4) {
                  Both.Index              = 1;
                  Both.TraceData[1] = a->TraceData[3];
                  Both.ellipse[1] = Both.ellipse[3];
                  Both.PicX[1]            = a->PicX[3];
                  Both.PicY[1]            = a->PicY[3];
                  Both.TraceData[2] = a->TraceData[1];
                  Both.ellipse[2] = Both.ellipse[1];
                  Both.PicX[2]            = a->PicX[1];
                  Both.PicY[2]            = a->PicY[1];

                  if (Both.TraceData[1].code == 1) {
                        TrimL_Run(&Both, x2, y2);
                  }
                  if (Both.TraceData[1].code == 2) {
                        Ret = TrimA(&Both, &dumy_x, &dumy_y);
                        if (Ret == 1) {
                              TrimA_Run(&Both, x2, y2);
                        }
                        else if (Ret == 2) {
                              TrimA_Pull(&Both, x2, y2);
                        }
                  }
                  if (Both.TraceData[1].code == 16) {
                        if (Both.ellipse[1].code == 1) {
                              Ret = TrimEA(&Both, &dumy_x, &dumy_y);
                              if (Ret == 1) {
                                    TrimEA_Run(&Both, x2, y2);
                              }
                              else if (Ret == 2) {
                                    TrimEA_Pull(&Both, x2, y2);
                              }
                        }
                  }
                  /* 戻す */
                  a->TraceData[3]         = Both.TraceData[1];
                  a->ellipse[3]           = Both.ellipse[1];
                  a->PicX[3]              = Both.PicX[1];
                  a->PicY[3]              = Both.PicY[1];
            }
      }





      /* トリム図形が線ならトリム実行 */
      else if (a->TraceData[1].code == 1 ) {
            if (debug > 0) g_print("トリム図形が線\n");
            Ret = TrimL(a, &x1, &y1);
            TrimL_Run(a, x1, y1);
            if (a->Index == 2 && a->TraceData[2].code != 4 ) {
                  Both.Index              = 1;
                  Both.TraceData[1] = a->TraceData[2];
                  Both.ellipse[1] = Both.ellipse[2];
                  Both.PicX[1]            = a->PicX[2];
                  Both.PicY[1]            = a->PicY[2];
                  Both.TraceData[2] = a->TraceData[1];
                  Both.ellipse[2] = Both.ellipse[1];
                  Both.PicX[2]            = a->PicX[1];
                  Both.PicY[2]            = a->PicY[1];

                  if (Both.TraceData[1].code == 1) {
                        TrimL_Run(&Both, x1, y1);
                  }
                  if (Both.TraceData[1].code == 2) {
                        Ret = TrimA(&Both, &dumy_x, &dumy_y);
                        if (Ret == 1) {
                              TrimA_Run(&Both, x1, y1);
                        }
                        else if (Ret == 2) {
                              TrimA_Pull(&Both, x1, y1);
                        }
                  }
                  if (Both.TraceData[1].code == 16) {
                        if (Both.ellipse[1].code == 1) {
                              Ret = TrimEA(&Both, &dumy_x, &dumy_y);
                              if (Ret == 1) {
                                    TrimEA_Run(&Both, x2, y2);
                              }
                              else if (Ret == 2) {
                                    TrimEA_Pull(&Both, x2, y2);
                              }
                        }
                  }
                  /* 戻す */
                  a->TraceData[2]         = Both.TraceData[1];
                  a->ellipse[2]           = Both.ellipse[1];
                  a->PicX[2]              = Both.PicX[1];
                  a->PicY[2]              = Both.PicY[1];
            }
      }





      /* トリム図形が円弧または楕円弧ならトリム実行 */
      else if ((a->TraceData[1].code == 16 && a->ellipse[1].code == 1) || a->TraceData[1].code == 2) {
            if (debug > 0) if (debug > 0) g_print("トリム図形が円弧または楕円弧\n");
            if (a->TraceData[1].code == 2) {
                  Ret = TrimA(a, &x1, &y1);
                  if (Ret == 1) {
                        TrimA_Run(a, x1, y1);
                  }
                  else if (Ret == 2) {
                        TrimA_Pull(a, x1, y1);
                  }
            }
            /* トリム図形が楕円弧 */
            if (a->TraceData[1].code == 16) {
                  if (debug > 0) g_print("トリム図形が楕円弧\n");
                  Ret = TrimEA(a, &x1, &y1);
                  if (debug > 0) g_print("Ret = %d\n", Ret);
                  if (Ret == 1) {
                        if (debug > 0) g_print("TrimEA_Run\n");
                        TrimEA_Run(a, x1, y1);
                  }
                  else if (Ret == 2) {
                        if (debug > 0) g_print("TrimEA_Pull\n");
                        TrimEA_Pull(a, x1, y1);
                  }
            }


            if (a->Index == 2 && a->TraceData[2].code != 4) {
                  Both.Index              = 1;
                  Both.TraceData[1] = a->TraceData[2];
                  Both.ellipse[1] = Both.ellipse[2];
                  Both.PicX[1]            = a->PicX[2];
                  Both.PicY[1]            = a->PicY[2];
                  Both.TraceData[2] = a->TraceData[1];
                  Both.ellipse[2] = Both.ellipse[1];
                  Both.PicX[2]            = a->PicX[1];
                  Both.PicY[2]            = a->PicY[1];

                  if (Both.TraceData[1].code == 1) {
                        TrimL_Run(&Both, x1, y1);
                  }
                  if (Both.TraceData[1].code == 2) {
                        Ret = TrimA(&Both, &dumy_x, &dumy_y);
                        if (Ret == 1) {
                              TrimA_Run(&Both, x1, y1);
                        }
                        else if (Ret == 2) {
                              TrimA_Pull(&Both, x1, y1);
                        }
                  }
                  if (Both.TraceData[1].code == 16) {
                        if (Both.ellipse[1].code == 1) {
                              Ret = TrimEA(&Both, &dumy_x, &dumy_y);
                              if (Ret == 1) {
                                    TrimEA_Run(&Both, x1, y1);
                              }
                              else if (Ret == 2) {
                                    TrimEA_Pull(&Both, x1, y1);
                              }
                        }
                  }
                  /* 戻す */
                  a->TraceData[2]         = Both.TraceData[1];
                  a->ellipse[2]           = Both.ellipse[1];
                  a->PicX[2]              = Both.PicX[1];
                  a->PicY[2]              = Both.PicY[1];
            }
      }

      return 1;
}





/* -------------------------------------------------------------------
 * 線を点でトリムする
 */
int TrimL_Point(struct TrimDat a, double *x, double *y)
{
      struct RtnDat PLPH;
      char str[256];

      /* トリム図形(線)と境界図形(点)の最近点を求める */
      PLPH.sx[1] = a.TraceData[1].sx;
      PLPH.sy[1] = a.TraceData[1].sy;
      PLPH.ex[1] = a.TraceData[1].ex;
      PLPH.ey[1] = a.TraceData[1].ey;
      PLPH.sx[2] = a.TraceData[2].sx;
      PLPH.sy[2] = a.TraceData[2].sy;
      plp(&PLPH);

      /* 交点がないなら。 */
      if (PLPH.type == 0) {
            strcpy(str, "Trim : error : ");
            strcat(str, _("There is not a point of intersection."));
            strcat(str, " (Line & Point)");
            g_print("%s\n", str);
            return 0;
      }
      /* 求めた最近点 */
      *x = PLPH.ex[2];
      *y = PLPH.ey[2];
      return 1;
}





/* -------------------------------------------------------------------
 * 線を線でトリムする
 */
int TrimL_Line(struct TrimDat a, double *x, double *y)
{
      struct RtnDat LLPH;
      char str[256];

      /* トリム図形(線)と境界図形(線)の交点を求める */
      LLPH.sx[1] = a.TraceData[1].sx;
      LLPH.sy[1] = a.TraceData[1].sy;
      LLPH.ex[1] = a.TraceData[1].ex;
      LLPH.ey[1] = a.TraceData[1].ey;
      LLPH.sx[2] = a.TraceData[2].sx;
      LLPH.sy[2] = a.TraceData[2].sy;
      LLPH.ex[2] = a.TraceData[2].ex;
      LLPH.ey[2] = a.TraceData[2].ey;
      llp(&LLPH);
      
      /* 交点がないなら */
      if (LLPH.type == 0 ) {
            strcpy(str, "Trim : error : ");
            strcat(str, _("There is not a point of intersection."));
            strcat(str, " (Line & Line)");
            g_print("%s\n", str);
            return 0;
      }
      
      /* 求めた交点 */
      *x = LLPH.sx[3];
      *y = LLPH.sy[3];
      return 1;
}





/* -------------------------------------------------------------------
 * 線を円でトリムする
 */
int TrimL_AC(struct TrimDat a, double *x, double *y)
{
      struct RtnDat LCPH, PPH;
      double L1, L2;                            /* トリム図形(線)とトリム図形(円)の交点が2個 */
      char str[256];


      /* トリム図形(線)と境界図形(円)の交点を求める */
      LCPH.cx[1] = a.TraceData[2].cx;
      LCPH.cy[1] = a.TraceData[2].cy;
      LCPH.r[1] = a.TraceData[2].r;
      LCPH.sx[1] = a.TraceData[1].sx;
      LCPH.sy[1] = a.TraceData[1].sy;
      LCPH.ex[1] = a.TraceData[1].ex;
      LCPH.ey[1] = a.TraceData[1].ey;
      lcp(&LCPH);

      /* 交点がないなら */
      if (LCPH.type == 0 ) {
            strcpy(str, "Trim : error : ");
            strcat(str, _("There is not a point of intersection."));
            strcat(str, " (Line & Circle)");
            g_print("%s\n", str);
            return 0;
      }

      /* 交点が1個のとき */
      else if (LCPH.type == 1 ) {
            /* 求めた交点 (LCPH.SX[2] , LCPH.SY[2]) */
            *x = LCPH.sx[2];
            *y = LCPH.sy[2];
            return 1;
      }

      /* 交点が2個のとき */
      else if (LCPH.type == 2 ) {
            /* クリックした点 (a.PicX[2] , a.PicY[2]) と 
             * 交点 1 (LCPH.sx[2] , LCPH.sy[2]) の距離 L1 を求める。
             */
            PPH.sx[1] = a.PicX[2];
            PPH.sy[1] = a.PicY[2];
            PPH.ex[1] = LCPH.sx[2];
            PPH.ey[1] = LCPH.sy[2];
            pp(&PPH);
            L1 = PPH.l;
            /* クリックした点 (a.PicX[2] , a.PicY[2]) と
             * 交点 2 (LCPH.SX[3] , LCPH.SY[3]) の距離 L2 を求める。
             */
            PPH.sx[1] = a.PicX[2];
            PPH.sy[1] = a.PicY[2];
            PPH.ex[1] = LCPH.sx[3];
            PPH.ey[1] = LCPH.sy[3];
            pp(&PPH);
            L2 = PPH.l;
            /* どっちの交点がクリック点に近いか?
             * 近かった交点(PointX,PointY)
             */

            /* 交点 1 の方が近い場合 */
            if (L1 < L2) {
                  /* 求めた交点 (LCPH.SX[2] , LCPH.SY[2]) */
                  *x = LCPH.sx[2];
                  *y = LCPH.sy[2];
                  return 1;
            }
            /* 交点 2 の方が近い場合 */
            else/* if (L1 > L2)*/ {
                  /* 求めた交点 (LCPH.SX[3] , LCPH.SY[3]) */
                  *x = LCPH.sx[3];
                  *y = LCPH.sy[3];
                  return 1;
            }
      }
      return 0;
}





/* -------------------------------------------------------------------
 * 線を楕円でトリムする
 */
int TrimL_E(struct TrimDat a, double *x, double *y)
{
      struct RtnDat LCPH, PPH;
      double L1, L2;                            /* トリム図形(線)とトリム図形(円)の交点が2個 */
      char str[256];


      /* トリム図形(線)と境界図形(楕円)の交点を求める */
      LCPH.sx[1] = a.TraceData[1].sx;
      LCPH.sy[1] = a.TraceData[1].sy;
      LCPH.ex[1] = a.TraceData[1].ex;
      LCPH.ey[1] = a.TraceData[1].ey;
      lep(&LCPH, a.ellipse[2], 10);

      /* 交点がないなら */
      if (LCPH.type == 0 ) {
            strcpy(str, "Trim : error : ");
            strcat(str, _("There is not a point of intersection."));
            strcat(str, " (Line & Ellipse)");
            g_print("%s\n", str);
            return 0;
      }

      /* 交点が1個のとき */
      else if (LCPH.type == 1 ) {
            /* 求めた交点 (LCPH.SX[2] , LCPH.SY[2]) */
            *x = LCPH.sx[2];
            *y = LCPH.sy[2];
            return 1;
      }

      /* 交点が2個のとき */
      else if (LCPH.type == 2 ) {
            /* クリックした点 (a.PicX[2] , a.PicY[2]) と 
             * 交点 1 (LCPH.sx[2] , LCPH.sy[2]) の距離 L1 を求める。
             */
            PPH.sx[1] = a.PicX[2];
            PPH.sy[1] = a.PicY[2];
            PPH.ex[1] = LCPH.sx[2];
            PPH.ey[1] = LCPH.sy[2];
            pp(&PPH);
            L1 = PPH.l;
            /* クリックした点 (a.PicX[2] , a.PicY[2]) と
             * 交点 2 (LCPH.SX[3] , LCPH.SY[3]) の距離 L2 を求める。
             */
            PPH.sx[1] = a.PicX[2];
            PPH.sy[1] = a.PicY[2];
            PPH.ex[1] = LCPH.sx[3];
            PPH.ey[1] = LCPH.sy[3];
            pp(&PPH);
            L2 = PPH.l;
            /* どっちの交点がクリック点に近いか?
             * 近かった交点(PointX,PointY)
             */

            /* 交点 1 の方が近い場合 */
            if (L1 < L2) {
                  /* 求めた交点 (LCPH.SX[2] , LCPH.SY[2]) */
                  *x = LCPH.sx[2];
                  *y = LCPH.sy[2];
                  return 1;
            }
            /* 交点 2 の方が近い場合 */
            else/* if (L1 > L2)*/ {
                  /* 求めた交点 (LCPH.SX[3] , LCPH.SY[3]) */
                  *x = LCPH.sx[3];
                  *y = LCPH.sy[3];
                  return 1;
            }
      }
      return 0;
}





/* -------------------------------------------------------------------
 * 線トリム実行
 */
int TrimL_Run(struct TrimDat *a, double x, double y)
{
      struct RtnDat PPH, LAH;
      double L;                                 /* トリム図形(線)の開始点と pic1 の距離 */
      double CL;                                /* トリム図形(線)の開始点とトリム点の距離 */
      double SenA;                              /* トリム図形(線)の開始点から終了点までの線の角度 */
      double ClickA;                            /* トリム図形(線)の開始点からトリム点までの線の角度 */


      /* -----------------------------------------------------------
       * 線トリム実行
       * 交点 (x , y)
       * スタート点と (a.TraceData[1].sx , a.TraceData[1].sy) の距離 L を求める。
       */
      PPH.sx[1] = a->TraceData[1].sx;
      PPH.sy[1] = a->TraceData[1].sy;
      PPH.ex[1] = a->PicX[1];
      PPH.ey[1] = a->PicY[1];
      pp(&PPH);
      L = PPH.l;

      /* スタート点と交点 (x , y) の距離 CL を求める。 */
      PPH.sx[1] = a->TraceData[1].sx;
      PPH.sy[1] = a->TraceData[1].sy;
      PPH.ex[1] = x;
      PPH.ey[1] = y;
      pp(&PPH);
      CL = PPH.l;

      /* トリム図形(線)の角度 SenA を求める。 */
      LAH.sx[1] = a->TraceData[1].sx;
      LAH.sy[1] = a->TraceData[1].sy;
      LAH.ex[1] = a->TraceData[1].ex;
      LAH.ey[1] = a->TraceData[1].ey;
      la(&LAH);
      SenA = LAH.angle;

      /* トリム図形(線)の始点から交点までの線の角度 ClickA を求める。 */
      LAH.sx[1] = a->TraceData[1].sx;
      LAH.sy[1] = a->TraceData[1].sy;
      LAH.ex[1] = x;
      LAH.ey[1] = y;
      la(&LAH);
      ClickA = LAH.angle;

      /* 線の角度とスタート点から交点までの角度が同じ時 */
      if (sg(SenA, compa_digits-2) == sg(ClickA, compa_digits-2)) {
            /* スタート点から交点 */
            if (L < CL) {
                  a->TraceData[1].ex = sg(x, calcu_digits);
                  a->TraceData[1].ey = sg(y, calcu_digits);
            }
            /* 交点からエンド点 */
            if (L > CL) {
                  a->TraceData[1].sx = sg(x, calcu_digits);
                  a->TraceData[1].sy = sg(y, calcu_digits);
            }
      }

      /* 線の角度とスタート点から交点までの角度が違う時、始点を伸ばす。 */
      else { //if (sg(SenA, compa_digits) != sg(ClickA, compa_digits)) {
            a->TraceData[1].sx = x;
            a->TraceData[1].sy = y;
      }

      return 1;
}





/* -------------------------------------------------------------------
 * 線をトリムする
 *    
 *    
 * 処理内容
 * 1 : トリム図形が線                                        error
 *     ① 境界図形が点(最近点でトリム)     TrimL_Point       -1
 *     ② 境界図形が線                     TrimL_Line        -2
 *     ③ 境界図形が円弧または円           TrimL_AC          -3
 * 2 : トリム実行
 * -------------------------------------------------------------------
 */
int TrimL(struct TrimDat *a, double *x, double *y)
{
//    double PointX = 0, PointY = 0;      /* トリムする点座標 */
      int Ret;
      char str[256];


      /* -----------------------------------------------------
       * 1 : トリム図形が線
       */
      if (a->TraceData[1].code == 1 ) {
            /* ① 境界図形が点 */
            if (a->TraceData[2].code == 0 ) {
                  /* トリム図形(線)と境界図形(点)の最近点を求める */
                  Ret = TrimL_Point(*a, x, y);
                  if (Ret == 0) {
                        strcpy(str, "Trim : error : ");
                        strcat(str, _("There is not a point of intersection."));
                        strcat(str, " (Line & Point)");
                        g_print("%s\n", str);
                        return 0;
                  }
            }
            /* ② 境界図形が線 */
            else if (a->TraceData[2].code == 1 ) {
                  /* トリム図形(線)と境界図形(線)の交点を求める */
                  Ret = TrimL_Line(*a, x, y);
                  if (Ret == 0) {
                        strcpy(str, "Trim : error : ");
                        strcat(str, _("There is not a point of intersection."));
                        strcat(str, " (Line & Line)");
                        g_print("%s\n", str);
                        return 0;
                  }
            }
            /* ③ 境界図形が円弧または円 */
            else if (a->TraceData[2].code == 2 || a->TraceData[2].code == 4) {
                  /* トリム図形(線)と境界図形(円)の交点を求める */
                  Ret = TrimL_AC(*a, x, y);
                  if (Ret == 0) {
                        strcpy(str, "Trim : error : ");
                        strcat(str, _("There is not a point of intersection."));
                        strcat(str, " (Line & Circle)");
                        g_print("%s\n", str);
                        return 0;
                  }
            }
            /* ④ 境界図形が楕円 */
            else if (a->TraceData[2].code == 16) {
                  /* トリム図形(線)と境界図形(円)の交点を求める */
                  Ret = TrimL_E(*a, x, y);
                  if (Ret == 0) {
                        strcpy(str, "Trim : error : ");
                        strcat(str, _("There is not a point of intersection."));
                        strcat(str, " (Line & Ellipse)");
                        g_print("%s\n", str);
                        return 0;
                  }
            }

            /* -----------------------------------------------------------
             * 線トリム実行
             */
//          return TrimL_Run(a, PointX, PointY);
      }
      return 1;
}





/* -------------------------------------------------------------------
 * 円弧の延長
 *    
 * コメントアウトしてある部分は、そのまま延長すると円になる部分で、
 * この動作をどうするか悩んでいるけど、とりあえず、何もしないでおく。
 *    
 */
int TrimA_Pull(struct TrimDat *a, double x, double y)
{
      struct RtnDat PPH;
      double CSL, CEL;

      /* 始点と終点のクリック点に近い方の端点を伸ばす。
       * クリック点から始点までの距離
       */
      PPH.sx[1] = a->PicX[1];
      PPH.sy[1] = a->PicY[1];
      PPH.ex[1] = a->TraceData[1].sx;
      PPH.ey[1] = a->TraceData[1].sy;
      pp(&PPH);
      CSL = PPH.l;
      /* クリック点から終点までの距離 */
      PPH.sx[1] = a->PicX[1];
      PPH.sy[1] = a->PicY[1];
      PPH.ex[1] = a->TraceData[1].ex;
      PPH.ey[1] = a->TraceData[1].ey;
      pp(&PPH);
      CEL = PPH.l;
      /* データを修正する前に、前の線を消す。
       * データを修正
       * クリック点が開始点に近い。(開始点を修正)
       */
      if (CSL < CEL) {
            /* 交点と終了点が同じなら円 */
            if (sg(x, compa_digits) == sg(a->TraceData[1].ex, compa_digits)
                  && sg(y, compa_digits) == sg(a->TraceData[1].ey, compa_digits))
            {
/*
                  Ret = MessageBox(NULL,  (LPCSTR)"交点と終了点が同じです。\n円にしますか?", 
                                                (LPCSTR)"確認" ,      
                                                MB_YESNO | MB_ICONQUESTION);
                  if (Ret == IDYES) {
                        a->TraceData[1].code = 4;
                        a->TraceData[1].sx = 0;
                        a->TraceData[1].sy = 0;
                        a->TraceData[1].ex = 0;
                        a->TraceData[1].ey = 0;
                  }
                  else
*/
                  return 0;
            }
            else {
                  a->TraceData[1].sx = sg(x, calcu_digits);
                  a->TraceData[1].sy = sg(y, calcu_digits);
                  return 1;
            }
      }


      /* クリック点がエンド点に近い。(終了点を修正) */
      else if (CSL > CEL) {
            /* 交点と開始点が同じなら円にする。*/
            if (sg(a->TraceData[1].sx, compa_digits) == sg(x, compa_digits) 
                  && sg(a->TraceData[1].sy, compa_digits) == sg(y, compa_digits)) 
            {
/*
                  Ret = MessageBox(NULL,  (LPCSTR)"交点と開始点が同じです。\n円にしますか?", 
                                                (LPCSTR)"確認" ,      
                                                MB_YESNO | MB_ICONQUESTION);
                  if (Ret == IDYES) {
                        a->TraceData[1].code = 4;
                        a->TraceData[1].sx = 0;
                        a->TraceData[1].sy = 0;
                        a->TraceData[1].ex = 0;
                        a->TraceData[1].ey = 0;
                  }
                  else
*/
                  return 0;
            }
            else {
                  a->TraceData[1].ex = sg(x, calcu_digits);
                  a->TraceData[1].ey = sg(y, calcu_digits);
                  return 1;
            }
      }
      return 0;
}





/* -------------------------------------------------------------------
 * 円弧のトリム実行
 *    
 */
int TrimA_Run(struct TrimDat *a, double x, double y)
{
      struct RtnDat LAH;
      double SA, EA, PA, KA;


      /* -----------------------------------------------------------
       * 円弧トリム実行
       */
      /* 円弧の SA & EA を求める */
      SA = Arc_SE_Angle(a->TraceData[1], 0);
      EA = Arc_SE_Angle(a->TraceData[1], 1);
      /* 中心から交点(PointX,PointY)までの角度 PA を求める。*/
      LAH.sx[1] = a->TraceData[1].cx;
      LAH.sy[1] = a->TraceData[1].cy;
      LAH.ex[1] = x;
      LAH.ey[1] = y;
      la(&LAH);
      PA = sg(LAH.angle, calcu_digits);


      /* 円弧のトリム ------------------------------------
       * 中心から交点までの角度 PA
       * 中心からクリック点までの角度 KAを求める。
       */
      LAH.sx[1] = a->TraceData[1].cx;
      LAH.sy[1] = a->TraceData[1].cy;
      LAH.ex[1] = a->PicX[1];
      LAH.ey[1] = a->PicY[1];
      la(&LAH);
      KA = sg(LAH.angle, calcu_digits);


      if (SA > EA)      EA = EA + 360;
      if (PA < SA)      PA = PA + 360;
      if (KA < SA)      KA = KA + 360;
      
      /* データを修正する前に、前の線を消す。
       * SelectColor = 2
       * SelectCadDraw (A.TraceNumber[1])
       */
      /* KA<PA */
      if (KA < PA) {
            /* 交点と開始点が同じなら円にする。*/
            if (sg(a->TraceData[1].sx, compa_digits) == sg(x, compa_digits) 
                  && sg(a->TraceData[1].sy, compa_digits) == sg(y, compa_digits)) 
            {
/*
                  Ret = MessageBox(NULL,  (LPCSTR)"交点と開始点が同じです。\n円にしますか?", 
                                                (LPCSTR)"確認" ,      
                                                MB_YESNO | MB_ICONQUESTION);
                  if (Ret == IDYES) {
                        a->TraceData[1].code = 4;
                        a->TraceData[1].sx = 0;
                        a->TraceData[1].sy = 0;
                        a->TraceData[1].ex = 0;
                        a->TraceData[1].ey = 0;
                  }
                  else
*/
                  return 0;
            }
            else {
                  a->TraceData[1].ex = sg(x, calcu_digits);
                  a->TraceData[1].ey = sg(y, calcu_digits);
                  return 1;
            }
      }
      /* KA > PA : 交点からエンド点 */
      if (KA > PA) {
            /* 交点と開始点が同じなら円にする。*/
            if (sg(a->TraceData[1].ex, compa_digits) == sg(x, compa_digits) 
                  && sg(a->TraceData[1].ey, compa_digits) == sg(y, compa_digits)) 
            {
/*
                  Ret = MessageBox(NULL,  (LPCSTR)"交点と終了点が同じです。\n円にしますか?", 
                                                (LPCSTR)"確認" ,      
                                                MB_YESNO | MB_ICONQUESTION);
                  if (Ret == IDYES) {
                        a->TraceData[1].code = 4;
                        a->TraceData[1].sx = 0;
                        a->TraceData[1].sy = 0;
                        a->TraceData[1].ex = 0;
                        a->TraceData[1].ey = 0;
                  }
                  else
*/
                  return 0;
            }
            else {
                  a->TraceData[1].sx = sg(x, calcu_digits);
                  a->TraceData[1].sy = sg(y, calcu_digits);
                  return 1;
            }
      }
      return 0;
}





/* -------------------------------------------------------------------
 * 円弧をトリムする
 *    
 * 戻値 : int    ERR : 0   OK : 1  延長 : 2
 *    
 * 処理内容
 * 2:トリム図形が円弧なら
 *            ①境界図形が点(最近点でトリム)
 *            ②境界図形が線
 *            ③境界図形が円弧または円
 *    
 * 修正内容
 *            円弧の延長トリムを考慮する。
 *    
 * 交点が SA & EA の間にないときは、クリックした点(pic2)に近い方の端点を伸ばす。
 * -------------------------------------------------------------------
 */
int TrimA(struct TrimDat *a, double *x, double *y)
{
      struct RtnDat LAH;
      double SA, EA, PA;
      char str[256];


      /* -----------------------------------------------------
       * 2 : トリム図形が円弧
       */
      if (a->TraceData[1].code == 2) {
            /* ① 境界図形が点 */
            if (a->TraceData[2].code == 0) {
                  if (TrimC_Point(*a, x, y, 2) == 0) {
                        strcpy(str, "Trim : error : ");
                        strcat(str, _("There is not a point of intersection."));
                        strcat(str, " (ARC & Point)");
                        g_print("%s\n", str);
                        return 0;
                  }
            }
            /* ② 境界図形が線 */
            if (a->TraceData[2].code == 1) {
                  if (TrimC_Line(*a, x, y, 2) == 0) {
                        strcpy(str, "Trim : error : ");
                        strcat(str, _("There is not a point of intersection."));
                        strcat(str, " (ARC & Line)");
                        g_print("%s\n", str);
                        return 0;
                  }
            }
            /* ③ 境界図形が円弧または円 */
            if (a->TraceData[2].code == 2 || a->TraceData[2].code == 4) {
                  if (TrimC_AC(*a, x, y, 2) == 0) {
                        strcpy(str, "Trim : error : ");
                        strcat(str, _("There is not a point of intersection."));
                        strcat(str, " (ARC & (ARC or Circle))");
                        g_print("%s\n", str);
                        return 0;
                  }
            }
            /* ④ 境界図形が楕円 */
            if (a->TraceData[2].code == 16) {
                  /* トリム図形(円)と境界図形(楕円)の交点を求める */
                  if (TrimC_Ellipse(*a, x, y, 2) == 0) {
                        strcpy(str, "Trim : error : ");
                        strcat(str, _("There is not a point of intersection."));
                        strcat(str, " (Circle & Ellipse)");
                        g_print("%s\n", str);
                        return 0;
                  }
            }



            /* -----------------------------------------------------------
             * 円弧トリム実行
             */
            /* 円弧の SA & EA を求める */
            SA = Arc_SE_Angle(a->TraceData[1], 0);
            EA = Arc_SE_Angle(a->TraceData[1], 1);
            /* 中心から交点(PointX,PointY)までの角度 PA を求める。*/
            LAH.sx[1] = a->TraceData[1].cx;
            LAH.sy[1] = a->TraceData[1].cy;
            LAH.ex[1] = *x;
            LAH.ey[1] = *y;
            la(&LAH);
            PA = sg(LAH.angle, calcu_digits);


            /* 円弧の延長 --------------------------------------
             * 交点が円弧上にないとき
             */
            if ( 
                  ((SA < EA) 
                  && (sg(PA, calcu_digits) < sg(SA, calcu_digits) 
                  || sg(PA, calcu_digits) > sg(EA, calcu_digits)))
                  || ((SA > EA) 
                  && (sg(PA, calcu_digits) <= sg(SA, calcu_digits) 
                  && sg(PA, calcu_digits) > sg(EA, calcu_digits)))
                  )
            {
                  return 2;
                  //TrimA_Pull(a, PointX, PointY);
            }


            /* 円弧のトリム ------------------------------------
             * 中心から交点までの角度 PA
             * 中心からクリック点までの角度 KAを求める。
             */
            return 1;
            //TrimA_Run(a, PointX, PointY, SA, EA, PA);
      }
      return 0;
}





/* -------------------------------------------------------------------
 * CAD DATA の円弧データから、SA EA を求める
 *    
 * 引数 : CAD Data, int Frag = (0:SA    1:EA)
 * 戻値 : double (Deg)
 */
double Arc_SE_Angle(CAD Data, int Frag)
{
      struct RtnDat rtn;

      /* SA */
      if (Frag == 0) {
            rtn.sx[1] = Data.cx;
            rtn.sy[1] = Data.cy;
            rtn.ex[1] = Data.sx;
            rtn.ey[1] = Data.sy;
            la(&rtn);
            return (rtn.angle);
      }

      /* EA */
      else if (Frag == 1) {
            rtn.sx[1] = Data.cx;
            rtn.sy[1] = Data.cy;
            rtn.ex[1] = Data.ex;
            rtn.ey[1] = Data.ey;
            la(&rtn);
            return (rtn.angle);
      }
      return 0;
}





/* -------------------------------------------------------------------
 * 円をトリムする関数のサブ
 *    
 * 境界図形 frag が点
 */
int TrimC_Point(struct TrimDat a, double *x, double *y, int frag)
{
      struct RtnDat LAH , PAPH;

      /* 円の中心から点に向かう線の角度Aを求める。 */
      LAH.sx[1] = a.TraceData[1].cx;
      LAH.sy[1] = a.TraceData[1].cy;
      LAH.ex[1] = a.TraceData[frag].sx;
      LAH.ey[1] = a.TraceData[frag].sy;
      la(&LAH);
      /* 円の中心から角度Aに半径の距離にある点。 */
      PAPH.sx[1] = a.TraceData[1].cx;
      PAPH.sy[1] = a.TraceData[1].cy;
      PAPH.angle = LAH.angle;
      PAPH.l = a.TraceData[1].r;
      pap(&PAPH);
      *x = PAPH.ex[1];
      *y = PAPH.ey[1];
      return 1;
}





/* -------------------------------------------------------------------
 * 円をトリムする関数のサブ
 *    
 * 境界図形 frag が線
 */
int TrimC_Line(struct TrimDat a, double *x, double *y, int frag)
{
      struct RtnDat LCPH, PPH;
      double L1, L2;
      char str[256];


      /*    */
      LCPH.cx[1] = a.TraceData[1].cx;
      LCPH.cy[1] = a.TraceData[1].cy;
      LCPH.r[1]  = a.TraceData[1].r;
      LCPH.sx[1] = a.TraceData[frag].sx;
      LCPH.sy[1] = a.TraceData[frag].sy;
      LCPH.ex[1] = a.TraceData[frag].ex;
      LCPH.ey[1] = a.TraceData[frag].ey;
      lcp(&LCPH);  // 交点(LCPH.SX[2],LCPH.SY[2])(LCPH.SX[3],LCPH.SY[3])

      /* 交点がないなら。 */
      if (LCPH.type == 0 ) {
            strcpy(str, "TrimC-1 : error : ");
            strcat(str, _("There is not a point of intersection."));
            g_print("%s\n", str);
            return 0;
      }

      /* 交点が1個        交点(LCPH.SX[2],LCPH.SY[2]) */
      else if (LCPH.type == 1 ) {
            /* 交点(LCPH.SX[2],LCPH.SY[2]) */
            *x = LCPH.sx[2];
            *y = LCPH.sy[2];
            return 1;
      }

      /* 交点が2個        交点(LCPH.SX[2],LCPH.SY[2])(LCPH.SX[3],LCPH.SY[3]) */
      else if (LCPH.type == 2 ) {
            /* クリックした点(A.PicX[2],A.PicY[2])と交点1(LCPH.SX[2],LCPH.SY[2])の距離を求める */
            PPH.sx[1] = a.PicX[frag];
            PPH.sy[1] = a.PicY[frag];
            PPH.ex[1] = LCPH.sx[2];
            PPH.ey[1] = LCPH.sy[2];
            pp(&PPH);
            L1 = PPH.l;
            /* クリックした点(A.PicX[2],A.PicY[2])と交点2(LCPH.SX[3],LCPH.SY[3])の距離を求める。 */
            PPH.sx[1] = a.PicX[frag];
            PPH.sy[1] = a.PicY[frag];
            PPH.ex[1] = LCPH.sx[3];
            PPH.ey[1] = LCPH.sy[3];
            pp(&PPH);
            L2 = PPH.l;
            /* どっちの交点がクリック点に近いか? */
            if (L1 < L2) {
                  *x = LCPH.sx[2];
                  *y = LCPH.sy[2];
                  return 1;
            }
            else if (L1 > L2) {
                  *x = LCPH.sx[3];
                  *y = LCPH.sy[3];
                  return 1;
            }
            /* 近かった交点(PointX,PointY) */
      }
      return 0;
}





/* -------------------------------------------------------------------
 * 円を円弧または円でトリムする関数のサブ
 * 
 */
int TrimC_AC(struct TrimDat a, double *x, double *y, int frag)
{
      struct RtnDat PPH, CCPH;
      double L1, L2;
      char str[256];

      /* 円と円の交点を求める。 */
      CCPH.cx[1] = a.TraceData[1].cx;
      CCPH.cy[1] = a.TraceData[1].cy;
      CCPH.r[1] = a.TraceData[1].r;
      CCPH.cx[2] = a.TraceData[frag].cx;
      CCPH.cy[2] = a.TraceData[frag].cy;
      CCPH.r[2] = a.TraceData[frag].r;
      ccp(&CCPH);  /* 交点(CCPH.SX[1],CCPH.SY[1])(CCPH.SX[2],CCPH.SY[2]) */

      /* 交点がないなら。 */
      if (CCPH.type == 0 ) {
            strcpy(str, "TrimC-3 : error : ");
            strcat(str, _("There is not a point of intersection."));
            g_print("%s\n", str);
            return 0;
      }

      /* 交点が1個のとき。 */
      else if (CCPH.type == 1 ) {
            /* 交点(CCPH.SX[1],CCPH.SY[1]) */
            *x = CCPH.sx[1];
            *y = CCPH.sy[1];
            return 1;
      }

      /* 交点が2個のとき。 */
      else if (CCPH.type == 2 ) {
            /* クリックした点(A.PicX[2],A.PicY[2])と交点1(LCPH.SX[2],LCPH.SY[2])の距離を求める。 */
            PPH.sx[1] = a.PicX[frag];
            PPH.sy[1] = a.PicY[frag];
            PPH.ex[1] = CCPH.sx[1];
            PPH.ey[1] = CCPH.sy[1];
            pp(&PPH);
            L1 = PPH.l;
            /* クリックした点(A.PicX[2],A.PicY[2])と交点2(LCPH.SX[3],LCPH.SY[3])の距離を求める。 */
            PPH.sx[1] = a.PicX[frag];
            PPH.sy[1] = a.PicY[frag];
            PPH.ex[1] = CCPH.sx[2];
            PPH.ey[1] = CCPH.sy[2];
            pp(&PPH);
            L2 = PPH.l;
            /* どっちの交点がクリック点に近いか? */
            if (L1 < L2) {
                  *x = CCPH.sx[1];
                  *y = CCPH.sy[1];
                  return 1;
            }
            else if (L1 > L2) {
                  *x = CCPH.sx[2];
                  *y = CCPH.sy[2];
                  return 1;
            }
            /* 近かった交点(PointX,PointY) */
      }
      return 0;
}





/* -------------------------------------------------------------------
 * 円を楕円でトリムする関数のサブ
 * 
 */
int TrimC_Ellipse(struct TrimDat a, double *x, double *y, int frag)
{
      struct RtnDat PPH, rtn;
      double min_value;
      int i, min;
      ELLIPSE ellipseA;
      char str[256];


      /* 楕円と円の交点を求める。 */
      ellipseA.cx = a.TraceData[1].cx;
      ellipseA.cy = a.TraceData[1].cy;
      ellipseA.dx = a.TraceData[1].r;
      ellipseA.dy = 0;
      ellipseA.k = 1;
      ellipseA.sa = 0;
      ellipseA.ea = 360;

      ellipse_on_ellipse(&rtn, ellipseA, a.ellipse[frag]);

      /* 交点がないなら。 */
      if (rtn.type == 0 ) {
            strcpy(str, "TrimC-Ellipse() : error : ");
            strcat(str, _("There is not a point of intersection."));
            g_print("%s\n", str);
            return 0;
      }

      /* 交点が n 個のとき。 */
      else if (rtn.type > 0 ) {
            min = 0;
            min_value = 0;
            for (i = 1 ; i < rtn.type + 1 ; i++) {
                  /* クリックした点(A.PicX[2],A.PicY[2])と交点1(LCPH.SX[2],LCPH.SY[2])の距離を求める。 */
                  PPH.sx[1] = a.PicX[frag];
                  PPH.sy[1] = a.PicY[frag];
                  PPH.ex[1] = rtn.sx[i];
                  PPH.ey[1] = rtn.sy[i];
                  pp(&PPH);
                  if (min == 0 || min_value > PPH.l) {
                        min = i;
                        min_value = PPH.l;
                  }
            }

            if (min == 0) {
                  return 0;
            }

            else {
                  *x = rtn.sx[min];
                  *y = rtn.sy[min];
                  //g_print("TrimC_Ellipse() : (%f,%f)\n", *x, *y);
                  return 1;
            }
      }

      return 0;
}





/* -------------------------------------------------------------------
 * 説明 : 円をトリムする
 * 関数 : TrimC
 * 引数 : struct TrimDat *
 * 戻値 : int
 *          : ERR : 0    OK : 1
 * 外部 : 無し
 * 内部 : 無し
 *          : 
 * -------------------------------------------------------------------
 * 処理内容
 * 1 : トリム図形が円
 *          ① 境界図形 2 が点
 *          ② 境界図形 3 が点
 *          ③ 境界図形 2 が線
 *          ④ 境界図形 3 が線
 *          ⑤ 境界図形 2 が円弧または円
 *          ⑥ 境界図形 3 が円弧または円
 *    
 */
int TrimC(struct TrimDat *a, double *x1, double *y1, double *x2, double *y2)
{
      char str[256];


      /* ① 境界図形 2 が点 */
      if (a->TraceData[2].code == 0 ) {
            if (TrimC_Point(*a, x1, y1, 2) == 0)
                  return 0;
      }
      /* ② 境界図形 3 が点 */
      if (a->TraceData[3].code == 0 ) {
            if (TrimC_Point(*a, x2, y2, 3) == 0)
                  return 0;
      }
      /* ③ 境界図形 2 が線 */
      if (a->TraceData[2].code == 1 ) {
            if (TrimC_Line(*a, x1, y1, 2) == 0)
                  return 0;
      }
      /* ④ 境界図形 3 が線 */
      if (a->TraceData[3].code == 1 ) {
            if (TrimC_Line(*a, x2, y2, 3) == 0)
                  return 0;
      }
      /* ⑤ 境界図形2が円弧 */
      if (a->TraceData[2].code == 2 || a->TraceData[2].code == 4 ) {
            if (TrimC_AC(*a, x1, y1, 2) == 0)
                  return 0;
      }
      /* ⑥ 境界図形 3 が円弧 */
      if (a->TraceData[3].code == 2 || a->TraceData[3].code == 4 ) {
            if (TrimC_AC(*a, x2, y2, 3) == 0)
                  return 0;
      }
      /* ⑦ 境界図形 2 が楕円 */
      if (a->TraceData[2].code == 16) {
            /* トリム図形(線)と境界図形(円)の交点を求める */
            if (TrimC_Ellipse(*a, x1, y1, 2) == 0) {
                  strcpy(str, "Trim : error : ");
                  strcat(str, _("There is not a point of intersection."));
                  strcat(str, " (Circle & Ellipse)");
                  g_print("%s\n", str);
                  return 0;
            }
      }
      /* ⑧ 境界図形 3 が楕円 */
      if (a->TraceData[3].code == 16) {
            /* トリム図形(線)と境界図形(円)の交点を求める */
            if (TrimC_Ellipse(*a, x2, y2, 3) == 0) {
                  strcpy(str, "Trim : error : ");
                  strcat(str, _("There is not a point of intersection."));
                  strcat(str, " (Circle & Ellipse)");
                  g_print("%s\n", str);
                  return 0;
            }
      }


      return 1;
}





/* -------------------------------------------------------------------
 * 説明 : 円をトリムする
 * 関数 : TrimC_Run
 * 引数 : struct TrimDat *
 * 戻値 : int
 *          : ERR : 0    OK : 1
 * 外部 : 無し
 * 内部 : 無し
 *          : 
 * -------------------------------------------------------------------
 * 処理内容
 * 1 : トリム図形が円
 *          ① 境界図形 2 が点
 *          ② 境界図形 3 が点
 *          ③ 境界図形 2 が線
 *          ④ 境界図形 3 が線
 *          ⑤ 境界図形 2 が円弧または円
 *          ⑥ 境界図形 3 が円弧または円
 *    
 */
int TrimC_Run(struct TrimDat *a, double *x1, double *y1, double *x2, double *y2)
{
      struct RtnDat LAH;
      double K1A, K2A, CA;


      /* ---------------------------------------------------------------
       * 円トリム実行
       * 
       * 交点 ( PointX , PointY ) ( PointX2 , PointY2 )
       */
      /* 交点 ( PointX , PointY ) の角度 K1A を求める。 */
      LAH.sx[1] = a->TraceData[1].cx;
      LAH.sy[1] = a->TraceData[1].cy;
      LAH.ex[1] = *x1;
      LAH.ey[1] = *y1;
      la(&LAH);
      K1A = LAH.angle;
      /* 交点 ( PointX2 , PointY2 ) の角度 K2A を求める。 */
      LAH.sx[1] = a->TraceData[1].cx;
      LAH.sy[1] = a->TraceData[1].cy;
      LAH.ex[1] = *x2;
      LAH.ey[1] = *y2;
      la(&LAH);
      K2A = LAH.angle;
      /* クリック点 ( A.PicX[1] , A.PicY[1] ) の角度 CA を求める。 */
      LAH.sx[1] = a->TraceData[1].cx;
      LAH.sy[1] = a->TraceData[1].cy;
      LAH.ex[1] = a->PicX[1];
      LAH.ey[1] = a->PicY[1];
      la(&LAH);
      CA = LAH.angle;

      /* データを修正する前に、前の線を消す。 */
      if (K1A < CA && CA < K2A ) {
            /* START(PointX,PointY)   END(PointX2,PointY2) */
            a->TraceData[1].code = 2;
            a->TraceData[1].sx = *x1;
            a->TraceData[1].sy = *y1;
            a->TraceData[1].ex = *x2;
            a->TraceData[1].ey = *y2;
      }
      else if (K2A < CA && CA < K1A ) {
            /* START(PointX2,PointY2)     END(PointX,PointY) */
            a->TraceData[1].code = 2;
            a->TraceData[1].sx = *x2;
            a->TraceData[1].sy = *y2;
            a->TraceData[1].ex = *x1;
            a->TraceData[1].ey = *y1;
      }
      else if (((CA > K1A && CA > K2A) || (CA < K1A && CA < K2A)) && K2A > K1A) {
            /* START(PointX2,PointY2)     END(PointX,PointY) */
            a->TraceData[1].code = 2;
            a->TraceData[1].sx = *x2;
            a->TraceData[1].sy = *y2;
            a->TraceData[1].ex = *x1;
            a->TraceData[1].ey = *y1;
      }
      else if (((CA > K1A && CA > K2A) || (CA < K1A && CA < K2A)) && K2A < K1A) {
            /* START(PointX,PointY)   END(PointX2,PointY2) */
            a->TraceData[1].code = 2;
            a->TraceData[1].sx = *x1;
            a->TraceData[1].sy = *y1;
            a->TraceData[1].ex = *x2;
            a->TraceData[1].ey = *y2;
      }
      return 1;
}










/* -------------------------------------------------------------------
 * 楕円を点でトリムする関数のサブ
 * 
 * 境界図形 frag が点
 */
int TrimE_Point(struct TrimDat a, double *x, double *y, int frag)
{
      SAG_POINT point;
      double angle;


      /* 円の中心から点に向かう線の角度Aを求める。 */
      point.x = a.TraceData[frag].sx;
      point.y = a.TraceData[frag].sy;
      angle = get_ellipse_angle_from_point (a.ellipse[1], point);

      point.x = 0;
      point.y = 0;
      get_ellipse_point_from_angle (a.ellipse[1], angle, &point);
      *x = point.x;
      *y = point.y;

      return 1;
}





/* -------------------------------------------------------------------
 * 楕円をトリムする関数のサブ
 * 
 * 境界図形 frag が線
 */
int TrimE_Line(struct TrimDat a, double *x, double *y, int frag)
{
      struct RtnDat rtn, PPH;
      double L1, L2;
      char str[256];


      /* -------------------------------------------------------------------
       * 楕円と線の交点
       * lep
       * RtnDat
       *   線   : (sx[1],sy[1]) - (ex[1],ey[1])
       *   楕円 : 
       * RtnDat
       *   type   0 , 1 , 2
       *   点 1  (sx[2],sy[2])
       *   点 2  (sx[3],sy[3])
       */

      /* トリム図形(線)と境界図形(円)の交点を求める */
      rtn.sx[1] = a.TraceData[frag].sx;
      rtn.sy[1] = a.TraceData[frag].sy;
      rtn.ex[1] = a.TraceData[frag].ex;
      rtn.ey[1] = a.TraceData[frag].ey;
      lep(&rtn, a.ellipse[1], 10);

      /* 交点がないなら。 */
      if (rtn.type == 0 ) {
            strcpy(str, "TrimE-Line : error : ");
            strcat(str, _("There is not a point of intersection."));
            g_print("%s\n", str);
            return 0;
      }

      /* 交点が1個        交点(rtn.SX[2],rtn.SY[2]) */
      else if (rtn.type == 1 ) {
            /* 交点(rtn.SX[2],rtn.SY[2]) */
            *x = rtn.sx[2];
            *y = rtn.sy[2];
//          g_print("TrimE_Line() : 1 (%f,%f)\n", rtn.sx[2], rtn.sy[2]);
            return 1;
      }

      /* 交点が2個        交点(rtn.SX[2],rtn.SY[2])(rtn.SX[3],rtn.SY[3]) */
      else if (rtn.type == 2 ) {
            /* クリックした点(A.PicX[2],A.PicY[2])と交点1(rtn.SX[2],rtn.SY[2])の距離を求める */
            PPH.sx[1] = a.PicX[frag];
            PPH.sy[1] = a.PicY[frag];
            PPH.ex[1] = rtn.sx[2];
            PPH.ey[1] = rtn.sy[2];
            pp(&PPH);
            L1 = PPH.l;
            /* クリックした点(A.PicX[2],A.PicY[2])と交点2(rtn.SX[3],rtn.SY[3])の距離を求める。 */
            PPH.sx[1] = a.PicX[frag];
            PPH.sy[1] = a.PicY[frag];
            PPH.ex[1] = rtn.sx[3];
            PPH.ey[1] = rtn.sy[3];
            pp(&PPH);
            L2 = PPH.l;

//          g_print("TrimE_Line() : 1(%f,%f),%f   2(%f,%f),%f   P(%f,%f)\n", 
//                      rtn.sx[2], rtn.sy[2], L1, 
//                      rtn.sx[3], rtn.sy[3], L2, 
//                      a.PicX[frag], a.PicY[frag]);

            /* どっちの交点がクリック点に近いか? */
            if (L1 < L2) {
                  *x = rtn.sx[2];
                  *y = rtn.sy[2];
//                g_print("TrimE_Line() : Ans (%f,%f)\n", rtn.sx[2], rtn.sy[2]);
                  return 1;
            }
            else if (L1 > L2) {
                  *x = rtn.sx[3];
                  *y = rtn.sy[3];
//                g_print("TrimE_Line() : Ans (%f,%f)\n", rtn.sx[3], rtn.sy[3]);
                  return 1;
            }
            /* 近かった交点(PointX,PointY) */
      }
      return 0;
}





/* -------------------------------------------------------------------
 * 楕円を円弧または円でトリムする関数のサブ
 * 
 */
int TrimE_AC(struct TrimDat a, double *x, double *y, int frag)
{
      struct RtnDat PPH, rtn;
      double min_value;
      int i, min;
      ELLIPSE ellipseB;
      char str[256];


      /* 楕円と円の交点を求める。 */
      ellipseB.cx = a.TraceData[frag].cx;
      ellipseB.cy = a.TraceData[frag].cy;
      ellipseB.dx = a.TraceData[frag].r;
      ellipseB.dy = 0;
      ellipseB.k = 1;
      ellipseB.sa = 0;
      ellipseB.ea = 360;

      ellipse_on_ellipse(&rtn, a.ellipse[1], ellipseB);

      /* 交点がないなら。 */
      if (rtn.type == 0 ) {
            strcpy(str, "TrimE-AC() : error : ");
            strcat(str, _("There is not a point of intersection."));
            g_print("%s\n", str);
            return 0;
      }

      /* 交点が n 個のとき。 */
      else if (rtn.type > 0 ) {
            min = 0;
            min_value = 0;
            for (i = 1 ; i < rtn.type + 1 ; i++) {
                  /* クリックした点(A.PicX[2],A.PicY[2])と交点1(LCPH.SX[2],LCPH.SY[2])の距離を求める。 */
                  PPH.sx[1] = a.PicX[frag];
                  PPH.sy[1] = a.PicY[frag];
                  PPH.ex[1] = rtn.sx[i];
                  PPH.ey[1] = rtn.sy[i];
                  pp(&PPH);
                  if (min == 0 || min_value > PPH.l) {
                        min = i;
                        min_value = PPH.l;
                  }
            }

            if (min == 0) {
                  return 0;
            }

            else {
                  *x = rtn.sx[min];
                  *y = rtn.sy[min];
                  //g_print("TrimE_AC() : (%f,%f)\n", *x, *y);
                  return 1;
            }
      }

      return 0;
}





/* -------------------------------------------------------------------
 * 楕円をトリムする関数のサブ
 * 
 * 境界図形 frag が楕円
 */
int TrimE_Ellipse(struct TrimDat a, double *x, double *y, int frag)
{
      struct RtnDat PPH, rtn;
      double min_value;
      int i, min;
      char str[256];


      ellipse_on_ellipse(&rtn, a.ellipse[1], a.ellipse[frag]);


      /* 交点がないなら。 */
      if (rtn.type == 0 ) {
            strcpy(str, "TrimE-Ellipse : error : ");
            strcat(str, _("There is not a point of intersection."));
            g_print("%s\n", str);
            return 0;
      }

      /* 交点が n 個のとき。 */
      else if (rtn.type > 0 ) {
            min = 0;
            min_value = 0;
            for (i = 1 ; i < rtn.type + 1 ; i++) {
                  /* クリックした点(A.PicX[2],A.PicY[2])と交点1(LCPH.SX[2],LCPH.SY[2])の距離を求める。 */
                  PPH.sx[1] = a.PicX[frag];
                  PPH.sy[1] = a.PicY[frag];
                  PPH.ex[1] = rtn.sx[i];
                  PPH.ey[1] = rtn.sy[i];
                  pp(&PPH);
                  if (min == 0 || min_value > PPH.l) {
                        min = i;
                        min_value = PPH.l;
                  }
            }

            if (min == 0) {
                  return 0;
            }

            else {
                  *x = rtn.sx[min];
                  *y = rtn.sy[min];
                  //g_print("TrimE_Ellipse() : (%f,%f)\n", *x, *y);
                  return 1;
            }
      }

      return 0;
}





/* -------------------------------------------------------------------
 * 説明 : 楕円をトリムする
 * 関数 : TrimE
 * 引数 : struct TrimDat *
 * 戻値 : int
 *          : ERR : 0    OK : 1
 * 外部 : 無し
 * 内部 : 無し
 *          : 
 * -------------------------------------------------------------------
 * 処理内容
 * 1 : トリム図形が円
 *          ① 境界図形 2 が点
 *          ② 境界図形 3 が点
 *          ③ 境界図形 2 が線
 *          ④ 境界図形 3 が線
 *          ⑤ 境界図形 2 が円弧または円
 *          ⑥ 境界図形 3 が円弧または円
 *    
 */
int TrimE(struct TrimDat *a, double *x1, double *y1, double *x2, double *y2)
{
//#define TRIME
      int debug = 0;


#ifdef TRIME
      debug = 1;
#endif


      /* ① 境界図形 2 が点 */
      if (a->TraceData[2].code == 0 ) {
            if (debug > 0) g_print("TrimE() : 1\n");
            if (TrimE_Point(*a, x1, y1, 2) == 0) {
                  if (debug > 0) g_print("TrimE() : 1 : error\n");
                  return 0;
            }
      }
      /* ② 境界図形 3 が点 */
      if (a->TraceData[3].code == 0 ) {
            if (debug > 0) g_print("TrimE() : 2\n");
            if (TrimE_Point(*a, x2, y2, 3) == 0) {
                  if (debug > 0) g_print("TrimE() : 2 : error\n");
                  return 0;
            }
      }
      /* ③ 境界図形 2 が線 */
      if (a->TraceData[2].code == 1 ) {
            if (debug > 0) g_print("TrimE() : 3\n");
            if (TrimE_Line(*a, x1, y1, 2) == 0) {
                  if (debug > 0) g_print("TrimE() : 3 : error\n");
                  return 0;
            }
      }
      /* ④ 境界図形 3 が線 */
      if (a->TraceData[3].code == 1 ) {
            if (debug > 0) g_print("TrimE() : 4\n");
            if (TrimE_Line(*a, x2, y2, 3) == 0) {
                  if (debug > 0) g_print("TrimE() : 4 : error\n");
                  return 0;
            }
      }
      /* ⑤ 境界図形2が円弧 */
      if (a->TraceData[2].code == 2 || a->TraceData[2].code == 4 ) {
            if (debug > 0) g_print("TrimE() : 5\n");
            if (TrimE_AC(*a, x1, y1, 2) == 0) {
                  if (debug > 0) g_print("TrimE() : 5 : error\n");
                  return 0;
            }
      }
      /* ⑥ 境界図形 3 が円弧 */
      if (a->TraceData[3].code == 2 || a->TraceData[3].code == 4 ) {
            if (debug > 0) g_print("TrimE() : 6\n");
            if (TrimE_AC(*a, x2, y2, 3) == 0) {
                  if (debug > 0) g_print("TrimE() : 6 : error\n");
                  return 0;
            }
      }
      /* ⑦ 境界図形 2 が楕円 */
      if (a->TraceData[2].code == 16) {
            if (debug > 0) g_print("TrimE() : 7\n");
            if (TrimE_Ellipse(*a, x1, y1, 2) == 0) {
                  if (debug > 0) g_print("TrimE() : 7 : error\n");
                  return 0;
            }
      }
      /* ⑧ 境界図形 3 が楕円 */
      if (a->TraceData[3].code == 16) {
            if (debug > 0) g_print("TrimE() : 8\n");
            if (TrimE_Ellipse(*a, x2, y2, 3) == 0) {
                  if (debug > 0) g_print("TrimE() : 8 : error\n");
                  return 0;
            }
      }

      return 1;
}





/* -------------------------------------------------------------------
 * 説明 : 円をトリムする
 * 関数 : TrimC_Run
 * 引数 : struct TrimDat *
 * 戻値 : int
 *          : ERR : 0    OK : 1
 * 外部 : 無し
 * 内部 : 無し
 *          : 
 * -------------------------------------------------------------------
 * 処理内容
 * 1 : トリム図形が円
 *          ① 境界図形 2 が点
 *          ② 境界図形 3 が点
 *          ③ 境界図形 2 が線
 *          ④ 境界図形 3 が線
 *          ⑤ 境界図形 2 が円弧または円
 *          ⑥ 境界図形 3 が円弧または円
 *    
 */
int TrimE_Run(struct TrimDat *a, double *x1, double *y1, double *x2, double *y2)
{
      double K1A, K2A, CA;
      SAG_POINT point;


      /* ---------------------------------------------------------------
       * 円トリム実行
       * 
       * 交点 ( PointX , PointY ) ( PointX2 , PointY2 )
       */
      /* 交点1 ( PointX , PointY ) の角度 K1A を求める。 */
      point.x = *x1;
      point.y = *y1;
      K1A = get_ellipse_angle_from_point (a->ellipse[1], point);

      /* 交点2 ( PointX2 , PointY2 ) の角度 K2A を求める。 */
      point.x = *x2;
      point.y = *y2;
      K2A = get_ellipse_angle_from_point (a->ellipse[1], point);

      /* クリック点 ( A.PicX[1] , A.PicY[1] ) の角度 CA を求める。 */
      point.x = a->PicX[1];
      point.y = a->PicY[1];
      CA = get_ellipse_angle_from_point (a->ellipse[1], point);


      /* データを修正する前に、前の線を消す。 */
      if (K1A < CA && CA < K2A ) {
            /* START(PointX,PointY)   END(PointX2,PointY2) */
            a->ellipse[1].sa = K1A;
            a->ellipse[1].ea = K2A;
      }
      else if (K2A < CA && CA < K1A ) {
            /* START(PointX2,PointY2)     END(PointX,PointY) */
            a->ellipse[1].sa = K2A;
            a->ellipse[1].ea = K1A;
      }
      else if (((CA > K1A && CA > K2A) || (CA < K1A && CA < K2A)) && K2A > K1A) {
            /* START(PointX2,PointY2)     END(PointX,PointY) */
            a->ellipse[1].sa = K2A;
            a->ellipse[1].ea = K1A;
      }
      else if (((CA > K1A && CA > K2A) || (CA < K1A && CA < K2A)) && K2A < K1A) {
            /* START(PointX,PointY)   END(PointX2,PointY2) */
            a->ellipse[1].sa = K1A;
            a->ellipse[1].ea = K2A;
      }
      return 1;
}





/* -------------------------------------------------------------------
 * 円弧の延長
 *    
 * コメントアウトしてある部分は、そのまま延長すると円になる部分で、
 * この動作をどうするか悩んでいるけど、とりあえず、何もしないでおく。
 *    
 */
int TrimEA_Pull(struct TrimDat *a, double x, double y)
{
      struct RtnDat PPH;
      double PA, CSL, CEL;
      SAG_POINT s_point, e_point, point;


      /* 始点と終点のクリック点に近い方の端点を伸ばす。
       * クリック点から始点までの距離
       */
      get_ellipse_point_from_angle (a->ellipse[1], a->ellipse[1].sa, &s_point);
      PPH.sx[1] = a->PicX[1];
      PPH.sy[1] = a->PicY[1];
      PPH.ex[1] = s_point.x;
      PPH.ey[1] = s_point.y;
      pp(&PPH);
      CSL = PPH.l;
      /* クリック点から終点までの距離 */
      get_ellipse_point_from_angle (a->ellipse[1], a->ellipse[1].ea, &e_point);
      PPH.sx[1] = a->PicX[1];
      PPH.sy[1] = a->PicY[1];
      PPH.ex[1] = e_point.x;
      PPH.ey[1] = e_point.y;
      pp(&PPH);
      CEL = PPH.l;


      /* 中心から交点(PointX,PointY)までの角度 PA を求める。*/
      point.x = x;
      point.y = y;
      PA = get_ellipse_angle_from_point (a->ellipse[1], point);


      /* データを修正する前に、前の線を消す */
      if (CSL < CEL) {
            /* 交点と終了点が同じなら円 */
            if (sg(a->ellipse[1].ea, compa_digits) == sg(PA, compa_digits)) {
/*
                  Ret = MessageBox(NULL,  (LPCSTR)"交点と終了点が同じです。\n円にしますか?", 
                                                (LPCSTR)"確認" ,      
                                                MB_YESNO | MB_ICONQUESTION);
                  if (Ret == IDYES) {
                        a->TraceData[1].code = 4;
                        a->TraceData[1].sx = 0;
                        a->TraceData[1].sy = 0;
                        a->TraceData[1].ex = 0;
                        a->TraceData[1].ey = 0;
                  }
                  else
*/
                  return 0;
            }
            else {
                  a->ellipse[1].sa = PA;
                  return 1;
            }
      }


      /* クリック点がエンド点に近い。(終了点を修正) */
      else if (CSL > CEL) {
            /* 交点と開始点が同じなら円にする。*/
            if (sg(a->ellipse[1].sa, compa_digits) == sg(PA, compa_digits)) {
/*
                  Ret = MessageBox(NULL,  (LPCSTR)"交点と開始点が同じです。\n円にしますか?", 
                                                (LPCSTR)"確認" ,      
                                                MB_YESNO | MB_ICONQUESTION);
                  if (Ret == IDYES) {
                        a->TraceData[1].code = 4;
                        a->TraceData[1].sx = 0;
                        a->TraceData[1].sy = 0;
                        a->TraceData[1].ex = 0;
                        a->TraceData[1].ey = 0;
                  }
                  else
*/
                  return 0;
            }
            else {
                  a->ellipse[1].ea = PA;
                  return 1;
            }
      }
      return 0;
}





/* -------------------------------------------------------------------
 * 楕円弧のトリム実行
 *    
 */
int TrimEA_Run(struct TrimDat *a, double x, double y)
{
//#define TRIMEA_RUN
      double SA, EA, PA, KA, sa, ea, pa, ka;
      SAG_POINT point;
      int debug = 0;


#ifdef TRIMEA_RUN
      debug = 1;
#endif

      /* -----------------------------------------------------------
       * 円弧トリム実行
       */
      /* 円弧の SA & EA を求める */
      SA = a->ellipse[1].sa;
      EA = a->ellipse[1].ea;
      /* 中心から交点(PointX,PointY)までの角度 PA を求める。*/
      point.x = x;
      point.y = y;
      PA = get_ellipse_angle_from_point (a->ellipse[1], point);
      angle_check(&PA);
      if (debug > 0) g_print("TrimEA_Run() : PA = %f (%f,%f)\n", PA, x, y);

      /* 円弧のトリム ------------------------------------
       * 中心から交点までの角度 PA
       * 中心からクリック点までの角度 KAを求める。
       */
      point.x = a->PicX[1];
      point.y = a->PicY[1];
      KA = get_ellipse_angle_from_point (a->ellipse[1], point);
      angle_check(&KA);
      if (debug > 0) g_print("TrimEA_Run() : KA = %f (%f,%f)\n", KA, a->PicX[1], a->PicY[1]);


      if (debug > 0) g_print("TrimEA_Run() : SA = %f   EA = %f   PA = %f   KA = %f\n", SA, EA, PA, KA);



      sa = SA;
      ea = EA;
      pa = PA;
      ka = KA;
      if (SA > EA) {
            ea = EA + 360;
            if (SA > PA) pa = PA + 360;
            if (SA > KA) ka = KA + 360;
      }


      /* KA < PA : 交点から開始点 */
      if (ka < pa) {
            if (debug > 0) g_print("TrimEA_Run() : KA < PA : 交点から開始点\n");
            /* 交点と開始点が同じなら円にする。*/
            if (sg(SA, compa_digits) == sg(PA, compa_digits)) {
                  return 0;
            }
            else {
                  if (debug > 0) g_print("TrimEA_Run() : 終了点を修正\n");
                  a->ellipse[1].ea = PA;
                  return 1;
            }
      }

      /* KA > PA : 交点から終了点 */
      if (ka > pa) {
            if (debug > 0) g_print("TrimEA_Run() : KA > PA : 交点から終了点\n");
            /* 交点と終了点が同じなら円にする。*/
            if (sg(a->ellipse[1].ea, compa_digits) == sg(PA, compa_digits)) { 
                  if (debug > 0) g_print("TrimEA_Run() : 交点と終了点が同じ\n");
                  return 0;
            }
            else {
                  if (debug > 0) g_print("TrimEA_Run() : 開始点を修正\n");
                  a->ellipse[1].sa = PA;
                  return 1;
            }
      }


      return 0;
}





/* -------------------------------------------------------------------
 * 円弧をトリムする
 *    
 * 戻値 : int    ERR : 0   OK : 1  延長 : 2
 *    
 * 処理内容
 * 2:トリム図形が円弧なら
 *            ①境界図形が点(最近点でトリム)
 *            ②境界図形が線
 *            ③境界図形が円弧または円
 *    
 * 修正内容
 *            円弧の延長トリムを考慮する。
 *    
 * 交点が SA & EA の間にないときは、クリックした点(pic2)に近い方の端点を伸ばす。
 * -------------------------------------------------------------------
 */
int TrimEA(struct TrimDat *a, double *x, double *y)
{
//#define TRIMEA
      double SA, EA, PA;
      SAG_POINT point;
      int debug = 0;
      char str[256];


#ifdef TRIMEA
      debug = 1;
#endif


      /* -----------------------------------------------------
       * 2 : トリム図形が円弧
       */
      if (a->TraceData[1].code == 16 && a->ellipse[1].code == 1) {
            /* ① 境界図形が点 */
            if (a->TraceData[2].code == 0) {
                  if (debug > 0) g_print("TrimEA() : 1\n");
                  if (TrimE_Point(*a, x, y, 2) == 0) {
                        strcpy(str, "TrimEA : error : ");
                        strcat(str, _("There is not a point of intersection."));
                        strcat(str, " (ELLIPSE & Point)");
                        g_print("%s\n", str);
                        return 0;
                  }
            }
            /* ② 境界図形が線 */
            else if (a->TraceData[2].code == 1) {
                  if (debug > 0) g_print("TrimEA() : 2\n");
                  if (TrimE_Line(*a, x, y, 2) == 0) {
                        strcpy(str, "TrimEA : error : ");
                        strcat(str, _("There is not a point of intersection."));
                        strcat(str, " (ELLIPSE & Line)");
                        g_print("%s\n", str);
                        return 0;
                  }
            }
            /* ③ 境界図形が円弧または円 */
            else if (a->TraceData[2].code == 2 || a->TraceData[2].code == 4) {
                  if (debug > 0) g_print("TrimEA() : 3\n");
                  if (TrimE_AC(*a, x, y, 2) == 0) {
                        strcpy(str, "TrimEA : error : ");
                        strcat(str, _("There is not a point of intersection."));
                        strcat(str, " (ELLIPSE & (ARC or Circle)");
                        g_print("%s\n", str);
                        return 0;
                  }
            }
            /* ④ 境界図形が楕円または楕円弧 */
            else if (a->TraceData[2].code == 16) {
                  if (debug > 0) g_print("TrimEA() : 4\n");
                  if (TrimE_Ellipse(*a, x, y, 2) == 0) {
                        strcpy(str, "TrimEA : error : ");
                        strcat(str, _("There is not a point of intersection."));
                        strcat(str, " (ELLIPSE & (ARC or Circle)");
                        g_print("%s\n", str);
                        return 0;
                  }
            }


            /* -----------------------------------------------------------
             * 円弧トリム実行
             */
            /* 円弧の SA & EA を求める */
            SA = a->ellipse[1].sa;
            EA = a->ellipse[1].ea;
            /* 中心から交点(PointX,PointY)までの角度 PA を求める。*/
            point.x = *x;
            point.y = *y;
            PA = get_ellipse_angle_from_point (a->ellipse[1], point);


            if (debug > 0) g_print("TrimEA() : SA = %f   EA = %f   PA = %f\n", SA, EA, PA);


            /* 円弧の延長 --------------------------------------
             * 交点が円弧上にないとき
             */
            if ( 
                  (     (SA < EA) && (PA < SA || PA > EA)   )
                  || 
                  (     (SA > EA) && (PA < SA && PA > EA)   )
                  )
            {
                  if (debug > 0) g_print("TrimEA() : 円弧の延長\n");
                  return 2;
                  //TrimA_Pull(a, PointX, PointY);
            }


            /* 円弧のトリム ------------------------------------
             * 中心から交点までの角度 PA
             * 中心からクリック点までの角度 KAを求める。
             */
            if (debug > 0) g_print("TrimEA() : 円弧のトリム\n");
            return 1;
            //TrimA_Run(a, PointX, PointY, SA, EA, PA);
      }
      return 0;
}





/* -------------------------------------------------------------------
 * 説明 : 線&円弧を分割する
 * 関数 : Split
 * 引数 : struct TrimDat *
 * 戻値 : int  NewData = a->TraceData[3]
 *          : ERR : 0    OK : 1
 * 外部 : 無し
 * 内部 : 無し
 *          : 
 * -------------------------------------------------------------------
 * 処理内容
 * 1 : トリム図形が 線
 *          ① 境界図形が 点(最近点で分割)
 *          ② 境界図形が 線
 *          ③ 境界図形が 円弧または円
 *          ④ 境界図形が 楕円弧または楕円
 * 2 : トリム図形が 円弧
 *          ① 境界図形が 点(最近点で分割)
 *          ② 境界図形が 線
 *          ③ 境界図形が 円弧または円
 *          ④ 境界図形が 楕円弧または楕円
 * 3 : トリム図形が 楕円弧
 *          ① 境界図形が 点(最近点で分割)
 *          ② 境界図形が 線
 *          ③ 境界図形が 円弧または円
 *          ④ 境界図形が 楕円弧または楕円
 * -------------------------------------------------------------------
 */
int Split(struct TrimDat *a)
{
      char str[256];
      struct RtnDat LAH;
      double PointX, PointY, SA, EA, PA;
      SAG_POINT point;


      /* -----------------------------------------------------
       * 1 : 分割する図形が 線
       */
      if (a->TraceData[1].code == 1) {
            /* ① 境界図形が 点 */
            if (a->TraceData[2].code == 0) {
                  if (TrimL_Point(*a, &PointX, &PointY) == 0) {
                        strcpy(str, "Split-10 : error : ");
                        strcat(str, _("There is not a point of intersection."));
                        g_print("%s\n", str);
                        return 0;
                  }
            }
            /* ② 境界図形が 線 */
            else if (a->TraceData[2].code == 1 ) {
                  if (TrimL_Line(*a, &PointX, &PointY) == 0) {
                        strcpy(str, "Split-11 : error : ");
                        strcat(str, _("There is not a point of intersection."));
                        g_print("%s\n", str);
                        return 0;
                  }
            }
            /* ③ 境界図形が 円弧または円 */
            else if (a->TraceData[2].code == 2 || a->TraceData[2].code == 4) {
                  if (TrimL_AC(*a, &PointX, &PointY) == 0) {
                        strcpy(str, "Split-12 : error : ");
                        strcat(str, _("There is not a point of intersection."));
                        g_print("%s\n", str);
                        return 0;
                  }
            }
            /* ④ 境界図形が 楕円弧または楕円 */
            else if (a->TraceData[2].code == 16) {
                  if (TrimL_E(*a, &PointX, &PointY) == 0) {
                        strcpy(str, "Split-13 : error : ");
                        strcat(str, _("There is not a point of intersection."));
                        g_print("%s\n", str);
                        return 0;
                  }
            }


            /* -------------------------------------------------
             * チェック
             */
            if (
                        sg(PointX, compa_digits) == sg(a->TraceData[1].sx, compa_digits) 
                        && 
                        sg(PointY, compa_digits) == sg(a->TraceData[1].sy, compa_digits)
                  ) 
            {
                  strcpy(str, "Split : error : ");
                  strcat(str, _("The division point is the same as the start point."));
                  strcat(str, " (LINE)");
                  g_print("%s\n", str);
                  return 0;
            }
            else if (
                              sg(PointX, compa_digits) == sg(a->TraceData[1].ex, compa_digits) 
                              && 
                              sg(PointY, compa_digits) == sg(a->TraceData[1].ey, compa_digits)
                        ) 
            {
                  strcpy(str, "Split : error : ");
                  strcat(str, _("The division point is the same as the end point."));
                  strcat(str, " (LINE)");
                  g_print("%s\n", str);
                  return 0;

            }


            /* -------------------------------------------------
             * 線分割実行
             * 交点 ( PointX , PointY )
             */
            /* 分割してできた新しいデータ*/
            a->TraceData[3].code = 1;
            a->TraceData[3].layer = a->TraceData[1].layer;
            a->TraceData[3].style = a->TraceData[1].style;
            a->TraceData[3].color = a->TraceData[1].color;
            a->TraceData[3].sx = sg(PointX, calcu_digits);
            a->TraceData[3].sy = sg(PointY, calcu_digits);
            a->TraceData[3].ex = a->TraceData[1].ex;
            a->TraceData[3].ey = a->TraceData[1].ey;

            /* 元のデータ */
            a->TraceData[1].ex = sg(PointX, calcu_digits);
            a->TraceData[1].ey = sg(PointY, calcu_digits);
            return 1;
      }





      /* -----------------------------------------------------
       * 2 : 分割する図形が円弧
       */
      else if (a->TraceData[1].code == 2) {
            /* ① 境界図形が 点 */
            if (a->TraceData[2].code == 0 ) {
                  if (TrimC_Point(*a, &PointX, &PointY, 2) == 0) {
                        strcpy(str, "Split-20 : error : ");
                        strcat(str, _("There is not a point of intersection."));
                        g_print("%s\n", str);
                        return 0;
                  }
            }
            /* ② 境界図形が 線 */
            else if (a->TraceData[2].code == 1 ) {
                  if (TrimC_Line(*a, &PointX, &PointY, 2) == 0) {
                        strcpy(str, "Split-21 : error : ");
                        strcat(str, _("There is not a point of intersection."));
                        g_print("%s\n", str);
                        return 0;
                  }
            }
            /* ③ 境界図形が 円弧または円 */
            else if (a->TraceData[2].code == 2 || a->TraceData[2].code == 4) {
                  if (TrimC_AC(*a, &PointX, &PointY, 2) == 0) {
                        strcpy(str, "Split-22 : error : ");
                        strcat(str, _("There is not a point of intersection."));
                        g_print("%s\n", str);
                        return 0;
                  }
            }
            /* ④ 境界図形が 楕円弧または楕円 */
            else if (a->TraceData[2].code == 16) {
                  if (TrimC_Ellipse(*a, &PointX, &PointY, 2) == 0) {
                        strcpy(str, "Split-23 : error : ");
                        strcat(str, _("There is not a point of intersection."));
                        g_print("%s\n", str);
                        return 0;
                  }
            }


            /* -------------------------------------------------
             * チェック
             */
            if (
                        sg(PointX, compa_digits) == sg(a->TraceData[1].sx, compa_digits) 
                        && 
                        sg(PointY, compa_digits) == sg(a->TraceData[1].sy, compa_digits)
                  )
            {
                  strcpy(str, "Split : error : ");
                  strcat(str, _("The division point is the same as the start point."));
                  strcat(str, " (LINE)");
                  g_print("%s\n", str);
                  return 0;
            }

            else if (
                              sg(PointX, compa_digits) == sg(a->TraceData[1].ex, compa_digits) 
                              && 
                              sg(PointY, compa_digits) == sg(a->TraceData[1].ey, compa_digits)
                        )
            {
                  strcpy(str, "Split : error : ");
                  strcat(str, _("The division point is the same as the end point."));
                  strcat(str, " (LINE)");
                  g_print("%s\n", str);
                  return 0;
            }


            /* -------------------------------------------------
             * 円弧分割実行
             * 交点 ( PointX , PointY )
             */
            /* 円弧の SA & EA を求める */
            SA = Arc_SE_Angle(a->TraceData[1], 0);
            EA = Arc_SE_Angle(a->TraceData[1], 1);

            /* 中心から交点までの角度 PA を求める。 */
            LAH.sx[1] = a->TraceData[1].cx;
            LAH.sy[1] = a->TraceData[1].cy;
            LAH.ex[1] = PointX;
            LAH.ey[1] = PointY;
            la(&LAH);
            PA = sg(LAH.angle, calcu_digits);

            /* 円弧の延長 -------------------------------------- */
            if (((SA < EA) && (PA < SA || PA > EA)) || ((SA > EA) && (PA < SA && PA > EA))) {
                  return 0; /* Beep; */
            }

            /* 円弧の分割 -------------------------------------- */
            /* 交点(PointX,PointY) */
            /* 分割してできた新しいデータ*/
            a->TraceData[3].code = 2;
            a->TraceData[3].layer = a->TraceData[1].layer;
            a->TraceData[3].style = a->TraceData[1].style;
            a->TraceData[3].color = a->TraceData[1].color;
            a->TraceData[3].cx = a->TraceData[1].cx;
            a->TraceData[3].cy = a->TraceData[1].cy;
            a->TraceData[3].r = a->TraceData[1].r;
            a->TraceData[3].sx = sg(PointX, calcu_digits);
            a->TraceData[3].sy = sg(PointY, calcu_digits);
            a->TraceData[3].ex = a->TraceData[1].ex;
            a->TraceData[3].ey = a->TraceData[1].ey;
            /* 元のデータ*/
            a->TraceData[1].ex = sg(PointX, calcu_digits);
            a->TraceData[1].ey = sg(PointY, calcu_digits);
            return 1;
      }





//#ifdef TEST
      /* -----------------------------------------------------
       * 3 : 分割する図形が楕円弧
       */
      else if (a->TraceData[1].code == 16 && a->ellipse[1].code == 1) {
            /* ① 境界図形が 点 */
            if (a->TraceData[2].code == 0 ) {
                  if (TrimE_Point(*a, &PointX, &PointY, 2) == 0) {
                        strcpy(str, "Split-30 : error : ");
                        strcat(str, _("There is not a point of intersection."));
                        g_print("%s\n", str);
                        return 0;
                  }
            }
            /* ② 境界図形が 線 */
            else if (a->TraceData[2].code == 1 ) {
                  if (TrimE_Line(*a, &PointX, &PointY, 2) == 0) {
                        strcpy(str, "Split-31 : error : ");
                        strcat(str, _("There is not a point of intersection."));
                        g_print("%s\n", str);
                        return 0;
                  }
            }
            /* ③ 境界図形が 円弧または円 */
            else if (a->TraceData[2].code == 2 || a->TraceData[2].code == 4) {
                  if (TrimE_AC(*a, &PointX, &PointY, 2) == 0) {
                        strcpy(str, "Split-32 : error : ");
                        strcat(str, _("There is not a point of intersection."));
                        g_print("%s\n", str);
                        return 0;
                  }
            }
            /* ④ 境界図形が 楕円弧または楕円 */
            else if (a->TraceData[2].code == 16) {
                  if (TrimE_Ellipse(*a, &PointX, &PointY, 2) == 0) {
                        strcpy(str, "Split-33 : error : ");
                        strcat(str, _("There is not a point of intersection."));
                        g_print("%s\n", str);
                        return 0;
                  }
            }


            /* -------------------------------------------------
             * チェック
             */
            /* 分割点が始点と同じ */
            get_ellipse_point_from_angle (a->ellipse[1], a->ellipse[1].sa, &point);
            if (
                        (
                              PointX + (1/pow(10, compa_digits)) > point.x
                              &&
                              PointX - (1/pow(10, compa_digits)) < point.x
                        )
                        && 
                        (
                              PointY + (1/pow(10, compa_digits)) > point.y
                              &&
                              PointY - (1/pow(10, compa_digits)) < point.y
                        )
                  )
            {
                  sprintf(str, "Split() : error : ");
                  strcat(str, _("The division point is the same as the start point.") );
                  strcat(str, " (ELLIPSE)");
                  g_print("%s\n", str);
                  return 0;
            }
            
            /* 分割点が終点と同じ */
            get_ellipse_point_from_angle (a->ellipse[1], a->ellipse[1].ea, &point);
            if (
                        (
                              PointX + (1/pow(10, compa_digits)) > point.x
                              &&
                              PointX - (1/pow(10, compa_digits)) < point.x
                        )
                        && 
                        (
                              PointY + (1/pow(10, compa_digits)) > point.y
                              &&
                              PointY - (1/pow(10, compa_digits)) < point.y
                        )
                  )
            {
                  sprintf(str, "Split() : error : ");
                  strcat(str, _("The division point is the same as the end point.") );
                  strcat(str, " (ELLIPSE)");
                  g_print("%s\n", str);
                  return 0;
            }


            /* -------------------------------------------------
             * 円弧分割実行
             * 交点 ( PointX , PointY )
             */
            /* 円弧の SA & EA を求める */
            SA = a->ellipse[1].sa;
            EA = a->ellipse[1].ea;

            /* 中心から交点までの角度 PA を求める。 */
            point.x = PointX;
            point.y = PointY;
            PA = get_ellipse_angle_from_point (a->ellipse[1], point);

            /* 円弧の延長 -------------------------------------- */
            if (((SA < EA) && (PA < SA || PA > EA)) || ((SA > EA) && (PA < SA && PA > EA))) {
                  return 0; /* Beep; */
            }


            g_print ("split() : SA = %f   EA = %f   PA = %f\n", SA, EA, PA);


            /* 円弧の分割 -------------------------------------- */
            /* 交点(PointX,PointY) */
            /* 分割してできた新しいデータ*/
            a->TraceData[3].code = 16;
            a->ellipse[3].code = 1;
            a->ellipse[3].layer = a->ellipse[1].layer;
            a->ellipse[3].style = a->ellipse[1].style;
            a->ellipse[3].color = a->ellipse[1].color;

            a->ellipse[3].cx = a->ellipse[1].cx;
            a->ellipse[3].cy = a->ellipse[1].cy;
            a->ellipse[3].k = a->ellipse[1].k;
            a->ellipse[3].dx = a->ellipse[1].dx;
            a->ellipse[3].dy = a->ellipse[1].dy;
            a->ellipse[3].sa = PA;
            a->ellipse[3].ea = a->ellipse[1].ea;
            /* 元のデータ*/
            a->ellipse[1].ea = PA;

            return 1;
      }
//#endif



      return 0;
}





/* -------------------------------------------------------------------
 * フィレット
 * Fillet
 * struct TrimDat *           double R
 * int        a->TraceData[3] : Fillet図形
 *            ERR : 0    OK : 1
 */
int Fillet(struct TrimDat *a, double R)
{
//#define FIRET_TEST
//char dumystr[256];


      CAD DumyCad;
      double DumyDbl1, DumyDbl2, CrossPointX = 0, CrossPointY = 0;
      double DumySX = 0, DumySY = 0, DumyEX = 0, DumyEY = 0, DumySX2 = 0, DumySY2 = 0, DumyEX2 = 0, DumyEY2 = 0;
      double FilletCX = 0, FilletCY = 0, DumyCX[3], DumyCY[3], L1, L2;
      int FilletType = 0, Int1 = 0, Int2 = 0;
      struct RtnDat DumyRTN;
      struct TrimDat DumyTrim;
      char str[256];


      /* -----------------------------------------------------
       * 図形要素を判定
       * 
       */
      if (a->TraceData[1].code == 1 ) {
            /* <線と線> (FilletType = 1) */
            if (a->TraceData[2].code == 1 ) {
                  FilletType = 1;
            }
            /* <線と円> (FilletType = 2) */
            else if (a->TraceData[2].code == 2 || a->TraceData[2].code == 4 ) {
                  FilletType = 2;
            }
      }
      else if (a->TraceData[1].code == 2 || a->TraceData[1].code == 4 ) {
            /* <円と線> (FilletType = 2) */
            if (a->TraceData[2].code == 1 ) {
                  /* データ1 と データ2 を入れかえる */
                  DumyCad = a->TraceData[1];
                  DumyDbl1 = a->PicX[1];
                  DumyDbl2 = a->PicY[1];
                  a->TraceData[1] = a->TraceData[2];
                  a->PicX[1] = a->PicX[2];
                  a->PicY[1] = a->PicY[2];
                  a->TraceData[2] = DumyCad;
                  a->PicX[2] = DumyDbl1;
                  a->PicY[2] = DumyDbl2;
                  FilletType = 2;
            }
            /* <円と円>  (FilletType = 3)*/
            else if (a->TraceData[2].code == 2 || a->TraceData[2].code == 4 ) {
                  FilletType = 3;
            }
      }



      /* -----------------------------------------------------
       * 交点を求める(トリム時のため)
       * 
       */
      if (FilletType == 1 ) {
            DumyRTN.sx[1] = a->TraceData[1].sx;
            DumyRTN.sy[1] = a->TraceData[1].sy;
            DumyRTN.ex[1] = a->TraceData[1].ex;
            DumyRTN.ey[1] = a->TraceData[1].ey;
            DumyRTN.sx[2] = a->TraceData[2].sx;
            DumyRTN.sy[2] = a->TraceData[2].sy;
            DumyRTN.ex[2] = a->TraceData[2].ex;
            DumyRTN.ey[2] = a->TraceData[2].ey;
            llp(&DumyRTN);

            /* 交点 */
            CrossPointX = DumyRTN.sx[3];
            CrossPointY = DumyRTN.sy[3];
      }

      else if (FilletType == 2 ) {
            DumyRTN.sx[1] = a->TraceData[1].sx;
            DumyRTN.sy[1] = a->TraceData[1].sy;
            DumyRTN.ex[1] = a->TraceData[1].ex;
            DumyRTN.ey[1] = a->TraceData[1].ey;
            DumyRTN.cx[1] = a->TraceData[2].cx;
            DumyRTN.cy[1] = a->TraceData[2].cy;
            DumyRTN.r[1] = a->TraceData[2].r;
            DumyRTN.sx[4] = a->PicX[1];
            DumyRTN.sy[4] = a->PicY[1];
            DumyRTN.ex[4] = a->PicX[2];
            DumyRTN.ey[4] = a->PicY[2];
            LCP1(&DumyRTN);

            if (DumyRTN.type == 1) {
                  CrossPointX = DumyRTN.sx[2];
                  CrossPointY = DumyRTN.sy[2];
            }
            else if (DumyRTN.type == 0) {
                  DumyRTN.sx[1] = a->TraceData[1].sx;
                  DumyRTN.sy[1] = a->TraceData[1].sy;
                  DumyRTN.ex[1] = a->TraceData[1].ex;
                  DumyRTN.ey[1] = a->TraceData[1].ey;
                  DumyRTN.sx[2] = a->TraceData[2].cx;
                  DumyRTN.sy[2] = a->TraceData[2].cy;
                  plp(&DumyRTN);
                  
                  /* 交点 */
                  CrossPointX = DumyRTN.ex[2];
                  CrossPointY = DumyRTN.ey[2];
            }
      }

      else if (FilletType == 3) {
            DumyRTN.cx[1] = a->TraceData[1].cx;
            DumyRTN.cy[1] = a->TraceData[1].cy;
            DumyRTN.r[1] = a->TraceData[1].r;
            DumyRTN.cx[2] = a->TraceData[2].cx;
            DumyRTN.cy[2] = a->TraceData[2].cy;
            DumyRTN.r[2] = a->TraceData[2].r;
            DumyRTN.sx[1] = a->PicX[1];
            DumyRTN.sy[1] = a->PicY[1];
            DumyRTN.sx[2] = a->PicX[2];
            DumyRTN.sy[2] = a->PicY[2];
            CCP1(&DumyRTN);

            if (DumyRTN.type == 1) {
                  /* 交点 */
                  CrossPointX = DumyRTN.sx[1];
                  CrossPointY = DumyRTN.sy[1];
            }
            else if (DumyRTN.type == 0) {
                  /*    */
                  DumyRTN.sx[1] = a->TraceData[1].cx;
                  DumyRTN.sy[1] = a->TraceData[1].cy;
                  DumyRTN.ex[1] = a->TraceData[2].cx;
                  DumyRTN.ey[1] = a->TraceData[2].cy;
                  pp(&DumyRTN);
                  DumyDbl1 = DumyRTN.l;
                  /*    */
                  DumyRTN.sx[1] = a->TraceData[1].cx;
                  DumyRTN.sy[1] = a->TraceData[1].cy;
                  DumyRTN.ex[1] = a->TraceData[2].cx;
                  DumyRTN.ey[1] = a->TraceData[2].cy;
                  la(&DumyRTN);
                  DumyDbl2 = DumyRTN.angle;
                  /*    */
                  DumyDbl1 = a->TraceData[1].r + (DumyDbl1 - a->TraceData[1].r - a->TraceData[2].r) / 2;
                  /*    */
                  DumyRTN.sx[1] = a->TraceData[1].cx;
                  DumyRTN.sy[1] = a->TraceData[1].cy;
                  DumyRTN.angle = DumyDbl2;
                  DumyRTN.l = DumyDbl1;
                  pap(&DumyRTN);

                  /* 交点 */
                  CrossPointX = DumyRTN.ex[1];
                  CrossPointY = DumyRTN.ey[1];
            }
      }



      /* -----------------------------------------------------
       * フィレット中心を求める
       * 
       */
      /* <線と線> (FilletType = 1) */
      if (FilletType == 1) {
            /* 線1 に対して対するピック点2 はどっち側か? */
            /* 点が直線の進行方向の右にあるか左にあるか
             * ChkPointLineSide
             * (a->sx[1], a->sy[1]) - (a->ex[1], a->ey[1]),,(a->sx[2], a->sy[2])
             *    a->type = 0:ERR 1:右     2:左     3:線上
             */
            DumyRTN.sx[1] = a->TraceData[1].sx;
            DumyRTN.sy[1] = a->TraceData[1].sy;
            DumyRTN.ex[1] = a->TraceData[1].ex;
            DumyRTN.ey[1] = a->TraceData[1].ey;
            DumyRTN.sx[2] = a->PicX[2];
            DumyRTN.sy[2] = a->PicY[2];
            ChkPointLineSide(&DumyRTN);
            Int1 = DumyRTN.type;
            
            /* 線2 に対して対するピック点1 はどっち側か? */
            DumyRTN.sx[1] = a->TraceData[2].sx;
            DumyRTN.sy[1] = a->TraceData[2].sy;
            DumyRTN.ex[1] = a->TraceData[2].ex;
            DumyRTN.ey[1] = a->TraceData[2].ey;
            DumyRTN.sx[2] = a->PicX[1];
            DumyRTN.sy[2] = a->PicY[1];
            ChkPointLineSide(&DumyRTN);
            Int2 = DumyRTN.type;

#ifdef FIRET_TEST /* --------------------------------------------------- */
            if(Int1==1) sprintf(dumystr,"線1に対して対するピック点2は、右");
            else if(Int1==2)  sprintf(dumystr,"線1に対して対するピック点2は、左");
            else if(Int1==3)  sprintf(dumystr,"線1に対して対するピック点2は、線上");
            else if(Int1==0)  sprintf(dumystr,"線1に対して対するピック点2は、err");
            MsgBox("FIRET TEST Test!", dumystr);
            if(Int2==1) sprintf(dumystr,"線2に対して対するピック点1は、右");
            else if(Int2==2)  sprintf(dumystr,"線2に対して対するピック点1は、左");
            else if(Int2==3)  sprintf(dumystr,"線2に対して対するピック点1は、線上");
            else if(Int2==0)  sprintf(dumystr,"線2に対して対するピック点1は、err");
            MsgBox("FIRET TEST Test!", dumystr);
            sprintf(dumystr,"ピック点1 (%f,%f)    ピック点2 (%f,%f)", 
                                    a->PicX[1], a->PicY[1], a->PicX[2], a->PicY[2]);
            MsgBox("FIRET TEST Test!", dumystr);
#endif /* -------------------------------------------------------------- */


            /* 線1をピック点2の方にオフセット */
            /* ------------------------------------------------ */
            /* LO 始点と終点を与えた直線のオフセット */
            /* ------------------------------------------------ */
            DumyRTN.sx[1] = a->TraceData[1].sx;
            DumyRTN.sy[1] = a->TraceData[1].sy;
            DumyRTN.ex[1] = a->TraceData[1].ex;
            DumyRTN.ey[1] = a->TraceData[1].ey;
            DumyRTN.l = R;
            lo(&DumyRTN);
            /* 右 */
            if (Int1 == 1) {
                  DumySX = DumyRTN.sx[3];
                  DumySY = DumyRTN.sy[3];
                  DumyEX = DumyRTN.ex[3];
                  DumyEY = DumyRTN.ey[3];
            }
            /* 左 */
            else if (Int1 == 2) {
                  DumySX = DumyRTN.sx[2];
                  DumySY = DumyRTN.sy[2];
                  DumyEX = DumyRTN.ex[2];
                  DumyEY = DumyRTN.ey[2];
            }
            
            /* 線2をピック点1の方にオフセット */
            DumyRTN.sx[1] = a->TraceData[2].sx;
            DumyRTN.sy[1] = a->TraceData[2].sy;
            DumyRTN.ex[1] = a->TraceData[2].ex;
            DumyRTN.ey[1] = a->TraceData[2].ey;
            DumyRTN.l = R;
            lo(&DumyRTN);
            /* 右 */
            if (Int2 == 1) {
                  DumySX2 = DumyRTN.sx[3];
                  DumySY2 = DumyRTN.sy[3];
                  DumyEX2 = DumyRTN.ex[3];
                  DumyEY2 = DumyRTN.ey[3];
            }
            /* 左 */
            else if (Int2 == 2) {
                  DumySX2 = DumyRTN.sx[2];
                  DumySY2 = DumyRTN.sy[2];
                  DumyEX2 = DumyRTN.ex[2];
                  DumyEY2 = DumyRTN.ey[2];
            }


            /* 線1をピック点2の方にオフセットした線と */
            /* 線2をピック点1の方にオフセットした線の交点 */
            /* ------------------------------------------------ */
            /* LLP      2直線の交点  初めてのグラフィックス P120 */
            /* ------------------------------------------------ */
            DumyRTN.sx[1] = DumySX;
            DumyRTN.sy[1] = DumySY;
            DumyRTN.ex[1] = DumyEX;
            DumyRTN.ey[1] = DumyEY;
            DumyRTN.sx[2] = DumySX2;
            DumyRTN.sy[2] = DumySY2;
            DumyRTN.ex[2] = DumyEX2;
            DumyRTN.ey[2] = DumyEY2;
            llp(&DumyRTN);

            if (DumyRTN.type == 0) {
                  strcpy(str, "Fillet : error : ");
                  strcat(str, _("There is not a point of intersection."));
                  strcat(str, _(" (Two lines is Parallel)"));
                  g_print("%s\n", str);
                  return 0;
            }

            /* フィレット中心      DumyRTN.SX[3]     DumyRTN.SY[3] */
            FilletCX = DumyRTN.sx[3];
            FilletCY = DumyRTN.sy[3];
            
      }





      /* <線と円> (FilletType = 2) */
      else if (FilletType == 2) {
            /* 線1に対して対するピック点2はどっち側か? */
            /* 点が直線の進行方向の右にあるか左にあるか
             * ChkPointLineSide
             * (a->sx[1], a->sy[1]) - (a->ex[1], a->ey[1]),,(a->sx[2], a->sy[2])
             *    a->type = 0:ERR 1:右     2:左     3:線上
             */
            DumyRTN.sx[1] = a->TraceData[1].sx;
            DumyRTN.sy[1] = a->TraceData[1].sy;
            DumyRTN.ex[1] = a->TraceData[1].ex;
            DumyRTN.ey[1] = a->TraceData[1].ey;
            DumyRTN.sx[2] = a->PicX[2];
            DumyRTN.sy[2] = a->PicY[2];
            ChkPointLineSide(&DumyRTN);
            Int1 = DumyRTN.type;
            
            /* 円2に対して対するピック点1はどっち側か? */
            /* 点が円の中にあるか外にあるか
             * ChkPointCircleSide
             * (a->sx[1] , a->sy[1])      (a->cx[1] , a->cy[1]) , a->r[1]
             *    a->type = 0:ERR   1:中   2:外   3:線上
             */
            DumyRTN.cx[1] = a->TraceData[2].cx;
            DumyRTN.cy[1] = a->TraceData[2].cy;
            DumyRTN.r[1] = a->TraceData[2].r;
            DumyRTN.sx[1] = a->PicX[1];
            DumyRTN.sy[1] = a->PicY[1];
            ChkPointCircleSide(&DumyRTN);
            Int2 = DumyRTN.type;


#ifdef FIRET_TEST /* --------------------------------------------------- */
            if(Int1==1) sprintf(dumystr,"線1に対して対するピック点2は、右");
            else if(Int1==2)  sprintf(dumystr,"線1に対して対するピック点2は、左");
            else if(Int1==3)  sprintf(dumystr,"線1に対して対するピック点2は、線上");
            else if(Int1==0)  sprintf(dumystr,"線1に対して対するピック点2は、err");
            MsgBox("FIRET TEST Test!", dumystr);
            if(Int2==1) sprintf(dumystr,"円2に対して対するピック点1は、中");
            else if(Int2==2)  sprintf(dumystr,"円2に対して対するピック点1は、外");
            else if(Int2==3)  sprintf(dumystr,"円2に対して対するピック点1は、線上");
            else if(Int2==0)  sprintf(dumystr,"円2に対して対するピック点1は、err");
            MsgBox("FIRET TEST Test!", dumystr);
            sprintf(dumystr,"ピック点1 (%f,%f)    ピック点2 (%f,%f)", 
                                    a->PicX[1], a->PicY[1], a->PicX[2], a->PicY[2]);
            MsgBox("FIRET TEST Test!", dumystr);
#endif /* -------------------------------------------------------------- */


            DumyRTN.sx[1] = a->TraceData[1].sx;
            DumyRTN.sy[1] = a->TraceData[1].sy;
            DumyRTN.ex[1] = a->TraceData[1].ex;
            DumyRTN.ey[1] = a->TraceData[1].ey;
            DumyRTN.l = R;
            lo(&DumyRTN);
            /* 右 */
            if (Int1 == 1) {
                  DumyRTN.sx[1] = DumyRTN.sx[3];
                  DumyRTN.sy[1] = DumyRTN.sy[3];
                  DumyRTN.ex[1] = DumyRTN.ex[3];
                  DumyRTN.ey[1] = DumyRTN.ey[3];
            }
            /* 左 */
            else if (Int1 == 2) {
                  DumyRTN.sx[1] = DumyRTN.sx[2];
                  DumyRTN.sy[1] = DumyRTN.sy[2];
                  DumyRTN.ex[1] = DumyRTN.ex[2];
                  DumyRTN.ey[1] = DumyRTN.ey[2];
            }


            /* 中 */
            if (Int2 == 1) {
                  DumyRTN.cx[1] = a->TraceData[2].cx;
                  DumyRTN.cy[1] = a->TraceData[2].cy;
                  DumyRTN.r[1] = a->TraceData[2].r - R;
            }
            /* 外 */
            else if (Int2 == 2) {
                  DumyRTN.cx[1] = a->TraceData[2].cx;
                  DumyRTN.cy[1] = a->TraceData[2].cy;
                  DumyRTN.r[1] = a->TraceData[2].r + R;
#ifdef FIRET_TEST /* --------------------------------------------------- */
//          CircleDraw(hDrawArea, DumyRTN.cx[1], DumyRTN.cy[1], DumyRTN.r[1], 1, 0x00ffffff);
#endif // --------------------------------------------------------------
            }
            /* 直線と円の交点  初めてのグラフィックス P126 */
            lcp(&DumyRTN);

            if (DumyRTN.type == 0) {
                  strcpy(str, "Fillet : error : ");
                  strcat(str, _("There is not a point of intersection."));
                  strcat(str, _(" (Radius is small)"));
                  g_print("%s\n", str);
                  return 0;
            }

            /* 交点1  ( DumyRTN.SX[2] , DumyRTN.SX[2] ) */
            /* 交点2  ( DumyRTN.SX[3] , DumyRTN.SX[3] ) */
            DumyCX[1] = DumyRTN.sx[2];
            DumyCY[1] = DumyRTN.sy[2];
            DumyCX[2] = DumyRTN.sx[3];
            DumyCY[2] = DumyRTN.sy[3];
      }





      /* <円と円> (FilletType = 3) */
      else if (FilletType == 3) {
            /* 円1に対して対するピック点2はどっち側か? */
            DumyRTN.cx[1] = a->TraceData[1].cx;
            DumyRTN.cy[1] = a->TraceData[1].cy;
            DumyRTN.r[1] = a->TraceData[1].r;
            DumyRTN.sx[1] = a->PicX[2];
            DumyRTN.sy[1] = a->PicY[2];
            ChkPointCircleSide(&DumyRTN);
            Int1 = DumyRTN.type;

            /* 円2に対して対するピック点1はどっち側か? */
            DumyRTN.cx[1] = a->TraceData[2].cx;
            DumyRTN.cy[1] = a->TraceData[2].cy;
            DumyRTN.r[1] = a->TraceData[2].r;
            DumyRTN.sx[1] = a->PicX[1];
            DumyRTN.sy[1] = a->PicY[1];
            ChkPointCircleSide(&DumyRTN);
            Int2 = DumyRTN.type;
            
            /* CCP      2円の交点 */
            /* 中 */
            if (Int1 == 1)    {
                  DumyRTN.cx[1] = a->TraceData[1].cx;
                  DumyRTN.cy[1] = a->TraceData[1].cy;
                  DumyRTN.r[1] = a->TraceData[1].r - R;
            }
            /* 外 */
            else if (Int1 == 2) {
                  DumyRTN.cx[1] = a->TraceData[1].cx;
                  DumyRTN.cy[1] = a->TraceData[1].cy;
                  DumyRTN.r[1] = a->TraceData[1].r + R;
            }


            /* 中 */
            if (Int2 == 1) {
                  DumyRTN.cx[2] = a->TraceData[2].cx;
                  DumyRTN.cy[2] = a->TraceData[2].cy;
                  DumyRTN.r[2] = a->TraceData[2].r - R;
            }
            /* 外 */
            else if (Int2 == 2) {
                  DumyRTN.cx[2] = a->TraceData[2].cx;
                  DumyRTN.cy[2] = a->TraceData[2].cy;
                  DumyRTN.r[2] = a->TraceData[2].r + R;
            }
            
            /* 2円の交点 */
            ccp(&DumyRTN);

            if (DumyRTN.type == 0) {
                  strcpy(str, "Fillet : error : ");
                  strcat(str, _("There is not a point of intersection."));
                  strcat(str, _(" (Radius is small)"));
                  g_print("%s\n", str);
                  return 0;
            }
            
            /* 交点1  ( DumyRTN.SX[1] , DumyRTN.SX[1] ) */
            /* 交点2  ( DumyRTN.SX[2] , DumyRTN.SX[2] ) */
            DumyCX[1] = DumyRTN.sx[1];
            DumyCY[1] = DumyRTN.sy[1];
            DumyCX[2] = DumyRTN.sx[2];
            DumyCY[2] = DumyRTN.sy[2];
      }





      /* ----------------------------------------------------- */
      /* フィレット円の中心がピック点に近い方をとる。--------- */
      /* 近いほうではなくて [中心からピック点の角度]      */
      /* と [中心から交点の角度] */
      /* で判別したらよいのでは? */
      /*    */
      /*    */
      /*    */
      if (FilletType == 2 || FilletType == 3)
      {
            /* ------------------------------------------------ */
            /* PP 2点間の距離 */
            /* ------------------------------------------------ */
            /* L1 */
            DumyRTN.sx[1] = DumyCX[1];
            DumyRTN.sy[1] = DumyCY[1];
            DumyRTN.ex[1] = a->PicX[1];
            DumyRTN.ey[1] = a->PicY[1];
            pp(&DumyRTN);
            L1 = DumyRTN.l;

            DumyRTN.sx[1] = DumyCX[1];
            DumyRTN.sy[1] = DumyCY[1];
            DumyRTN.ex[1] = a->PicX[2];
            DumyRTN.ey[1] = a->PicY[2];
            pp(&DumyRTN);
            L1 = L1 + DumyRTN.l;

            /* L2 */
            DumyRTN.sx[1] = DumyCX[2];
            DumyRTN.sy[1] = DumyCY[2];
            DumyRTN.ex[1] = a->PicX[1];
            DumyRTN.ey[1] = a->PicY[1];
            pp(&DumyRTN);
            L2 = DumyRTN.l;

            DumyRTN.sx[1] = DumyCX[2];
            DumyRTN.sy[1] = DumyCY[2];
            DumyRTN.ex[1] = a->PicX[2];
            DumyRTN.ey[1] = a->PicY[2];
            pp(&DumyRTN);
            L2 = L2 + DumyRTN.l;

            if (L1 < L2) {
                  FilletCX = DumyCX[1];
                  FilletCY = DumyCY[1];
            }
            else if (L1 > L2) {
                  FilletCX = DumyCX[2];
                  FilletCY = DumyCY[2];
            }
      }
      /* ----- < フィレット円の中心がピック点に近い方をとる。> ------------------ */





      /* ----------------------------------------------------- */
      /* フィレット円を CAD データにする --------------------- */
      a->TraceData[3].code = 4;
      a->TraceData[3].layer = a->TraceData[1].layer;//NowLayer;
      a->TraceData[3].style = a->TraceData[1].style;//NowStyle;
      a->TraceData[3].color = a->TraceData[1].color;//NowColor;
      
      a->TraceData[3].cx = sg(FilletCX, calcu_digits);
      a->TraceData[3].cy = sg(FilletCY, calcu_digits);
      a->TraceData[3].r = R;


      /* ----------------------------------------------------- */
      /* フィレット円をトリムする ---------------------------- */

      /* トリムのときのピック点を作る */
      /* LA 直線の角度 */
      DumyRTN.sx[1] = a->TraceData[3].cx;
      DumyRTN.sy[1] = a->TraceData[3].cy;
      DumyRTN.ex[1] = CrossPointX;
      DumyRTN.ey[1] = CrossPointY;
      la(&DumyRTN);
      
      /* PAP      始点と角度と距離で直線の終点を求める */
      DumyRTN.l = a->TraceData[3].r;
      pap(&DumyRTN);
      
      CrossPointX = DumyRTN.ex[1];
      CrossPointY = DumyRTN.ey[1];

      /* ----------------------------------------------------- */
      /* トリム図形が円ならトリム実行 ------------------------ */
      DumyTrim.TraceData[1] = a->TraceData[3];
      DumyTrim.PicX[1] = CrossPointX;
      DumyTrim.PicY[1] = CrossPointY;
      
      DumyTrim.TraceData[2] = a->TraceData[1];
      DumyTrim.PicX[2] = a->PicX[1];
      DumyTrim.PicY[2] = a->PicY[1];
      
      DumyTrim.TraceData[3] = a->TraceData[2];
      DumyTrim.PicX[3] = a->PicX[2];
      DumyTrim.PicY[3] = a->PicY[2];
      
      DumyTrim.Index = 2;

      /* < トリム実行 > */
      TrimMain(&DumyTrim);

      a->TraceData[1] = DumyTrim.TraceData[2];
      a->PicX[1] = DumyTrim.PicX[2];
      a->PicY[1] = DumyTrim.PicY[2];
      
      a->TraceData[2] = DumyTrim.TraceData[3];
      a->PicX[2] = DumyTrim.PicX[3];
      a->PicY[2] = DumyTrim.PicY[3];
      
      a->TraceData[3] = DumyTrim.TraceData[1];
      a->PicX[3] = DumyTrim.PicX[1];
      a->PicY[3] = DumyTrim.PicY[1];
      return 1;
}





/* ====================================================================
 * ===  Copyright (C) 1998-2007 Yutaka Sagiya. All rights reserved. ===
 * ====================================================================
 *    Project              : SagCAD
 *    Source               : TrimFunc.c
 * ====================================================================
 */

Generated by  Doxygen 1.6.0   Back to index