Tube.cpp 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. /******************************************************************************/
  2. #include "stdafx.h"
  3. namespace EE{
  4. /******************************************************************************/
  5. Tube& Tube::operator*=( Flt f) {pos*=f; r*=f; h*=f; return T;}
  6. Tube& Tube::operator/=( Flt f) {pos/=f; r/=f; h/=f; return T;}
  7. Tube& Tube::operator*=(C Vec &v)
  8. {
  9. Matrix3 m; m.setUp(up)*=v;
  10. h*= m.y.length();
  11. r*=Avg(m.x.length(), m.z.length());
  12. pos*=v;
  13. return T;
  14. }
  15. Tube& Tube::operator/=(C Vec &v)
  16. {
  17. Matrix3 m; m.setUp(up)/=v;
  18. h*= m.y.length();
  19. r*=Avg(m.x.length(), m.z.length());
  20. pos/=v;
  21. return T;
  22. }
  23. Tube& Tube::operator*=(C Matrix3 &m)
  24. {
  25. pos*=m;
  26. up *=m;
  27. h *=up.normalize();
  28. r *=m .avgScale ();
  29. return T;
  30. }
  31. Tube& Tube::operator*=(C Matrix &m)
  32. {
  33. pos*=m;
  34. up *=m .orn ();
  35. h *=up.normalize();
  36. r *=m .avgScale ();
  37. return T;
  38. }
  39. /******************************************************************************/
  40. void Tube::drawVI(Bool fill, Int resolution)C
  41. {
  42. if(resolution<0)resolution=24;else if(resolution<3)resolution=3;
  43. Matrix3 matrix; matrix.setUp(up);
  44. matrix.x*=r; matrix.y*=h/2;
  45. matrix.z*=r;
  46. Vec prev=pos+matrix.x;
  47. REP(resolution)
  48. {
  49. Flt c, s; CosSin(c, s, (PI2*i)/resolution); Vec next=pos + c*matrix.x + s*matrix.z;
  50. if(fill)VI.quad(next+matrix.y, prev+matrix.y, prev-matrix.y, next-matrix.y);else
  51. {
  52. VI.line(prev-matrix.y, prev+matrix.y);
  53. VI.line(prev+matrix.y, next+matrix.y);
  54. VI.line(prev-matrix.y, next-matrix.y);
  55. }
  56. prev=next;
  57. }
  58. }
  59. void Tube::draw(C Color &color, Bool fill, Int resolution)C
  60. {
  61. VI.color(color); drawVI(fill, resolution);
  62. VI.end ( );
  63. }
  64. /******************************************************************************/
  65. Bool Cuts(C Vec &point, C Tube &tube)
  66. {
  67. Flt dist_y=DistPointPlane(point, tube.pos, tube.up);
  68. if( dist_y>=-tube.h*0.5f
  69. && dist_y<= tube.h*0.5f)return DistPointStr(point, tube.pos, tube.up)<=tube.r;
  70. return false;
  71. }
  72. Bool Cuts(C Edge &edge, C Tube &tube)
  73. {
  74. Flt h_2 =tube.h*0.5f,
  75. dist_y0=DistPointPlane(edge.p[0], tube.pos, tube.up),
  76. dist_y1=DistPointPlane(edge.p[1], tube.pos, tube.up);
  77. Edge temp=edge; if(dist_y0>dist_y1){temp.reverse(); Swap(dist_y0, dist_y1);}
  78. if(dist_y0<= h_2
  79. && dist_y1>=-h_2)
  80. {
  81. if(dist_y0!=dist_y1) // clamp 'temp' to -h_2 .. h_2 range
  82. {
  83. if(dist_y0<-h_2)
  84. {
  85. temp.p[0]=PointOnPlane(temp.p[0], temp.p[1], dist_y0-(-h_2), dist_y1-(-h_2));
  86. dist_y0=-h_2;
  87. }
  88. if(dist_y1>h_2)
  89. {
  90. temp.p[1]=PointOnPlane(temp.p[0], temp.p[1], dist_y0-h_2, dist_y1-h_2);
  91. dist_y1=h_2;
  92. }
  93. }
  94. return Dist(temp, tube.edge())<=tube.r;
  95. }
  96. return false;
  97. }
  98. /******************************************************************************/
  99. Bool SweepPointTube(C Vec &point, C Vec &move, C Tube &tube, Flt *hit_frac, Vec *hit_normal)
  100. {
  101. Vec pos; Plane plane;
  102. Flt h_2=tube.h*0.5f;
  103. plane.pos=tube.pos+h_2*tube.up; plane.normal= tube.up; if(SweepPointPlane(point, move, plane, hit_frac, hit_normal, &pos) && Dist(pos, plane.pos)<=tube.r)return true;
  104. plane.pos=tube.pos-h_2*tube.up; plane.normal=-tube.up; if(SweepPointPlane(point, move, plane, hit_frac, hit_normal, &pos) && Dist(pos, plane.pos)<=tube.r)return true;
  105. Matrix matrix; matrix. setPosDir(tube.pos, tube.up);
  106. Vec2 point2= matrix. convert(point , true);
  107. Vec2 move2 = matrix.orn().convert(move , true);
  108. Vec2 nrm2 ; Flt frac;
  109. if(SweepPointCircle(point2, move2, Circle(tube.r), &frac, &nrm2))
  110. {
  111. Flt y=DistPointPlane(point+move*frac, tube.pos, tube.up);
  112. if(Abs(y)<=h_2)
  113. {
  114. if(hit_frac )*hit_frac =frac;
  115. if(hit_normal)*hit_normal=matrix.orn().convert(nrm2);
  116. return true;
  117. }
  118. }
  119. return false;
  120. }
  121. /******************************************************************************/
  122. }
  123. /******************************************************************************/