pursuedream
成功=水平+业务+沟通+判断
如何得到扇型的数据,这其中需要考虑角度在180时,和小于180两种情况。
得到数据可以利用mo的Extent得到矩形覆盖范围,该方位是借助圆心,和半径画出矩形,先得到该矩形区域的值。
该区域中的任意值和半径边,变化边的角度,如果两角度相加等于张角,而且到圆心的距离小等于半径,那么该点在所选区域内。
对于180的,可以利用斜率来算,因为先前已经保存了半径在哪以象限
       /// <summary>
       
/// get sector region data  for gridbase
       
/// </summary>
       
/// <param name="FeatureList">ractangle region</param>
       
/// <param name="unitExtent">longth</param>
       
/// <returns></returns>
       public SelectedData SetGridBaseSelectedData(ArrayList FeatureList, double unitExtent)
       {
           SelectedData dt 
= new SelectedData();

           ESRI.MapObjects2.Core.Point pt 
= new ESRI.MapObjects2.Core.PointClass();
     
           
double thirdDist = Math.Sqrt(Math.Pow((varietyPoint.X - firstPoint.X),2+ Math.Pow((varietyPoint.Y - firstPoint.Y),2));

           
try
           {

               
for(int i = 0;i<FeatureList.Count;i++)
               {
              .
//get pt

//                   int length = Convert.ToInt32(Math.Sqrt(Math.Pow((pt.X - firstPoint.X),2) + Math.Pow((pt.Y - firstPoint.Y),2)));
                  double lengthDist = Math.Sqrt(Math.Pow((pt.X - firstPoint.X),2+ Math.Pow((pt.Y - firstPoint.Y),2));

                   
if (Convert.ToInt32(lengthDist) <= Convert.ToInt32(this.radius))    // reduce errors
                   {
                       
if (Convert.ToInt32(Math.Abs(sweepAngle)) == 180)
                       {
                           
//two point connection line is y = ax+b.   a= (y1-y2)/(x1-x2) 
                           double a1 = (firstPoint.Y - secondPoint.Y) / (firstPoint.X - secondPoint.X);
                           
double b1 = (firstPoint.Y - a1*firstPoint.X);

                           
double varietyB = 0.0d, movePro =0.0d;

                           
//know the radius direction
                           switch(radiusDirection)
                           {
                               
case 1
                               
case 4:   
                                   
//direction must down. y=ax+b . the line move negative y1. 
                                   
//know a and (x,y) to calculate b according to y=ax+b;
                                   varietyB = pt.Y - a1*pt.X ;
                                   movePro 
= b1 - varietyB;
                                   
if (sweepAngle > 0)    //sweepAngle is 180
                                   {
                                       
if (movePro >= 0)
                                       {
                                           .
                                       }
                                   }
                                   
else       //sweepAngle is -180
                                   {
                                       
if (movePro <= 0)
                                       {
                                           .
                                       }
                            
                                   }
                                   
break;
                               
case 2:
                               
case 3:
                                   varietyB 
= pt.Y - a1*pt.X ;
                                   movePro 
= b1 - varietyB;
                                   
if (sweepAngle > 0)
                                   {
                                       
if (movePro <= 0)
                                       {
                                           .
                                       }
                                   }
                                   
else
                                   {
                                       
if (movePro >= 0)
                                       {
                                           
                                       }

                                   }
                                   
break;
                               
case 5:
                                   varietyB 
= firstPoint.X - pt.X ;
                                   
if (sweepAngle > 0)
                                   {
                                       
if (varietyB <=0)
                                       {
                                          
                                       }
                                   }
                                   
else
                                   {
                                       
if (varietyB >=0)
                                       {
                                           
                                       }

                                   }
                                   
break;
                               
case 6:
                                   varietyB 
= firstPoint.Y - pt.Y;
                                   
if (sweepAngle > 0)
                                   {
                                       
if (varietyB >=0)
                                       {
                                          
                                       }
                                   }
                                   
else
                                   {
                                       
if (varietyB <=0)
                                       {
                                          
                                       }

                                   }
                                   
break;
                               
case 7:
                                   varietyB 
= firstPoint.X - pt.X ;
                                   
if (sweepAngle > 0)
                                   {
                                       
if (varietyB >=0)
                                       {
                                           
                                       }
                                   }
                                   
else
                                   {
                                       
if (varietyB <=0)
                                       {
                                           
                                       }

                                   }

                                   
break;
                               
case 8:
                                   varietyB 
= firstPoint.Y - pt.Y;
                                   
if (sweepAngle > 0)
                                   {
                                       
if (varietyB >=0)
                                       {
                                          
                                       }
                                   }
                                   
else
                                   {
                                       
if (varietyB <=0)
                                       {
                                           
                                       }

                                   }

                                   
break;
                           }
                       }
                       
else     // sweepAngle must be less than 180.If any point and enother three point angle is equal to the angle, it is in the selection region.
                       {
                           
// c*c = a*a + b*b - 2abcosα. 0<angle <180
                          double  anyRadiusDist = Math.Sqrt(Math.Pow((pt.X - secondPoint.X),2)+Math.Pow((pt.Y -secondPoint.Y),2));

                          
double  anyVarietyDist = Math.Sqrt(Math.Pow((pt.X - varietyPoint.X),2)+Math.Pow((pt.Y - varietyPoint.Y),2));

                          
float   angle1 = (float)(180*(Math.Acos((lengthDist*lengthDist + thirdDist*thirdDist -anyVarietyDist * anyVarietyDist) /(2*lengthDist*thirdDist)))/Math.PI);

                          
float   angle2 =(float)(180*(Math.Acos((radius*radius + lengthDist*lengthDist - anyRadiusDist*anyRadiusDist)/(2*radius*lengthDist)))/Math.PI);

                          
float   sumAngle = angle1 + angle2 ;

                           
if (Convert.ToInt32(sumAngle) == Convert.ToInt32(Math.Abs(this.sweepAngle)))
                           {
                               
                           }
                       }
                   }
            
               }
               
return dt;
           }
           
catch
           {
               
throw new Exception("Get gridbase of sector selection data failed.");
           }
       }
对于求扇型中心点可以借助方法dist = 2*r*sinA/(2*A) A是弧度
  
    /// <summary>
        
/// Each side of the mid-point links to form center for sector of isosceles triangle.
        
/// </summary>
        
/// <returns></returns>
        public ESRI.MapObjects2.Core.Point SectorCenter()
        {
            
            
double otherSideDist = 0.0d,sideDist=0.0d,a,b,c,check,n1;
            
double k2 = 0.0d,k1=0.0d;

            
if (Math.Abs(sweepAngle) > 179)
            {
                ESRI.MapObjects2.Core.Point centerP 
= new PointClass();
                otherSideDist 
= (4*this.Radius)/(3*Math.PI);

                
if (radiusDirection == 5)
                {
                    
if (sweepAngle > 0)     // right
                    {
                        centerP.X 
= firstPoint.X + otherSideDist;
                        centerP.Y 
= firstPoint.Y;
                    }
                    
else
                    {
                        centerP.X 
= firstPoint.X - otherSideDist;
                        centerP.Y 
= firstPoint.Y;
                    }
                }
                
else if (radiusDirection == 7)
                {
                    
if (sweepAngle > 0)     // left
                    {
                        centerP.X 
= firstPoint.X - otherSideDist;
                        centerP.Y 
= firstPoint.Y;
                    }
                    
else
                    {
                        centerP.X 
= firstPoint.X + otherSideDist;
                        centerP.Y 
= firstPoint.Y;
                    }
                }
                
else if (radiusDirection == 6)
                {
                    
if (sweepAngle > 0)     // bottom
                    {
                        centerP.X 
= firstPoint.X ;
                        centerP.Y 
= firstPoint.Y - otherSideDist;
                    }
                    
else
                    {
                        centerP.X 
= firstPoint.X ;
                        centerP.Y 
= firstPoint.Y + otherSideDist;
                    }
                }
                
else if(radiusDirection == 8)
                {
                    
if (sweepAngle > 0)     // top
                    {
                        centerP.X 
= firstPoint.X ;
                        centerP.Y 
= firstPoint.Y + otherSideDist;
                    }
                    
else
                    {
                        centerP.X 
= firstPoint.X ;
                        centerP.Y 
= firstPoint.Y - otherSideDist;
                    }
                }
                
else
                {
                    k1 
= (firstPoint.Y - secondPoint.Y) / (firstPoint.X - secondPoint.X);
                    k2 
= (-1)/k1;
             
                    
//(x-x1)*(x-x1)+(k2*x-n1)*(k2*x-n1)- r*r= 0

                    
//(1+k2*k2)x*x-2(x1+k2*n1)*x +n1*n1+x1*x1-r*r=0

                    a 
= Math.Sqrt((otherSideDist*otherSideDist)/(1+k2*k2));

                    
double x1 = a + this.firstPoint.X;

                    
double y1 = firstPoint.Y - k2 * firstPoint.X +x1*k2;

                        
//need know equation according to slope. y=ax+b
                        
//calculte b
                    double varietySlope = y1 - k1*x1;

                    
double centerSlope = firstPoint.Y - k1*x1;

                    
double compare = centerSlope - varietySlope;

                    
if (radiusDirection == 1 || radiusDirection ==4)
                    {
                        
if (sweepAngle >0)
                        {
                            
if (compare < 0)
                            {
                                x1 
= (-a) + this.firstPoint.X;
                                y1 
= firstPoint.Y - k2 * firstPoint.X +x1*k2;
                            }
                        }
                        
else
                        {
                            
if (compare > 0)
                            {
                                x1 
= (-a) + this.firstPoint.X;
                                y1 
= firstPoint.Y - k2 * firstPoint.X +x1*k2;
                            }
                        }
                    }
                    
else if (radiusDirection == 2 || radiusDirection ==3)
                    {
                        
if (sweepAngle > 0)
                        {
                            
if (compare > 0)
                            {
                                x1 
= (-a) + this.firstPoint.X;
                                y1 
= firstPoint.Y - k2 * firstPoint.X +x1*k2;
                            }
                        }
                        
else
                        {
                            
if (compare < 0)
                            {
                                x1 
= (-a) + this.firstPoint.X;
                                y1 
= firstPoint.Y - k2 * firstPoint.X +x1*k2;
                            }
                        }
                    }

                        centerP.X 
= x1;
                        centerP.Y 
= y1;
                 }
                
return centerP;
            }
            
else  // sweepAngle is less than 179
            {

                
//c*c = a*a + b*b - 2abcosα        a= radius/2 ,b= radius
                
//  2*r*sinA/(3*A)  A represents radian.
                otherSideDist = (2*this.radius*Math.Sin(Math.Abs(sweepAngle)*Math.PI/360)*360)/(3*Math.Abs(sweepAngle)*Math.PI);

                sideDist 
= Math.Sqrt(otherSideDist*otherSideDist + this.radius*this.radius - 2* otherSideDist*radius*Math.Cos(Math.Abs(sweepAngle)*Math.PI/360));

                
//y=ax+b
                
//two point connection line is y = ax+b.   a= (y1-y2)/(x1-x2) 
                k1 = (firstPoint.Y - secondPoint.Y) / (firstPoint.X - secondPoint.X);
                
double kv = (firstPoint.Y - varietyPoint.Y) / (firstPoint.X - varietyPoint.X);
                
// k1<k2<kv

                
//tana= |(k2-k1)/1-(k1k2)|  . y=ax+b

                
//  k1+tana/(1+k1*tana)= k2 = (y1-y)/(x1-x) = (firstPoint.Y -y)/(firstPoint.X - x)

                
                
double kn1 = (k1- Math.Tan(Math.Abs(sweepAngle)*Math.PI/360))/(1 + k1*Math.Tan(Math.Abs(sweepAngle)*Math.PI/360));
                
double kn2 = (k1+ Math.Tan(Math.Abs(sweepAngle)*Math.PI/360))/(1 - k1*Math.Tan(Math.Abs(sweepAngle)*Math.PI/360));
                

                
double kvn1 = (kv- Math.Tan(Math.Abs(sweepAngle)*Math.PI/360))/(1 + kv*Math.Tan(Math.Abs(sweepAngle)*Math.PI/360));
                 
                
double kvn2 = (kv+ Math.Tan(Math.Abs(sweepAngle)*Math.PI/360))/(1 - kv*Math.Tan(Math.Abs(sweepAngle)*Math.PI/360));

                
// this center must be in selection region.
                if (kn1.ToString("0.0000").CompareTo(kvn1.ToString("0.0000"))==0)
                {
                    k2 
= kn1;
                }
                
else if (kn1.ToString("0.0000").CompareTo(kvn2.ToString("0.0000"))==0)
                {
                    k2 
= kn1;
                }
                
else if (kn2.ToString("0.0000").CompareTo(kvn1.ToString("0.0000"))==0)
                {
                    k2 
= kn2;
                }
                
else if (kn2.ToString("0.0000").CompareTo(kvn2.ToString("0.0000"))==0)
                {
                    k2 
= kn2;
                }

                
// y = firstPoint.Y -k2 * firstPoint.X + k2*x
                 
                
// (x-x1)*(x-x1)+(y-y1)*(y-y1) = r*r      (x1,y1) = (secondPoint.X,secondPoint.Y)

                n1 
= firstPoint.Y- k2*firstPoint.X - secondPoint.Y ;
                
//(x-x1)*(x-x1)+(k2*x-n1)*(k2*x-n1)- r*r= 0

                
//(1+k2*k2)x*x-2(x1+k2*n1)*x +n1*n1+x1*x1-r*r=0

                a 
= 1+k2*k2;
                b 
= 2*(n1*k2 -secondPoint.X);

                c 
= secondPoint.X * secondPoint.X + n1*n1 -sideDist*sideDist;
 
                check 
= b*- 4*a*c;

                
if (check>=0)
                {
                    
double x1 = (-- Math.Sqrt(check))/(2*a);

                    
double y1 = firstPoint.Y - k2 * firstPoint.X +x1*k2;

                    
int otherLenDist = Convert.ToInt32(Math.Sqrt(Math.Pow((x1-firstPoint.X),2+ Math.Pow((y1-firstPoint.Y),2)));

                    
int lenDist = Convert.ToInt32(Math.Sqrt(Math.Pow((x1-secondPoint.X),2+ Math.Pow((y1-secondPoint.Y),2)));
                
                    ESRI.MapObjects2.Core.Point centerP 
= new PointClass(); 

                    
if ((otherLenDist == Convert.ToInt32(otherSideDist))&& (lenDist == Convert.ToInt32(sideDist)))
                    {
                        centerP.X 
= x1;
                        centerP.Y 
= y1;
                    }
                    
else
                    {
                        x1 
= (-+ Math.Sqrt(check))/(2*a);
                        y1 
= firstPoint.Y - k2 * firstPoint.X +x1*k2;

                        centerP.X 
= x1;
                        centerP.Y 
= y1;
                    }
                    
return centerP;
                }
                
else
                {
                    
return firstPoint; // return center point
                }
            }
             
         }
posted on 2007-08-28 17:59  pursuedream  阅读(231)  评论(0)    收藏  举报