如何得到扇型的数据,这其中需要考虑角度在180时,和小于180两种情况。
得到数据可以利用mo的Extent得到矩形覆盖范围,该方位是借助圆心,和半径画出矩形,先得到该矩形区域的值。
该区域中的任意值和半径边,变化边的角度,如果两角度相加等于张角,而且到圆心的距离小等于半径,那么该点在所选区域内。
对于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是弧度 /// 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.");
}
}
/// <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*b - 4*a*c;
if (check>=0)
{
double x1 = (-b - 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 = (-b + 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
}
}
}
/// 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*b - 4*a*c;
if (check>=0)
{
double x1 = (-b - 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 = (-b + 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
}
}
}
浙公网安备 33010602011771号