0
위키피디아 의사 코드에서 그레이엄 스캔을 구현하려고하는데, C#으로 변환하는 데 약간의 문제가 있습니다. 아마 너는보기를 꺼리지 않을 것인가?그레이엄 스캔을 C#으로 구현하기
public class GrahamScan
{
public static List<CoordinatesD> Scan(List<CoordinatesD> coordinateslist)
{
int coordinatesize = coordinateslist.Count;
CoordinatesD[] coordinatesarray = new CoordinatesD[coordinatesize];
for (int i = 0; i < coordinatesize; i++)
{
coordinatesarray[i] = coordinateslist[i];
}
//swap points[1] with the point with the lowest y-coordinate;
int lowestyindex = LowestY(coordinatesarray);
Swap(coordinatesarray[0], coordinatesarray[lowestyindex]);
//sort points by polar angle with points[1];
coordinatesarray = SortByPolarAngle(coordinatesarray[0], coordinateslist);
// We want points[0] to be a sentinel point that will stop the loop.
coordinatesarray[0] = coordinatesarray[coordinatesize];
// M will denote the number of points on the convex hull.
int numpointsonhull = 1;
for (int i = 2; i < coordinatesize; i++)
{
// Find next valid point on convex hull.
while(CCW(coordinatesarray[numpointsonhull-1], coordinatesarray[numpointsonhull], coordinatesarray[i]) <= 0)
{
if(numpointsonhull > 1)
{
numpointsonhull -= 1;
}
// All points are collinear
else if (i == coordinatesize)
{
break;
}
else
{
i += 1;
}
}
// Update M and swap points[i] to the correct place.
numpointsonhull += 1;
//swap(points[M],points[i]);
Swap(coordinatesarray[numpointsonhull], coordinatesarray[i]);
}
List<CoordinatesD> pointsonhulllist = new List<CoordinatesD>();
for (int i = 0; i < numpointsonhull; i++)
{
pointsonhulllist.Add(coordinatesarray[i]);
}
return pointsonhulllist;
}
/// <summary>
/// Swaps two points.
/// </summary>
/// <param name="p1"></param>
/// <param name="p2"></param>
private static void Swap(CoordinatesD p1, CoordinatesD p2)
{
CoordinatesD temp = p1;
p1 = p2;
p2 = temp;
}
/// <summary>
/// Attempts to Sort by Polar Angle, with respect to p1.
/// </summary>
/// <param name="p1"></param>
/// <param name="points"></param>
/// <returns></returns>
private static CoordinatesD[] SortByPolarAngle(CoordinatesD p1, List<CoordinatesD> points)
{
CoordinatesD[] sortedpoints = new CoordinatesD[points.Count];
int sortedpointiterator = 0;
while(true)
{
int current = 0;
for (int i = 0; i < points.Count; i++)
{
if (p1.PolarAngle - points[i].PolarAngle < p1.PolarAngle - points[current].PolarAngle)
{
current = i;
}
}
sortedpoints[sortedpointiterator] = points[current];
sortedpointiterator++;
points.RemoveAt(current);
if (points.Count == 0)
{
break;
}
}
return sortedpoints;
}
/// <summary>
/// Finds the index of the CoordinateD with the lowest Y.
/// </summary>
/// <param name="coords"></param>
/// <returns></returns>
private static int LowestY(CoordinatesD[] coords)
{
int index = 0;
for (int i = 0; i < coords.Length; i++)
{
if(coords[i].Y < coords[index].Y)
{
index = i;
}
}
return index;
}
// Three points are a counter-clockwise turn if ccw > 0, clockwise if
// ccw < 0, and collinear if ccw = 0 because ccw is a determinant that
// gives the signed area of the triangle formed by p1, p2 and p3.
private static double CCW(CoordinatesD p1, CoordinatesD p2, CoordinatesD p3)
{
return (p2.X - p1.X) * (p3.Y - p1.Y) - (p2.Y - p1.Y) * (p3.X - p1.X);
}
}
그리고이 클래스의 사용을 만들고있다 : 여기
내가 가진 무엇 코드는 내가 모두 다스 의사 구현을 읽은 대부분이 있기 때문에, 폭발 좋아public class CoordinatesD : iCoordinates
{
private double latitude = 0.0;
private double longitude = 0.0;
public enum ServiceType { Google = 0, Bing = 1 };
public double Latitude
{
get { return latitude; }
}
public double Longitude
{
get { return longitude; }
}
public double X
{
get { return longitude; }
}
public double Y
{
get { return latitude; }
}
public double PolarAngle { get { return CalculatePolarAngle(); } }
public CoordinatesD(double latitude, double longitude)
{
this.latitude = latitude;
this.longitude = longitude;
}
private double CalculatePolarAngle()
{
double polarangle = Math.Atan(latitude/longitude);
if (polarangle > 0.0)
{
return polarangle;
}
return polarangle + Math.PI;
}
public CoordinatesD Change(double changelat, double changelong)
{
CoordinatesD newCoordinates = new CoordinatesD(this.latitude + changelat, this.longitude + changelong);
return newCoordinates;
}
public string ToJScriptString(ServiceType service)
{
string jscriptstring = string.Empty;
switch (service)
{
case ServiceType.Bing:
jscriptstring = String.Format("new Microsoft.Maps.Location({0},{1})", this.latitude.ToString(), this.longitude.ToString());
break;
case ServiceType.Google:
jscriptstring = String.Format("new google.maps.LatLng({0},{1})", this.latitude.ToString(), this.longitude.ToString());
break;
default:
break;
}
return jscriptstring;
}
}
다른 것, 그리고 너무 적절하게 설명하는 것도 없습니다. 배열에 대한 범위를 벗어난 오류가 발생합니다. 좌표를 지정해야하거나 좌표를 +1하거나 좌표를 -1로 지정하거나 좌표를 지정하지 않습니다. 원래는 'N'또는 'N'입니다. +1 '을 보았지만 알 수 있듯이 나는이 번역에 대한 생각을 서서히 잃어 가고있다.
어디에서 폭발하는지 알려주실 수 있습니까? – doctorlove
[this] (http://my-bsc-thesis.googlecode.com/svn/trunk/KinectFingerDetection/KinectControl.Core/Detection/GrahamScan.cs)을 사용해 보셨습니까? –
현재 '좌표 배열 [0] = 좌표 배열 [좌표];에서 폭발합니다. 범위를 벗어나는 인덱스가있는 행 (배열 외부의 항목에 액세스하고 있기 때문에). 내가 겪고있는 문제의 일부는이 코드를 번역하는 것입니다 : "N = 포인트 수"와 "포인트 수 [N + 1] = 포인트 배열"... 0 기반을 사용한 다음 1 기반 인덱싱. – user978122