Line.cpp 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. #include "Line.hpp"
  2. #include "Polyline.hpp"
  3. #include <algorithm>
  4. #include <cmath>
  5. #include <sstream>
  6. namespace Slic3r {
  7. std::string
  8. Line::wkt() const
  9. {
  10. std::ostringstream ss;
  11. ss << "LINESTRING(" << this->a.x << " " << this->a.y << ","
  12. << this->b.x << " " << this->b.y << ")";
  13. return ss.str();
  14. }
  15. Line::operator Polyline() const
  16. {
  17. Polyline pl;
  18. pl.points.push_back(this->a);
  19. pl.points.push_back(this->b);
  20. return pl;
  21. }
  22. void
  23. Line::scale(double factor)
  24. {
  25. this->a.scale(factor);
  26. this->b.scale(factor);
  27. }
  28. void
  29. Line::translate(double x, double y)
  30. {
  31. this->a.translate(x, y);
  32. this->b.translate(x, y);
  33. }
  34. void
  35. Line::rotate(double angle, Point* center)
  36. {
  37. this->a.rotate(angle, center);
  38. this->b.rotate(angle, center);
  39. }
  40. void
  41. Line::reverse()
  42. {
  43. std::swap(this->a, this->b);
  44. }
  45. double
  46. Line::length() const
  47. {
  48. return this->a.distance_to(&(this->b));
  49. }
  50. Point*
  51. Line::midpoint() const
  52. {
  53. return new Point ((this->a.x + this->b.x) / 2.0, (this->a.y + this->b.y) / 2.0);
  54. }
  55. Point*
  56. Line::point_at(double distance) const
  57. {
  58. double len = this->length();
  59. Point* p = new Point(this->a);
  60. if (this->a.x != this->b.x)
  61. p->x = this->a.x + (this->b.x - this->a.x) * distance / len;
  62. if (this->a.y != this->b.y)
  63. p->y = this->a.y + (this->b.y - this->a.y) * distance / len;
  64. return p;
  65. }
  66. bool
  67. Line::coincides_with(const Line* line) const
  68. {
  69. return this->a.coincides_with(&line->a) && this->b.coincides_with(&line->b);
  70. }
  71. double
  72. Line::distance_to(const Point* point) const
  73. {
  74. return point->distance_to(this);
  75. }
  76. double
  77. Line::atan2_() const
  78. {
  79. return atan2(this->b.y - this->a.y, this->b.x - this->a.x);
  80. }
  81. double
  82. Line::direction() const
  83. {
  84. double atan2 = this->atan2_();
  85. return (atan2 == PI) ? 0
  86. : (atan2 < 0) ? (atan2 + PI)
  87. : atan2;
  88. }
  89. Vector
  90. Line::vector() const
  91. {
  92. return Vector(this->b.x - this->a.x, this->b.y - this->a.y);
  93. }
  94. #ifdef SLIC3RXS
  95. void
  96. Line::from_SV(SV* line_sv)
  97. {
  98. AV* line_av = (AV*)SvRV(line_sv);
  99. this->a.from_SV_check(*av_fetch(line_av, 0, 0));
  100. this->b.from_SV_check(*av_fetch(line_av, 1, 0));
  101. }
  102. void
  103. Line::from_SV_check(SV* line_sv)
  104. {
  105. if (sv_isobject(line_sv) && (SvTYPE(SvRV(line_sv)) == SVt_PVMG)) {
  106. if (!sv_isa(line_sv, "Slic3r::Line") && !sv_isa(line_sv, "Slic3r::Line::Ref"))
  107. CONFESS("Not a valid Slic3r::Line object");
  108. *this = *(Line*)SvIV((SV*)SvRV( line_sv ));
  109. } else {
  110. this->from_SV(line_sv);
  111. }
  112. }
  113. SV*
  114. Line::to_AV() {
  115. AV* av = newAV();
  116. av_extend(av, 1);
  117. SV* sv = newSV(0);
  118. sv_setref_pv( sv, "Slic3r::Point::Ref", &(this->a) );
  119. av_store(av, 0, sv);
  120. sv = newSV(0);
  121. sv_setref_pv( sv, "Slic3r::Point::Ref", &(this->b) );
  122. av_store(av, 1, sv);
  123. return newRV_noinc((SV*)av);
  124. }
  125. SV*
  126. Line::to_SV_ref() {
  127. SV* sv = newSV(0);
  128. sv_setref_pv( sv, "Slic3r::Line::Ref", this );
  129. return sv;
  130. }
  131. SV*
  132. Line::to_SV_clone_ref() const {
  133. SV* sv = newSV(0);
  134. sv_setref_pv( sv, "Slic3r::Line", new Line(*this) );
  135. return sv;
  136. }
  137. SV*
  138. Line::to_SV_pureperl() const {
  139. AV* av = newAV();
  140. av_extend(av, 1);
  141. av_store(av, 0, this->a.to_SV_pureperl());
  142. av_store(av, 1, this->b.to_SV_pureperl());
  143. return newRV_noinc((SV*)av);
  144. }
  145. #endif
  146. }