From af45f95f16cee22f8f012f706f4d0a42eaeb68fa Mon Sep 17 00:00:00 2001 From: Graeme Geldenhuys Date: Thu, 22 Nov 2012 11:48:47 +0000 Subject: Fixes line ending issues --- .../render/software/ctrl/agg_polygon_ctrl.pas | 1538 ++++++++++---------- 1 file changed, 769 insertions(+), 769 deletions(-) (limited to 'src/corelib/render/software/ctrl/agg_polygon_ctrl.pas') diff --git a/src/corelib/render/software/ctrl/agg_polygon_ctrl.pas b/src/corelib/render/software/ctrl/agg_polygon_ctrl.pas index 881c9d60..2aa16ed7 100644 --- a/src/corelib/render/software/ctrl/agg_polygon_ctrl.pas +++ b/src/corelib/render/software/ctrl/agg_polygon_ctrl.pas @@ -1,769 +1,769 @@ -//---------------------------------------------------------------------------- -// Anti-Grain Geometry - Version 2.4 (Public License) -// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com) -// -// Anti-Grain Geometry - Version 2.4 Release Milano 3 (AggPas 2.4 RM3) -// Pascal Port By: Milan Marusinec alias Milano -// milan@marusinec.sk -// http://www.aggpas.org -// Copyright (c) 2005-2006 -// -// Permission to copy, use, modify, sell and distribute this software -// is granted provided this copyright notice appears in all copies. -// This software is provided "as is" without express or implied -// warranty, and with no claim as to its suitability for any purpose. -// -//---------------------------------------------------------------------------- -// Contact: mcseem@antigrain.com -// mcseemagg@yahoo.com -// http://www.antigrain.com -// -// [Pascal Port History] ----------------------------------------------------- -// -// 23.06.2006-Milano: ptrcomp adjustments -// 23.02.2006-Milano: Unit port establishment -// -{ agg_polygon_ctrl.pas } -unit - agg_polygon_ctrl ; - -INTERFACE - -{$I agg_mode.inc } - -uses - Math , - agg_basics , - agg_conv_stroke , - agg_ellipse , - agg_color , - agg_ctrl , - agg_vertex_source ; - -{ TYPES DEFINITION } -type - simple_polygon_vertex_source = object(vertex_source ) - m_polygon : double_ptr; - m_num_points , - m_vertex : unsigned; - m_roundoff , - m_close : boolean; - - constructor Construct(polygon : double_ptr; np : unsigned; roundoff : boolean = false; close : boolean = true ); - - procedure close_(f : boolean ); - function _close : boolean; - - procedure rewind(path_id : unsigned ); virtual; - function vertex(x ,y : double_ptr ) : unsigned; virtual; - - end; - - polygon_ctrl_impl = object(ctrl ) - m_polygon : double_ptr; - m_num_points : unsigned; - - m_node , - m_edge : int; - - m_vs : simple_polygon_vertex_source; - m_stroke : conv_stroke; - - m_ellipse : ellipse; - m_point_radius : double; - m_status : unsigned; - - m_dx , - m_dy : double; - - m_in_polygon_check : boolean; - - constructor Construct(np : unsigned; point_radius : double = 5 ); - destructor Destruct; virtual; - - function _num_points : unsigned; - - function _xn(n : unsigned ) : double; - function _yn(n : unsigned ) : double; - - function xn_ptr(n : unsigned ) : double_ptr; - function yn_ptr(n : unsigned ) : double_ptr; - - function _polygon : double_ptr; - - procedure line_width_(w : double ); - function _line_width : double; - - procedure point_radius_(r : double ); - function _point_radius : double; - - procedure in_polygon_check_(f : boolean ); - function _in_polygon_check : boolean; - - procedure close_(f : boolean ); - function _close : boolean; - - // Vertex source interface - function num_paths : unsigned; virtual; - procedure rewind(path_id : unsigned ); virtual; - function vertex(x ,y : double_ptr ) : unsigned; virtual; - - // Event handlers - function in_rect(x ,y : double ) : boolean; virtual; - - function on_mouse_button_down(x ,y : double ) : boolean; virtual; - function on_mouse_button_up (x ,y : double ) : boolean; virtual; - - function on_mouse_move(x ,y : double; button_flag : boolean ) : boolean; virtual; - function on_arrow_keys(left ,right ,down ,up : boolean ) : boolean; virtual; - - // Private - function check_edge (i : unsigned; x ,y : double ) : boolean; - function point_in_polygon(x ,y : double ) : boolean; - - end; - - polygon_ctrl = object(polygon_ctrl_impl ) - m_color : aggclr; - - constructor Construct(np : unsigned; point_radius : double = 5 ); - - procedure line_color_(c : aggclr_ptr ); - - function _color(i : unsigned ) : aggclr_ptr; virtual; - - end; - -{ GLOBAL PROCEDURES } - - -IMPLEMENTATION -{ LOCAL VARIABLES & CONSTANTS } -{ UNIT IMPLEMENTATION } -{ CONSTRUCT } -constructor simple_polygon_vertex_source.Construct; -begin - m_polygon :=polygon; - m_num_points:=np; - m_vertex :=0; - m_roundoff :=roundoff; - m_close :=close; - -end; - -{ CLOSE_ } -procedure simple_polygon_vertex_source.close_; -begin - m_close:=f; - -end; - -{ _CLOSE } -function simple_polygon_vertex_source._close; -begin - result:=m_close; - -end; - -{ REWIND } -procedure simple_polygon_vertex_source.rewind; -begin - m_vertex:=0; - -end; - -{ VERTEX } -function simple_polygon_vertex_source.vertex; -begin - if m_vertex > m_num_points then - begin - result:=path_cmd_stop; - - exit; - - end; - - if m_vertex = m_num_points then - begin - inc(m_vertex ); - - if m_close then - result:=path_cmd_end_poly or path_flags_close - else - result:=path_cmd_end_poly or 0; - - exit; - - end; - - x^:=double_ptr(ptrcomp(m_polygon ) + (m_vertex * 2 ) * sizeof(double ) )^; - y^:=double_ptr(ptrcomp(m_polygon ) + (m_vertex * 2 + 1 ) * sizeof(double ) )^; - - if m_roundoff then - begin - x^:=Floor(x^ ) + 0.5; - y^:=Floor(y^ ) + 0.5; - - end; - - inc(m_vertex ); - - if m_vertex = 1 then - result:=path_cmd_move_to - else - result:=path_cmd_line_to; - -end; - -{ CONSTRUCT } -constructor polygon_ctrl_impl.Construct; -begin - inherited Construct(0 ,0 ,1 ,1 ,false ); - - agg_getmem(pointer(m_polygon ) ,np * 2 * sizeof(double ) ); - - m_num_points:=np; - - m_node:=-1; - m_edge:=-1; - - m_vs.Construct (m_polygon ,m_num_points ,false ); - m_stroke.Construct(@m_vs ); - m_ellipse.Construct; - - m_point_radius:=point_radius; - - m_status:=0; - - m_dx:=0.0; - m_dy:=0.0; - - m_in_polygon_check:=false; - - m_stroke.width_(1.0 ); - -end; - -{ DESTRUCT } -destructor polygon_ctrl_impl.Destruct; -begin - agg_freemem(pointer(m_polygon ) ,m_num_points * 2 * sizeof(double ) ); - - m_stroke.Destruct; - -end; - -{ _NUM_POINTS } -function polygon_ctrl_impl._num_points; -begin - result:=m_num_points; - -end; - -{ _XN } -function polygon_ctrl_impl._xn; -begin - result:=double_ptr(ptrcomp(m_polygon ) + (n * 2 ) * sizeof(double ) )^; - -end; - -{ _YN } -function polygon_ctrl_impl._yn; -begin - result:=double_ptr(ptrcomp(m_polygon ) + (n * 2 + 1 ) * sizeof(double ) )^; - -end; - -{ XN_PTR } -function polygon_ctrl_impl.xn_ptr; -begin - result:=double_ptr(ptrcomp(m_polygon ) + (n * 2 ) * sizeof(double ) ); - -end; - -{ YN_PTR } -function polygon_ctrl_impl.yn_ptr; -begin - result:=double_ptr(ptrcomp(m_polygon ) + (n * 2 + 1 ) * sizeof(double ) ); - -end; - -{ _POLYGON } -function polygon_ctrl_impl._polygon; -begin - result:=m_polygon; - -end; - -{ LINE_WIDTH_ } -procedure polygon_ctrl_impl.line_width_; -begin - m_stroke.width_(w ); - -end; - -{ _LINE_WIDTH } -function polygon_ctrl_impl._line_width; -begin - result:=m_stroke._width; - -end; - -{ POINT_RADIUS_ } -procedure polygon_ctrl_impl.point_radius_; -begin - m_point_radius:=r; - -end; - -{ _POINT_RADIUS } -function polygon_ctrl_impl._point_radius; -begin - result:=m_point_radius; - -end; - -{ IN_POLYGON_CHECK_ } -procedure polygon_ctrl_impl.in_polygon_check_; -begin - m_in_polygon_check:=f; - -end; - -{ _IN_POLYGON_CHECK } -function polygon_ctrl_impl._in_polygon_check; -begin - result:=m_in_polygon_check; - -end; - -{ CLOSE_ } -procedure polygon_ctrl_impl.close_; -begin - m_vs.close_(f ); - -end; - -{ _CLOSE } -function polygon_ctrl_impl._close; -begin - result:=m_vs._close; - -end; - -{ NUM_PATHS } -function polygon_ctrl_impl.num_paths; -begin - result:=1; - -end; - -{ REWIND } -procedure polygon_ctrl_impl.rewind; -begin - m_status:=0; - - m_stroke.rewind(0 ); - -end; - -{ VERTEX } -function polygon_ctrl_impl.vertex; -var - cmd : unsigned; - r : double; - -begin - cmd:=path_cmd_stop; - r :=m_point_radius; - - if m_status = 0 then - begin - cmd:=m_stroke.vertex(x ,y ); - - if not is_stop(cmd ) then - begin - transform_xy(x ,y ); - - result:=cmd; - - exit; - - end; - - if (m_node >= 0 ) and - (m_node = m_status ) then - r:=r * 1.2; - - m_ellipse.init(_xn(m_status ) ,_yn(m_status ) ,r ,r ,32 ); - - inc(m_status ); - - end; - - cmd:=m_ellipse.vertex(x ,y ); - - if not is_stop(cmd ) then - begin - transform_xy(x ,y ); - - result:=cmd; - - exit; - - end; - - if m_status >= m_num_points then - begin - result:=path_cmd_stop; - - exit; - - end; - - if (m_node >= 0 ) and - (m_node = m_status ) then - r:=r * 1.2; - - m_ellipse.init(_xn(m_status ) ,_yn(m_status ) ,r ,r ,32 ); - - inc(m_status ); - - cmd:=m_ellipse.vertex(x ,y ); - - if not is_stop(cmd ) then - transform_xy(x ,y ); - - result:=cmd; - -end; - -{ IN_RECT } -function polygon_ctrl_impl.in_rect; -begin - result:=false; - -end; - -{ ON_MOUSE_BUTTON_DOWN } -function polygon_ctrl_impl.on_mouse_button_down; -var - i : unsigned; - ret : boolean; - -begin - ret:=false; - - m_node:=-1; - m_edge:=-1; - - inverse_transform_xy(@x ,@y ); - - for i:=0 to m_num_points - 1 do - if Sqrt((x - _xn(i ) ) * (x - _xn(i ) ) + (y - _yn(i ) ) * (y - _yn(i ) ) ) < m_point_radius then - begin - m_dx :=x - _xn(i ); - m_dy :=y - _yn(i ); - m_node:=i; - ret :=true; - - break; - - end; - - if not ret then - for i:=0 to m_num_points - 1 do - if check_edge(i ,x ,y ) then - begin - m_dx :=x; - m_dy :=y; - m_edge:=i; - ret :=true; - - break; - - end; - - if not ret then - if point_in_polygon(x ,y ) then - begin - m_dx :=x; - m_dy :=y; - m_node:=m_num_points; - ret :=true; - - end; - - result:=ret; - -end; - -{ ON_MOUSE_BUTTON_UP } -function polygon_ctrl_impl.on_mouse_button_up; -var - ret : boolean; - -begin - ret :=(m_node >= 0 ) or (m_edge >= 0 ); - m_node:=-1; - m_edge:=-1; - result:=ret; - -end; - -{ ON_MOUSE_MOVE } -function polygon_ctrl_impl.on_mouse_move; -var - ret : boolean; - - i ,n1 ,n2 : unsigned; - - dx ,dy : double; - -begin - ret:=false; - - inverse_transform_xy(@x ,@y ); - - if m_node = m_num_points then - begin - dx:=x - m_dx; - dy:=y - m_dy; - - for i:=0 to m_num_points - 1 do - begin - xn_ptr(i )^:=_xn(i ) + dx; - yn_ptr(i )^:=_yn(i ) + dy; - - end; - - m_dx:=x; - m_dy:=y; - ret :=true; - - end - else - if m_edge >= 0 then - begin - n1:=m_edge; - n2:=(n1 + m_num_points - 1 ) mod m_num_points; - dx:=x - m_dx; - dy:=y - m_dy; - - xn_ptr(n1 )^:=_xn(n1 ) + dx; - yn_ptr(n1 )^:=_yn(n1 ) + dy; - xn_ptr(n2 )^:=_xn(n2 ) + dx; - yn_ptr(n2 )^:=_yn(n2 ) + dy; - - m_dx:=x; - m_dy:=y; - ret :=true; - - end - else - if m_node >= 0 then - begin - xn_ptr(m_node )^:=x - m_dx; - yn_ptr(m_node )^:=y - m_dy; - - ret:=true; - - end; - - result:=ret; - -end; - -{ ON_ARROW_KEYS } -function polygon_ctrl_impl.on_arrow_keys; -begin - result:=false; - -end; - -{ CHECK_EDGE } -function polygon_ctrl_impl.check_edge; -var - ret : boolean; - - n1 ,n2 : unsigned; - - x1 ,y1 ,x2 ,y2 ,dx ,dy ,x3 ,y3 ,x4 ,y4 ,den ,u1 ,xi ,yi : double; - -begin - ret:=false; - - n1:=i; - n2:=(i + m_num_points - 1 ) mod m_num_points; - x1:=_xn(n1 ); - y1:=_yn(n1 ); - x2:=_xn(n2 ); - y2:=_yn(n2 ); - - dx:=x2 - x1; - dy:=y2 - y1; - - if Sqrt(dx * dx + dy * dy ) > 0.0000001 then - begin - x3:=x; - y3:=y; - x4:=x3 - dy; - y4:=y3 + dx; - - den:=(y4 - y3 ) * (x2 - x1 ) - (x4 - x3 ) * (y2 - y1 ); - u1 :=((x4 - x3 ) * (y1 - y3 ) - (y4 - y3 ) * (x1 - x3 ) ) / den; - - xi:=x1 + u1 * (x2 - x1 ); - yi:=y1 + u1 * (y2 - y1 ); - - dx:=xi - x; - dy:=yi - y; - - if (u1 > 0.0 ) and - (u1 < 1.0 ) and - (Sqrt(dx * dx + dy * dy ) <= m_point_radius ) then - ret:=true; - - end; - - result:=ret; - -end; - -{ POINT_IN_POLYGON } -//======= Crossings Multiply algorithm of InsideTest ======================== -// -// By Eric Haines, 3D/Eye Inc, erich@eye.com -// -// This version is usually somewhat faster than the original published in -// Graphics Gems IV; by turning the division for testing the X axis crossing -// into a tricky multiplication test this part of the test became faster, -// which had the additional effect of making the test for "both to left or -// both to right" a bit slower for triangles than simply computing the -// intersection each time. The main increase is in triangle testing speed, -// which was about 15% faster; all other polygon complexities were pretty much -// the same as before. On machines where division is very expensive (not the -// case on the HP 9000 series on which I tested) this test should be much -// faster overall than the old code. Your mileage may (in fact, will) vary, -// depending on the machine and the test data, but in general I believe this -// code is both shorter and faster. This test was inspired by unpublished -// Graphics Gems submitted by Joseph Samosky and Mark Haigh-Hutchinson. -// Related work by Samosky is in: -// -// Samosky, Joseph, "SectionView: A system for interactively specifying and -// visualizing sections through three-dimensional medical image data", -// M.S. Thesis, Department of Electrical Engineering and Computer Science, -// Massachusetts Institute of Technology, 1993. -// -// Shoot a test ray along +X axis. The strategy is to compare vertex Y values -// to the testing point's Y and quickly discard edges which are entirely to one -// side of the test ray. Note that CONVEX and WINDING code can be added as -// for the CrossingsTest() code; it is left out here for clarity. -// -// Input 2D polygon _pgon_ with _numverts_ number of vertices and test point -// _point_, returns 1 if inside, 0 if outside. -function polygon_ctrl_impl.point_in_polygon; -var - j ,k : unsigned; - - yflag0 ,yflag1 ,inside_flag : int; - - vtx0 ,vty0 ,vtx1 ,vty1 : double; - -begin - if m_num_points < 3 then - begin - result:=false; - - exit; - - end; - - if not m_in_polygon_check then - begin - result:=false; - - exit; - - end; - - vtx0:=_xn(m_num_points - 1 ); - vty0:=_yn(m_num_points - 1 ); - -// get test bit for above/below X axis - yflag0:=int(vty0 >= y); - - vtx1:=_xn(0 ); - vty1:=_yn(0 ); - - inside_flag:=0; - - for j:=1 to m_num_points do - begin - yflag1:=int(vty1 >= y ); - - // Check if endpoints straddle (are on opposite sides) of X axis - // (i.e. the Y's differ); if so, +X ray could intersect this edge. - // The old test also checked whether the endpoints are both to the - // right or to the left of the test point. However, given the faster - // intersection point computation used below, this test was found to - // be a break-even proposition for most polygons and a loser for - // triangles (where 50% or more of the edges which survive this test - // will cross quadrants and so have to have the X intersection computed - // anyway). I credit Joseph Samosky with inspiring me to try dropping - // the "both left or both right" part of my code. - if yflag0 <> yflag1 then - // Check intersection of pgon segment with +X ray. - // Note if >= point's X; if so, the ray hits it. - // The division operation is avoided for the ">=" test by checking - // the sign of the first vertex wrto the test point; idea inspired - // by Joseph Samosky's and Mark Haigh-Hutchinson's different - // polygon inclusion tests. - if int((vty1 - y ) * (vtx0 - vtx1 ) >= - (vtx1 - x ) * (vty0 - vty1 ) ) = yflag1 then - inside_flag:=inside_flag xor 1; - - // Move to the next pair of vertices, retaining info as possible. - yflag0:=yflag1; - vtx0 :=vtx1; - vty0 :=vty1; - - if j >= m_num_points then - k:=j - m_num_points - else - k:=j; - - vtx1:=_xn(k ); - vty1:=_yn(k ); - - end; - - result:=inside_flag <> 0; - -end; - -{ CONSTRUCT } -constructor polygon_ctrl.Construct; -begin - inherited Construct(np ,point_radius ); - - m_color.ConstrDbl(0.0 ,0.0 ,0.0 ); - -end; - -{ LINE_COLOR_ } -procedure polygon_ctrl.line_color_; -begin - m_color:=c^; - -end; - -{ _COLOR } -function polygon_ctrl._color; -begin - result:=@m_color; - -end; - -END. - +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 (Public License) +// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com) +// +// Anti-Grain Geometry - Version 2.4 Release Milano 3 (AggPas 2.4 RM3) +// Pascal Port By: Milan Marusinec alias Milano +// milan@marusinec.sk +// http://www.aggpas.org +// Copyright (c) 2005-2006 +// +// Permission to copy, use, modify, sell and distribute this software +// is granted provided this copyright notice appears in all copies. +// This software is provided "as is" without express or implied +// warranty, and with no claim as to its suitability for any purpose. +// +//---------------------------------------------------------------------------- +// Contact: mcseem@antigrain.com +// mcseemagg@yahoo.com +// http://www.antigrain.com +// +// [Pascal Port History] ----------------------------------------------------- +// +// 23.06.2006-Milano: ptrcomp adjustments +// 23.02.2006-Milano: Unit port establishment +// +{ agg_polygon_ctrl.pas } +unit + agg_polygon_ctrl ; + +INTERFACE + +{$I agg_mode.inc } + +uses + Math , + agg_basics , + agg_conv_stroke , + agg_ellipse , + agg_color , + agg_ctrl , + agg_vertex_source ; + +{ TYPES DEFINITION } +type + simple_polygon_vertex_source = object(vertex_source ) + m_polygon : double_ptr; + m_num_points , + m_vertex : unsigned; + m_roundoff , + m_close : boolean; + + constructor Construct(polygon : double_ptr; np : unsigned; roundoff : boolean = false; close : boolean = true ); + + procedure close_(f : boolean ); + function _close : boolean; + + procedure rewind(path_id : unsigned ); virtual; + function vertex(x ,y : double_ptr ) : unsigned; virtual; + + end; + + polygon_ctrl_impl = object(ctrl ) + m_polygon : double_ptr; + m_num_points : unsigned; + + m_node , + m_edge : int; + + m_vs : simple_polygon_vertex_source; + m_stroke : conv_stroke; + + m_ellipse : ellipse; + m_point_radius : double; + m_status : unsigned; + + m_dx , + m_dy : double; + + m_in_polygon_check : boolean; + + constructor Construct(np : unsigned; point_radius : double = 5 ); + destructor Destruct; virtual; + + function _num_points : unsigned; + + function _xn(n : unsigned ) : double; + function _yn(n : unsigned ) : double; + + function xn_ptr(n : unsigned ) : double_ptr; + function yn_ptr(n : unsigned ) : double_ptr; + + function _polygon : double_ptr; + + procedure line_width_(w : double ); + function _line_width : double; + + procedure point_radius_(r : double ); + function _point_radius : double; + + procedure in_polygon_check_(f : boolean ); + function _in_polygon_check : boolean; + + procedure close_(f : boolean ); + function _close : boolean; + + // Vertex source interface + function num_paths : unsigned; virtual; + procedure rewind(path_id : unsigned ); virtual; + function vertex(x ,y : double_ptr ) : unsigned; virtual; + + // Event handlers + function in_rect(x ,y : double ) : boolean; virtual; + + function on_mouse_button_down(x ,y : double ) : boolean; virtual; + function on_mouse_button_up (x ,y : double ) : boolean; virtual; + + function on_mouse_move(x ,y : double; button_flag : boolean ) : boolean; virtual; + function on_arrow_keys(left ,right ,down ,up : boolean ) : boolean; virtual; + + // Private + function check_edge (i : unsigned; x ,y : double ) : boolean; + function point_in_polygon(x ,y : double ) : boolean; + + end; + + polygon_ctrl = object(polygon_ctrl_impl ) + m_color : aggclr; + + constructor Construct(np : unsigned; point_radius : double = 5 ); + + procedure line_color_(c : aggclr_ptr ); + + function _color(i : unsigned ) : aggclr_ptr; virtual; + + end; + +{ GLOBAL PROCEDURES } + + +IMPLEMENTATION +{ LOCAL VARIABLES & CONSTANTS } +{ UNIT IMPLEMENTATION } +{ CONSTRUCT } +constructor simple_polygon_vertex_source.Construct; +begin + m_polygon :=polygon; + m_num_points:=np; + m_vertex :=0; + m_roundoff :=roundoff; + m_close :=close; + +end; + +{ CLOSE_ } +procedure simple_polygon_vertex_source.close_; +begin + m_close:=f; + +end; + +{ _CLOSE } +function simple_polygon_vertex_source._close; +begin + result:=m_close; + +end; + +{ REWIND } +procedure simple_polygon_vertex_source.rewind; +begin + m_vertex:=0; + +end; + +{ VERTEX } +function simple_polygon_vertex_source.vertex; +begin + if m_vertex > m_num_points then + begin + result:=path_cmd_stop; + + exit; + + end; + + if m_vertex = m_num_points then + begin + inc(m_vertex ); + + if m_close then + result:=path_cmd_end_poly or path_flags_close + else + result:=path_cmd_end_poly or 0; + + exit; + + end; + + x^:=double_ptr(ptrcomp(m_polygon ) + (m_vertex * 2 ) * sizeof(double ) )^; + y^:=double_ptr(ptrcomp(m_polygon ) + (m_vertex * 2 + 1 ) * sizeof(double ) )^; + + if m_roundoff then + begin + x^:=Floor(x^ ) + 0.5; + y^:=Floor(y^ ) + 0.5; + + end; + + inc(m_vertex ); + + if m_vertex = 1 then + result:=path_cmd_move_to + else + result:=path_cmd_line_to; + +end; + +{ CONSTRUCT } +constructor polygon_ctrl_impl.Construct; +begin + inherited Construct(0 ,0 ,1 ,1 ,false ); + + agg_getmem(pointer(m_polygon ) ,np * 2 * sizeof(double ) ); + + m_num_points:=np; + + m_node:=-1; + m_edge:=-1; + + m_vs.Construct (m_polygon ,m_num_points ,false ); + m_stroke.Construct(@m_vs ); + m_ellipse.Construct; + + m_point_radius:=point_radius; + + m_status:=0; + + m_dx:=0.0; + m_dy:=0.0; + + m_in_polygon_check:=false; + + m_stroke.width_(1.0 ); + +end; + +{ DESTRUCT } +destructor polygon_ctrl_impl.Destruct; +begin + agg_freemem(pointer(m_polygon ) ,m_num_points * 2 * sizeof(double ) ); + + m_stroke.Destruct; + +end; + +{ _NUM_POINTS } +function polygon_ctrl_impl._num_points; +begin + result:=m_num_points; + +end; + +{ _XN } +function polygon_ctrl_impl._xn; +begin + result:=double_ptr(ptrcomp(m_polygon ) + (n * 2 ) * sizeof(double ) )^; + +end; + +{ _YN } +function polygon_ctrl_impl._yn; +begin + result:=double_ptr(ptrcomp(m_polygon ) + (n * 2 + 1 ) * sizeof(double ) )^; + +end; + +{ XN_PTR } +function polygon_ctrl_impl.xn_ptr; +begin + result:=double_ptr(ptrcomp(m_polygon ) + (n * 2 ) * sizeof(double ) ); + +end; + +{ YN_PTR } +function polygon_ctrl_impl.yn_ptr; +begin + result:=double_ptr(ptrcomp(m_polygon ) + (n * 2 + 1 ) * sizeof(double ) ); + +end; + +{ _POLYGON } +function polygon_ctrl_impl._polygon; +begin + result:=m_polygon; + +end; + +{ LINE_WIDTH_ } +procedure polygon_ctrl_impl.line_width_; +begin + m_stroke.width_(w ); + +end; + +{ _LINE_WIDTH } +function polygon_ctrl_impl._line_width; +begin + result:=m_stroke._width; + +end; + +{ POINT_RADIUS_ } +procedure polygon_ctrl_impl.point_radius_; +begin + m_point_radius:=r; + +end; + +{ _POINT_RADIUS } +function polygon_ctrl_impl._point_radius; +begin + result:=m_point_radius; + +end; + +{ IN_POLYGON_CHECK_ } +procedure polygon_ctrl_impl.in_polygon_check_; +begin + m_in_polygon_check:=f; + +end; + +{ _IN_POLYGON_CHECK } +function polygon_ctrl_impl._in_polygon_check; +begin + result:=m_in_polygon_check; + +end; + +{ CLOSE_ } +procedure polygon_ctrl_impl.close_; +begin + m_vs.close_(f ); + +end; + +{ _CLOSE } +function polygon_ctrl_impl._close; +begin + result:=m_vs._close; + +end; + +{ NUM_PATHS } +function polygon_ctrl_impl.num_paths; +begin + result:=1; + +end; + +{ REWIND } +procedure polygon_ctrl_impl.rewind; +begin + m_status:=0; + + m_stroke.rewind(0 ); + +end; + +{ VERTEX } +function polygon_ctrl_impl.vertex; +var + cmd : unsigned; + r : double; + +begin + cmd:=path_cmd_stop; + r :=m_point_radius; + + if m_status = 0 then + begin + cmd:=m_stroke.vertex(x ,y ); + + if not is_stop(cmd ) then + begin + transform_xy(x ,y ); + + result:=cmd; + + exit; + + end; + + if (m_node >= 0 ) and + (m_node = m_status ) then + r:=r * 1.2; + + m_ellipse.init(_xn(m_status ) ,_yn(m_status ) ,r ,r ,32 ); + + inc(m_status ); + + end; + + cmd:=m_ellipse.vertex(x ,y ); + + if not is_stop(cmd ) then + begin + transform_xy(x ,y ); + + result:=cmd; + + exit; + + end; + + if m_status >= m_num_points then + begin + result:=path_cmd_stop; + + exit; + + end; + + if (m_node >= 0 ) and + (m_node = m_status ) then + r:=r * 1.2; + + m_ellipse.init(_xn(m_status ) ,_yn(m_status ) ,r ,r ,32 ); + + inc(m_status ); + + cmd:=m_ellipse.vertex(x ,y ); + + if not is_stop(cmd ) then + transform_xy(x ,y ); + + result:=cmd; + +end; + +{ IN_RECT } +function polygon_ctrl_impl.in_rect; +begin + result:=false; + +end; + +{ ON_MOUSE_BUTTON_DOWN } +function polygon_ctrl_impl.on_mouse_button_down; +var + i : unsigned; + ret : boolean; + +begin + ret:=false; + + m_node:=-1; + m_edge:=-1; + + inverse_transform_xy(@x ,@y ); + + for i:=0 to m_num_points - 1 do + if Sqrt((x - _xn(i ) ) * (x - _xn(i ) ) + (y - _yn(i ) ) * (y - _yn(i ) ) ) < m_point_radius then + begin + m_dx :=x - _xn(i ); + m_dy :=y - _yn(i ); + m_node:=i; + ret :=true; + + break; + + end; + + if not ret then + for i:=0 to m_num_points - 1 do + if check_edge(i ,x ,y ) then + begin + m_dx :=x; + m_dy :=y; + m_edge:=i; + ret :=true; + + break; + + end; + + if not ret then + if point_in_polygon(x ,y ) then + begin + m_dx :=x; + m_dy :=y; + m_node:=m_num_points; + ret :=true; + + end; + + result:=ret; + +end; + +{ ON_MOUSE_BUTTON_UP } +function polygon_ctrl_impl.on_mouse_button_up; +var + ret : boolean; + +begin + ret :=(m_node >= 0 ) or (m_edge >= 0 ); + m_node:=-1; + m_edge:=-1; + result:=ret; + +end; + +{ ON_MOUSE_MOVE } +function polygon_ctrl_impl.on_mouse_move; +var + ret : boolean; + + i ,n1 ,n2 : unsigned; + + dx ,dy : double; + +begin + ret:=false; + + inverse_transform_xy(@x ,@y ); + + if m_node = m_num_points then + begin + dx:=x - m_dx; + dy:=y - m_dy; + + for i:=0 to m_num_points - 1 do + begin + xn_ptr(i )^:=_xn(i ) + dx; + yn_ptr(i )^:=_yn(i ) + dy; + + end; + + m_dx:=x; + m_dy:=y; + ret :=true; + + end + else + if m_edge >= 0 then + begin + n1:=m_edge; + n2:=(n1 + m_num_points - 1 ) mod m_num_points; + dx:=x - m_dx; + dy:=y - m_dy; + + xn_ptr(n1 )^:=_xn(n1 ) + dx; + yn_ptr(n1 )^:=_yn(n1 ) + dy; + xn_ptr(n2 )^:=_xn(n2 ) + dx; + yn_ptr(n2 )^:=_yn(n2 ) + dy; + + m_dx:=x; + m_dy:=y; + ret :=true; + + end + else + if m_node >= 0 then + begin + xn_ptr(m_node )^:=x - m_dx; + yn_ptr(m_node )^:=y - m_dy; + + ret:=true; + + end; + + result:=ret; + +end; + +{ ON_ARROW_KEYS } +function polygon_ctrl_impl.on_arrow_keys; +begin + result:=false; + +end; + +{ CHECK_EDGE } +function polygon_ctrl_impl.check_edge; +var + ret : boolean; + + n1 ,n2 : unsigned; + + x1 ,y1 ,x2 ,y2 ,dx ,dy ,x3 ,y3 ,x4 ,y4 ,den ,u1 ,xi ,yi : double; + +begin + ret:=false; + + n1:=i; + n2:=(i + m_num_points - 1 ) mod m_num_points; + x1:=_xn(n1 ); + y1:=_yn(n1 ); + x2:=_xn(n2 ); + y2:=_yn(n2 ); + + dx:=x2 - x1; + dy:=y2 - y1; + + if Sqrt(dx * dx + dy * dy ) > 0.0000001 then + begin + x3:=x; + y3:=y; + x4:=x3 - dy; + y4:=y3 + dx; + + den:=(y4 - y3 ) * (x2 - x1 ) - (x4 - x3 ) * (y2 - y1 ); + u1 :=((x4 - x3 ) * (y1 - y3 ) - (y4 - y3 ) * (x1 - x3 ) ) / den; + + xi:=x1 + u1 * (x2 - x1 ); + yi:=y1 + u1 * (y2 - y1 ); + + dx:=xi - x; + dy:=yi - y; + + if (u1 > 0.0 ) and + (u1 < 1.0 ) and + (Sqrt(dx * dx + dy * dy ) <= m_point_radius ) then + ret:=true; + + end; + + result:=ret; + +end; + +{ POINT_IN_POLYGON } +//======= Crossings Multiply algorithm of InsideTest ======================== +// +// By Eric Haines, 3D/Eye Inc, erich@eye.com +// +// This version is usually somewhat faster than the original published in +// Graphics Gems IV; by turning the division for testing the X axis crossing +// into a tricky multiplication test this part of the test became faster, +// which had the additional effect of making the test for "both to left or +// both to right" a bit slower for triangles than simply computing the +// intersection each time. The main increase is in triangle testing speed, +// which was about 15% faster; all other polygon complexities were pretty much +// the same as before. On machines where division is very expensive (not the +// case on the HP 9000 series on which I tested) this test should be much +// faster overall than the old code. Your mileage may (in fact, will) vary, +// depending on the machine and the test data, but in general I believe this +// code is both shorter and faster. This test was inspired by unpublished +// Graphics Gems submitted by Joseph Samosky and Mark Haigh-Hutchinson. +// Related work by Samosky is in: +// +// Samosky, Joseph, "SectionView: A system for interactively specifying and +// visualizing sections through three-dimensional medical image data", +// M.S. Thesis, Department of Electrical Engineering and Computer Science, +// Massachusetts Institute of Technology, 1993. +// +// Shoot a test ray along +X axis. The strategy is to compare vertex Y values +// to the testing point's Y and quickly discard edges which are entirely to one +// side of the test ray. Note that CONVEX and WINDING code can be added as +// for the CrossingsTest() code; it is left out here for clarity. +// +// Input 2D polygon _pgon_ with _numverts_ number of vertices and test point +// _point_, returns 1 if inside, 0 if outside. +function polygon_ctrl_impl.point_in_polygon; +var + j ,k : unsigned; + + yflag0 ,yflag1 ,inside_flag : int; + + vtx0 ,vty0 ,vtx1 ,vty1 : double; + +begin + if m_num_points < 3 then + begin + result:=false; + + exit; + + end; + + if not m_in_polygon_check then + begin + result:=false; + + exit; + + end; + + vtx0:=_xn(m_num_points - 1 ); + vty0:=_yn(m_num_points - 1 ); + +// get test bit for above/below X axis + yflag0:=int(vty0 >= y); + + vtx1:=_xn(0 ); + vty1:=_yn(0 ); + + inside_flag:=0; + + for j:=1 to m_num_points do + begin + yflag1:=int(vty1 >= y ); + + // Check if endpoints straddle (are on opposite sides) of X axis + // (i.e. the Y's differ); if so, +X ray could intersect this edge. + // The old test also checked whether the endpoints are both to the + // right or to the left of the test point. However, given the faster + // intersection point computation used below, this test was found to + // be a break-even proposition for most polygons and a loser for + // triangles (where 50% or more of the edges which survive this test + // will cross quadrants and so have to have the X intersection computed + // anyway). I credit Joseph Samosky with inspiring me to try dropping + // the "both left or both right" part of my code. + if yflag0 <> yflag1 then + // Check intersection of pgon segment with +X ray. + // Note if >= point's X; if so, the ray hits it. + // The division operation is avoided for the ">=" test by checking + // the sign of the first vertex wrto the test point; idea inspired + // by Joseph Samosky's and Mark Haigh-Hutchinson's different + // polygon inclusion tests. + if int((vty1 - y ) * (vtx0 - vtx1 ) >= + (vtx1 - x ) * (vty0 - vty1 ) ) = yflag1 then + inside_flag:=inside_flag xor 1; + + // Move to the next pair of vertices, retaining info as possible. + yflag0:=yflag1; + vtx0 :=vtx1; + vty0 :=vty1; + + if j >= m_num_points then + k:=j - m_num_points + else + k:=j; + + vtx1:=_xn(k ); + vty1:=_yn(k ); + + end; + + result:=inside_flag <> 0; + +end; + +{ CONSTRUCT } +constructor polygon_ctrl.Construct; +begin + inherited Construct(np ,point_radius ); + + m_color.ConstrDbl(0.0 ,0.0 ,0.0 ); + +end; + +{ LINE_COLOR_ } +procedure polygon_ctrl.line_color_; +begin + m_color:=c^; + +end; + +{ _COLOR } +function polygon_ctrl._color; +begin + result:=@m_color; + +end; + +END. + -- cgit v1.2.3-54-g00ecf