polygon.cpp 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. #include "polygon.hpp"
  2. Coefficients Polygon::coefficients;
  3. Polygon::Polygon(string str){
  4. Vertex v(0,0);
  5. indices.insert({v,0});
  6. vertices.push_back(v);
  7. length=0;
  8. size_t i=0;
  9. size_t l=str.size();
  10. if(l==0) return;
  11. char c=str[0];
  12. while(i<l){
  13. char s=c;
  14. int64 xs=0;
  15. int64 ys=0;
  16. switch(s){
  17. case 'l':
  18. xs=-1;
  19. break;
  20. case 'r':
  21. xs=1;
  22. break;
  23. case 'u':
  24. ys=1;
  25. break;
  26. case 'd':
  27. ys=-1;
  28. break;
  29. default:
  30. Error::string_error("Invalid step",str,i);
  31. break;
  32. };
  33. size_t j=++i;
  34. size_t n=0;
  35. if(i<l){
  36. c=str[i];
  37. while(i<l and '0'<=c and c<='9'){
  38. n=n*10+c-'0';
  39. if(++i==l) break;
  40. c=str[i];
  41. }
  42. }
  43. if(i==j) n=1; // No digits after step s
  44. for(size_t k=0;k<n;++k){
  45. v.x+=xs;
  46. v.y+=ys;
  47. ++length;
  48. auto res=indices.insert({v,length});
  49. if(!res.second and (i<l or k<n-1)) Error::string_error("Not self avoiding",str,j-1);
  50. if(res.second) vertices.push_back(v);
  51. }
  52. }
  53. if(v.x!=0 or v.y!=0) Error::error("Not a polygon");
  54. compute_B();
  55. compute_C();
  56. compute_M();
  57. compute_fp();
  58. }
  59. void Polygon::add_vertex(const int32& x,const int32& y){
  60. Vertex w(x,y);
  61. if(indices.find(w)==indices.end()){
  62. indices.insert({w,vertices.size()});
  63. vertices.push_back(w);
  64. }
  65. }
  66. void
  67. Polygon::add_neighbours(const int32& x,const int32& y){
  68. add_vertex(x,y+1);
  69. add_vertex(x,y-1);
  70. add_vertex(x-1,y);
  71. add_vertex(x+1,y);
  72. }
  73. void
  74. Polygon::compute_B(){
  75. for(size_t i=0;i<length;++i){
  76. int32 x=vertices[i].x;
  77. int32 y=vertices[i].y;
  78. add_neighbours(x,y);
  79. }
  80. B.init(vertices.size());
  81. B.clear();
  82. for(size_t i=0;i<length;++i){
  83. Vertex& v=vertices[i];
  84. size_t r=indices[Vertex(v.x+1,v.y)];
  85. size_t l=indices[Vertex(v.x-1,v.y)];
  86. size_t u=indices[Vertex(v.x,v.y+1)];
  87. size_t d=indices[Vertex(v.x,v.y-1)];
  88. B.get(i,r)=1;
  89. B.get(r,i)=1;
  90. B.get(i,l)=1;
  91. B.get(l,i)=1;
  92. B.get(i,u)=1;
  93. B.get(u,i)=1;
  94. B.get(i,d)=1;
  95. B.get(d,i)=1;
  96. }
  97. }
  98. void
  99. Polygon::compute_C(){
  100. C.init(vertices.size());
  101. size_t n=vertices.size();
  102. for(size_t i=0;i<n;++i){
  103. for(size_t j=0;j<n;++j){
  104. Vertex& vi=vertices[i];
  105. Vertex& vj=vertices[j];
  106. double dx=abs(vi.x-vj.x);
  107. double dy=abs(vi.y-vj.y);
  108. C.get(i,j)=coefficients.get(dx,dy);
  109. }
  110. }
  111. }
  112. void
  113. Polygon::compute_M(){
  114. //M=[I+1/4*C*B|1]=[I+1/4*C*tB|1]
  115. size_t n=vertices.size();
  116. M.init(n,n+1);
  117. for(size_t i=0;i<n;++i){
  118. for(size_t j=0;j<n;++j){
  119. Reel c=0;
  120. for(size_t k=0;k<n;++k){
  121. c+=C.get(i,k)*B.get(k,j);
  122. }
  123. M.get(i,j)=c/4;
  124. }
  125. M.get(i,i)+=1;
  126. M.get(i,n)=1;
  127. }
  128. }
  129. void
  130. Polygon::compute_fp(){
  131. size_t n=vertices.size();
  132. Reel det=M.Gauss();
  133. //cout<<"Det = "<<det<<endl;
  134. fp=0;
  135. for(size_t i=0;i<n;++i){
  136. fp+=B.get_diag_square_sym(i)*M.get(i,n);
  137. }
  138. fp*=(det*0.25);
  139. }