Algorithms.cs
上传用户:sex100000
上传日期:2013-11-09
资源大小:1377k
文件大小:4k
源码类别:

GIS编程

开发平台:

C#

  1. // Copyright 2005, 2006 - Morten Nielsen (www.iter.dk)
  2. //
  3. // This file is part of SharpMap.
  4. // SharpMap is free software; you can redistribute it and/or modify
  5. // it under the terms of the GNU Lesser General Public License as published by
  6. // the Free Software Foundation; either version 2 of the License, or
  7. // (at your option) any later version.
  8. // 
  9. // SharpMap is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. // GNU Lesser General Public License for more details.
  13. // You should have received a copy of the GNU Lesser General Public License
  14. // along with SharpMap; if not, write to the Free Software
  15. // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
  16. using System;
  17. using System.Collections.Generic;
  18. using System.Text;
  19. using SharpMap.Geometries;
  20. namespace SharpMap.Utilities
  21. {
  22. class Algorithms
  23. {
  24. // METHOD IsCCW() IS MODIFIED FROM ANOTHER WORK AND IS ORIGINALLY BASED ON GeoTools.NET:
  25. /*
  26.  *  Copyright (C) 2002 Urban Science Applications, Inc. 
  27.  *
  28.  *  This library is free software; you can redistribute it and/or
  29.  *  modify it under the terms of the GNU Lesser General Public
  30.  *  License as published by the Free Software Foundation; either
  31.  *  version 2.1 of the License, or (at your option) any later version.
  32.  *
  33.  *  This library is distributed in the hope that it will be useful,
  34.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  35.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  36.  *  Lesser General Public License for more details.
  37.  *
  38.  *  You should have received a copy of the GNU Lesser General Public
  39.  *  License along with this library; if not, write to the Free Software
  40.  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  41.  *
  42.  */
  43. /// <summary>
  44. /// Tests whether a ring is oriented counter-clockwise.
  45. /// </summary>
  46. /// <param name="ring">Ring to test.</param>
  47. /// <returns>Returns true if ring is oriented counter-clockwise.</returns>
  48. public static bool IsCCW(LinearRing ring)
  49. {
  50. Point PrevPoint, NextPoint;
  51. Point p;
  52. // Check if the ring has enough vertices to be a ring
  53. if (ring.Vertices.Count < 3) throw(new ArgumentException("Invalid LinearRing"));
  54. // find the point with the largest Y coordinate
  55. Point hip = ring.Vertices[0];
  56. int hii = 0;
  57. for (int i = 1; i < ring.Vertices.Count; i++)
  58. {
  59. p = ring.Vertices[i];
  60. if (p.Y > hip.Y)
  61. {
  62. hip = p;
  63. hii = i;
  64. }
  65. }
  66. // Point left to Hip
  67. int iPrev = hii - 1;
  68. if (iPrev < 0) iPrev = ring.Vertices.Count - 2; 
  69. // Point right to Hip
  70. int iNext = hii + 1;
  71. if (iNext >= ring.Vertices.Count) iNext = 1;
  72. PrevPoint = ring.Vertices[iPrev];
  73. NextPoint = ring.Vertices[iNext];
  74. // translate so that hip is at the origin.
  75. // This will not affect the area calculation, and will avoid
  76. // finite-accuracy errors (i.e very small vectors with very large coordinates)
  77. // This also simplifies the discriminant calculation.
  78. double prev2x = PrevPoint.X - hip.X;
  79. double prev2y = PrevPoint.Y - hip.Y;
  80. double next2x = NextPoint.X - hip.X;
  81. double next2y = NextPoint.Y - hip.Y;
  82. // compute cross-product of vectors hip->next and hip->prev
  83. // (e.g. area of parallelogram they enclose)
  84. double disc = next2x * prev2y - next2y * prev2x;
  85. // If disc is exactly 0, lines are collinear.  There are two possible cases:
  86. // (1) the lines lie along the x axis in opposite directions
  87. // (2) the line lie on top of one another
  88. //  (2) should never happen, so we're going to ignore it!
  89. // (Might want to assert this)
  90. //  (1) is handled by checking if next is left of prev ==> CCW
  91. if (disc == 0.0)
  92. {
  93. // poly is CCW if prev x is right of next x
  94. return (PrevPoint.X > NextPoint.X);
  95. }
  96. else
  97. {
  98. // if area is positive, points are ordered CCW
  99. return (disc > 0.0);
  100. }
  101. }
  102. }