home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / yacl-012.zip / ui / piewedge.cxx < prev    next >
C/C++ Source or Header  |  1995-04-05  |  6KB  |  211 lines

  1.  
  2.  
  3.  
  4.  
  5.  
  6. /*
  7.  *
  8.  *          Copyright (C) 1994, M. A. Sridhar
  9.  *  
  10.  *
  11.  *     This software is Copyright M. A. Sridhar, 1994. You are free
  12.  *     to copy, modify or distribute this software  as you see fit,
  13.  *     and to use  it  for  any  purpose, provided   this copyright
  14.  *     notice and the following   disclaimer are included  with all
  15.  *     copies.
  16.  *
  17.  *                        DISCLAIMER
  18.  *
  19.  *     The author makes no warranties, either expressed or implied,
  20.  *     with respect  to  this  software, its  quality, performance,
  21.  *     merchantability, or fitness for any particular purpose. This
  22.  *     software is distributed  AS IS.  The  user of this  software
  23.  *     assumes all risks  as to its quality  and performance. In no
  24.  *     event shall the author be liable for any direct, indirect or
  25.  *     consequential damages, even if the  author has been  advised
  26.  *     as to the possibility of such damages.
  27.  *
  28.  */
  29.  
  30. #if defined(__GNUC__)
  31. #pragma implementation
  32. #endif
  33.  
  34.  
  35. #include "ui/rectangl.h"
  36. #include "ui/chord.h"
  37. #include "ui/arc.h"
  38. #include "ui/applic.h"
  39. #include "ui/cntroler.h"
  40. #include "ui/dwgsurf.h"
  41. #include "ui/lineseg.h"
  42. #include "ui/ellipse.h"
  43. #include "ui/piewedge.h"
  44. #include "ui/grutils.h"
  45.  
  46. #include <math.h>
  47. #include <stdlib.h>
  48.  
  49.  
  50. #ifndef M_PI
  51. #define M_PI 3.1415926535897932
  52. #endif
  53.  
  54.  
  55. UI_PieWedge::UI_PieWedge (const UI_Rectangle &boundingRect, long
  56.                           startAngleDeg64, long subtendedDeg64): 
  57.                          _arc (boundingRect, startAngleDeg64, subtendedDeg64)
  58. {
  59.     _boundingEllipse = boundingRect;
  60.     _startAngle      = startAngleDeg64;
  61.     _subtAngle       = subtendedDeg64;
  62. }
  63.  
  64.  
  65.  
  66. UI_PieWedge::UI_PieWedge (const UI_Point &p1, const UI_Point &p2,
  67.                           const UI_Point& origin): _arc (p1, p2, origin)
  68. {
  69.     _boundingEllipse = _arc.Ellipse().BoundingRectangle();
  70.     _startAngle      = _arc.StartAngle();
  71.     _subtAngle       = _arc.SubtendedAngle();
  72. }
  73.  
  74.  
  75.  
  76. UI_Rectangle UI_PieWedge::BoundingRectangle () const
  77. {
  78.     return Ellipse().BoundingRectangle();
  79. }
  80.  
  81.  
  82. bool UI_PieWedge::DrawOn (UI_DrawingSurface& sfc, const UI_Point& p) const
  83. {
  84.     if (p != UI_Point (0, 0)) {
  85.         UI_PieWedge a (_boundingEllipse + p, _startAngle, _subtAngle);
  86.         sfc.DrawPieWedge (a, UID_Outline);
  87.     }
  88.     else
  89.         sfc.DrawPieWedge (*this, UID_Outline);
  90.     return TRUE;
  91. }
  92.  
  93.  
  94.  
  95. bool UI_PieWedge::Fill (UI_DrawingSurface& sfc) const
  96. {
  97.     sfc.DrawPieWedge (*this, UID_Fill);
  98.     return TRUE;
  99. }
  100.  
  101.  
  102.  
  103. bool UI_PieWedge::ReshapeTo (const UI_Point &p1, const UI_Point &p2)
  104. {
  105.     _arc.ReshapeTo (p1, p2);
  106.     _startAngle = _arc.StartAngle();
  107.     _subtAngle  = _arc.SubtendedAngle();
  108.     _boundingEllipse = _arc.Ellipse().BoundingRectangle();
  109.     return TRUE;
  110. }
  111.  
  112.  
  113. void UI_PieWedge::StartAngle (long startAngle64)
  114. {
  115.     _startAngle = startAngle64;
  116.     _arc.StartAngle (_startAngle);
  117. }
  118.  
  119.  
  120.  
  121. void UI_PieWedge::SubtendedAngle (long subtAngle64)
  122. {
  123.     _subtAngle   = subtAngle64;
  124.     _arc.SubtendedAngle (_subtAngle);
  125. }
  126.  
  127.  
  128.  
  129. void UI_PieWedge::Origin (const UI_Point &origin)
  130. {
  131.     _boundingEllipse.Origin (origin);
  132.     _arc.Ellipse().BoundingRectangle().Origin (origin);
  133. }
  134.  
  135.  
  136.  
  137. UI_Ellipse UI_PieWedge::Ellipse() const
  138. {
  139.     return UI_Ellipse (_boundingEllipse);
  140. }
  141.  
  142.  
  143.  
  144. UI_PointPair UI_PieWedge::EndPoints () const
  145. {
  146.    return _arc.EndPoints();
  147. }
  148.  
  149.  
  150.  
  151. bool UI_PieWedge::IntersectsBoundary (const UI_Rectangle& r) const
  152. {
  153.     long topx = r.Left();
  154.     long topy = r.Top();
  155.     long a    = r.Width();
  156.     long b    = r.Height();
  157.     UI_PointPair pp = EndPoints();
  158.     UI_Point pa = pp.p1;
  159.     UI_Point pb = pp.p2;
  160.     long centerx = _boundingEllipse.Width()/2 + _boundingEllipse.Left();
  161.     long centery = _boundingEllipse.Height()/2 + _boundingEllipse.Top();
  162.  
  163.     if (_arc.IntersectsBoundary (r) == TRUE) return TRUE;
  164.  
  165.     UI_LineSegment la (UI_Point (topx, topy), UI_Point (topx+a, topy));
  166.     UI_LineSegment lb (UI_Point (topx, topy), UI_Point (topx, topy+b));
  167.     UI_LineSegment lc (UI_Point (topx, topy+b), UI_Point (topx+a, topy+b));
  168.     UI_LineSegment ld (UI_Point (topx+a, topy), UI_Point (topx+a, topy+b));
  169.     UI_LineSegment wa (pa, UI_Point (centerx, centery));
  170.     UI_LineSegment wb (pb, UI_Point (centerx, centery));
  171.  
  172.     return (la.Intersects (wa) || lb.Intersects (wa) || lc.Intersects (wa) ||
  173.             ld.Intersects (wa) || la.Intersects (wb) || lb.Intersects (wb) ||
  174.             lc.Intersects (wb) || ld.Intersects (wb));
  175. }
  176.  
  177.  
  178. UI_HitTest UI_PieWedge::HitTest (const UI_Point& p) const
  179. {
  180.     UI_Ellipse e = Ellipse();
  181.     UI_Point center = e.Center();
  182.     double x = p.XCoord() - center.XCoord();
  183.     double y = p.YCoord() - center.YCoord();
  184.     // Borland is buggy. The following conditional does not compute the
  185.     // correct result.
  186.     //     double angle = (x == 0) ? (y > 0 ? M_PI/2 : 1.5 * M_PI)
  187.     //         : atan2 (y, x);
  188.     // So we say:
  189.     double angle;
  190.     if (x == 0) {
  191.         if (y > 0)
  192.             angle = 1.5 * M_PI/2;
  193.         else
  194.             angle = M_PI / 2;
  195.     }
  196.     else angle = atan2 (-y, x); // Note the negated y, since y axis is
  197.                                 // downwards
  198.     if (angle < 0)
  199.         angle += 2 * M_PI;
  200.     double aStart =  DegToRad (_startAngle / 64.0);
  201.     double aEnd   =  DegToRad ((_startAngle + _subtAngle) / 64.0);
  202.     if (angle >=  aStart && angle <= aEnd) {
  203.         UI_HitTest result = e.HitTest (p);
  204.         if (result == UIHit_Inside)
  205.             return angle == aStart || angle == aEnd ? UIHit_Boundary
  206.                 : UIHit_Inside;
  207.         return result;
  208.     }
  209.     return UIHit_Outside;
  210. }
  211.