home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
yacl-012.zip
/
ui
/
piewedge.cxx
< prev
next >
Wrap
C/C++ Source or Header
|
1995-04-05
|
6KB
|
211 lines
/*
*
* Copyright (C) 1994, M. A. Sridhar
*
*
* This software is Copyright M. A. Sridhar, 1994. You are free
* to copy, modify or distribute this software as you see fit,
* and to use it for any purpose, provided this copyright
* notice and the following disclaimer are included with all
* copies.
*
* DISCLAIMER
*
* The author makes no warranties, either expressed or implied,
* with respect to this software, its quality, performance,
* merchantability, or fitness for any particular purpose. This
* software is distributed AS IS. The user of this software
* assumes all risks as to its quality and performance. In no
* event shall the author be liable for any direct, indirect or
* consequential damages, even if the author has been advised
* as to the possibility of such damages.
*
*/
#if defined(__GNUC__)
#pragma implementation
#endif
#include "ui/rectangl.h"
#include "ui/chord.h"
#include "ui/arc.h"
#include "ui/applic.h"
#include "ui/cntroler.h"
#include "ui/dwgsurf.h"
#include "ui/lineseg.h"
#include "ui/ellipse.h"
#include "ui/piewedge.h"
#include "ui/grutils.h"
#include <math.h>
#include <stdlib.h>
#ifndef M_PI
#define M_PI 3.1415926535897932
#endif
UI_PieWedge::UI_PieWedge (const UI_Rectangle &boundingRect, long
startAngleDeg64, long subtendedDeg64):
_arc (boundingRect, startAngleDeg64, subtendedDeg64)
{
_boundingEllipse = boundingRect;
_startAngle = startAngleDeg64;
_subtAngle = subtendedDeg64;
}
UI_PieWedge::UI_PieWedge (const UI_Point &p1, const UI_Point &p2,
const UI_Point& origin): _arc (p1, p2, origin)
{
_boundingEllipse = _arc.Ellipse().BoundingRectangle();
_startAngle = _arc.StartAngle();
_subtAngle = _arc.SubtendedAngle();
}
UI_Rectangle UI_PieWedge::BoundingRectangle () const
{
return Ellipse().BoundingRectangle();
}
bool UI_PieWedge::DrawOn (UI_DrawingSurface& sfc, const UI_Point& p) const
{
if (p != UI_Point (0, 0)) {
UI_PieWedge a (_boundingEllipse + p, _startAngle, _subtAngle);
sfc.DrawPieWedge (a, UID_Outline);
}
else
sfc.DrawPieWedge (*this, UID_Outline);
return TRUE;
}
bool UI_PieWedge::Fill (UI_DrawingSurface& sfc) const
{
sfc.DrawPieWedge (*this, UID_Fill);
return TRUE;
}
bool UI_PieWedge::ReshapeTo (const UI_Point &p1, const UI_Point &p2)
{
_arc.ReshapeTo (p1, p2);
_startAngle = _arc.StartAngle();
_subtAngle = _arc.SubtendedAngle();
_boundingEllipse = _arc.Ellipse().BoundingRectangle();
return TRUE;
}
void UI_PieWedge::StartAngle (long startAngle64)
{
_startAngle = startAngle64;
_arc.StartAngle (_startAngle);
}
void UI_PieWedge::SubtendedAngle (long subtAngle64)
{
_subtAngle = subtAngle64;
_arc.SubtendedAngle (_subtAngle);
}
void UI_PieWedge::Origin (const UI_Point &origin)
{
_boundingEllipse.Origin (origin);
_arc.Ellipse().BoundingRectangle().Origin (origin);
}
UI_Ellipse UI_PieWedge::Ellipse() const
{
return UI_Ellipse (_boundingEllipse);
}
UI_PointPair UI_PieWedge::EndPoints () const
{
return _arc.EndPoints();
}
bool UI_PieWedge::IntersectsBoundary (const UI_Rectangle& r) const
{
long topx = r.Left();
long topy = r.Top();
long a = r.Width();
long b = r.Height();
UI_PointPair pp = EndPoints();
UI_Point pa = pp.p1;
UI_Point pb = pp.p2;
long centerx = _boundingEllipse.Width()/2 + _boundingEllipse.Left();
long centery = _boundingEllipse.Height()/2 + _boundingEllipse.Top();
if (_arc.IntersectsBoundary (r) == TRUE) return TRUE;
UI_LineSegment la (UI_Point (topx, topy), UI_Point (topx+a, topy));
UI_LineSegment lb (UI_Point (topx, topy), UI_Point (topx, topy+b));
UI_LineSegment lc (UI_Point (topx, topy+b), UI_Point (topx+a, topy+b));
UI_LineSegment ld (UI_Point (topx+a, topy), UI_Point (topx+a, topy+b));
UI_LineSegment wa (pa, UI_Point (centerx, centery));
UI_LineSegment wb (pb, UI_Point (centerx, centery));
return (la.Intersects (wa) || lb.Intersects (wa) || lc.Intersects (wa) ||
ld.Intersects (wa) || la.Intersects (wb) || lb.Intersects (wb) ||
lc.Intersects (wb) || ld.Intersects (wb));
}
UI_HitTest UI_PieWedge::HitTest (const UI_Point& p) const
{
UI_Ellipse e = Ellipse();
UI_Point center = e.Center();
double x = p.XCoord() - center.XCoord();
double y = p.YCoord() - center.YCoord();
// Borland is buggy. The following conditional does not compute the
// correct result.
// double angle = (x == 0) ? (y > 0 ? M_PI/2 : 1.5 * M_PI)
// : atan2 (y, x);
// So we say:
double angle;
if (x == 0) {
if (y > 0)
angle = 1.5 * M_PI/2;
else
angle = M_PI / 2;
}
else angle = atan2 (-y, x); // Note the negated y, since y axis is
// downwards
if (angle < 0)
angle += 2 * M_PI;
double aStart = DegToRad (_startAngle / 64.0);
double aEnd = DegToRad ((_startAngle + _subtAngle) / 64.0);
if (angle >= aStart && angle <= aEnd) {
UI_HitTest result = e.HitTest (p);
if (result == UIHit_Inside)
return angle == aStart || angle == aEnd ? UIHit_Boundary
: UIHit_Inside;
return result;
}
return UIHit_Outside;
}