1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/linkablemapobj.cpp Thu Jul 17 11:11:55 2008 +0000
1.3 @@ -0,0 +1,693 @@
1.4 +//#include <math.h>
1.5 +
1.6 +#include "linkablemapobj.h"
1.7 +#include "branchobj.h"
1.8 +#include "mapeditor.h"
1.9 +
1.10 +#include "version.h"
1.11 +
1.12 +
1.13 +/////////////////////////////////////////////////////////////////
1.14 +// LinkableMapObj
1.15 +/////////////////////////////////////////////////////////////////
1.16 +
1.17 +LinkableMapObj::LinkableMapObj():MapObj()
1.18 +{
1.19 + // cout << "Const LinkableMapObj ()\n";
1.20 + init ();
1.21 +}
1.22 +
1.23 +LinkableMapObj::LinkableMapObj(QCanvas* c) :MapObj(c)
1.24 +{
1.25 +// cout << "Const LinkableMapObj\n";
1.26 + init ();
1.27 +}
1.28 +
1.29 +LinkableMapObj::LinkableMapObj (LinkableMapObj* lmo) : MapObj (lmo->canvas)
1.30 +{
1.31 + copy (lmo);
1.32 +}
1.33 +
1.34 +LinkableMapObj::~LinkableMapObj()
1.35 +{
1.36 + delete (bottomline);
1.37 + delete (selbox);
1.38 + delete (frame);
1.39 + delLink();
1.40 +}
1.41 +
1.42 +void LinkableMapObj::delLink()
1.43 +{
1.44 + switch (style)
1.45 + {
1.46 + case StyleLine:
1.47 + delete (l);
1.48 + break;
1.49 + case StyleParabel:
1.50 + segment.clear();
1.51 + break;
1.52 + case StylePolyLine:
1.53 + delete (p);
1.54 + delete (l);
1.55 + break;
1.56 + case StylePolyParabel:
1.57 + delete (p);
1.58 + segment.clear();
1.59 + break;
1.60 + default:
1.61 + break;
1.62 + }
1.63 +}
1.64 +
1.65 +void LinkableMapObj::init ()
1.66 +{
1.67 + depth=-1;
1.68 + childObj=NULL;
1.69 + parObj=NULL;
1.70 + parObjTmpBuf=NULL;
1.71 + parPos=QPoint(0,0);
1.72 + childPos=QPoint(0,0);
1.73 + link2ParPos=false;
1.74 + l=NULL;
1.75 + orientation=OrientUndef;
1.76 + linkwidth=20;
1.77 + thickness_start=8;
1.78 + style=StyleUndef;
1.79 + linkpos=LinkBottom;
1.80 + segment.setAutoDelete (TRUE);
1.81 + arcsegs=13;
1.82 + QPointArray pa(arcsegs*2+2);
1.83 +
1.84 + bottomline=new QCanvasLine(canvas);
1.85 + bottomline->setPen( QPen(linkcolor, 1) );
1.86 + bottomline->setZ(Z_LINK);
1.87 + bottomline->show();
1.88 +
1.89 + // Prepare showing the selection of a MapObj
1.90 + selbox = new QCanvasRectangle (canvas);
1.91 + selbox->setZ(Z_SELBOX);
1.92 + selbox->setBrush( QColor(255,255,0) );
1.93 + selbox->setPen( QPen(QColor(255,255,0) ));
1.94 + selbox->hide();
1.95 + selected=false;
1.96 +
1.97 + // initialize frame
1.98 + frame = new FrameObj (canvas);
1.99 +
1.100 + repositionRequest=false;
1.101 +}
1.102 +
1.103 +void LinkableMapObj::copy (LinkableMapObj* other)
1.104 +{
1.105 + MapObj::copy(other);
1.106 + bboxTotal=other->bboxTotal;
1.107 +// linkwidth=other->linkwidth;
1.108 +
1.109 + setLinkStyle(other->style);
1.110 + setLinkColor (other->linkcolor);
1.111 +}
1.112 +
1.113 +void LinkableMapObj::setChildObj(LinkableMapObj* o)
1.114 +{
1.115 + childObj=o;
1.116 +}
1.117 +
1.118 +void LinkableMapObj::setParObj(LinkableMapObj* o)
1.119 +{
1.120 + parObj=o;
1.121 + mapEditor=parObj->getMapEditor();
1.122 +}
1.123 +
1.124 +void LinkableMapObj::setParObjTmp(LinkableMapObj*,QPoint,int)
1.125 +{
1.126 +}
1.127 +
1.128 +void LinkableMapObj::unsetParObjTmp()
1.129 +{
1.130 +}
1.131 +
1.132 +LinkStyle LinkableMapObj::getDefLinkStyle ()
1.133 +{
1.134 + LinkStyle ls=mapEditor->getLinkStyle();
1.135 + switch (ls)
1.136 + {
1.137 + case StyleLine:
1.138 + return ls;
1.139 + break;
1.140 + case StyleParabel:
1.141 + return ls;
1.142 + break;
1.143 + case StylePolyLine:
1.144 + if (depth>1)
1.145 + return StyleLine;
1.146 + else
1.147 + return ls;
1.148 + break;
1.149 + case StylePolyParabel:
1.150 + if (depth>1)
1.151 + return StyleParabel;
1.152 + else
1.153 + return ls;
1.154 + break;
1.155 + default:
1.156 + break;
1.157 + }
1.158 + return StyleUndef;
1.159 +}
1.160 +
1.161 +void LinkableMapObj::setLinkStyle(LinkStyle newstyle)
1.162 +{
1.163 + delLink();
1.164 +
1.165 + style=newstyle;
1.166 +
1.167 + if (childObj!=NULL && parObj != NULL)
1.168 + {
1.169 + int i;
1.170 + QCanvasLine* cl;
1.171 + switch (style)
1.172 + {
1.173 + case StyleUndef:
1.174 + bottomline->hide();
1.175 + break;
1.176 + case StyleLine:
1.177 + l = new QCanvasLine(canvas);
1.178 + l->setPen( QPen(linkcolor, 1) );
1.179 + l->setZ(Z_LINK);
1.180 + if (visible)
1.181 + l->show();
1.182 + else
1.183 + l->hide();
1.184 + break;
1.185 + case StyleParabel:
1.186 + for (i=0;i<arcsegs;i++)
1.187 + {
1.188 + cl = new QCanvasLine(canvas);
1.189 + cl->setPen( QPen(linkcolor, 1) );
1.190 + cl->setPoints( 0,0,i*10,100);
1.191 + cl->setZ(Z_LINK);
1.192 + if (visible)
1.193 + cl->show();
1.194 + else
1.195 + cl->hide();
1.196 + segment.append(cl);
1.197 + }
1.198 + pa0.resize (arcsegs+1);
1.199 + break;
1.200 + case StylePolyLine:
1.201 + p = new QCanvasPolygon(canvas);
1.202 + p->setBrush( linkcolor );
1.203 + p->setZ(Z_LINK);
1.204 + if (visible)
1.205 + p->show();
1.206 + else
1.207 + p->hide();
1.208 + pa0.resize (3);
1.209 + // TODO
1.210 + // a bit awkward: draw the lines additionally to polygon, to avoid
1.211 + // missing pixels, when polygon is extremly flat
1.212 + l = new QCanvasLine(canvas);
1.213 + l->setPen( QPen(linkcolor, 1) );
1.214 + l->setZ(Z_LINK);
1.215 + if (visible)
1.216 + l->show();
1.217 + else
1.218 + l->hide();
1.219 + break;
1.220 + case StylePolyParabel:
1.221 + p = new QCanvasPolygon(canvas);
1.222 + p->setBrush( linkcolor );
1.223 + p->setZ(Z_LINK);
1.224 + if (visible)
1.225 + p->show();
1.226 + else
1.227 + p->hide();
1.228 + pa0.resize (arcsegs*2+2);
1.229 + pa1.resize (arcsegs+1);
1.230 + pa2.resize (arcsegs+1);
1.231 +
1.232 + // TODO
1.233 + // a bit awkward: draw the lines additionally
1.234 + // to polygon, to avoid missing pixels,
1.235 + // if polygon is extremly flat
1.236 + for (i=0;i<arcsegs;i++)
1.237 + {
1.238 + cl = new QCanvasLine(canvas);
1.239 + cl->setPen( QPen(linkcolor, 1) );
1.240 + cl->setPoints( 0,0,i*10,100);
1.241 + cl->setZ(Z_LINK);
1.242 + if (visible)
1.243 + cl->show();
1.244 + else
1.245 + cl->hide();
1.246 + segment.append(cl);
1.247 + }
1.248 + break;
1.249 + default:
1.250 + break;
1.251 + }
1.252 + } else
1.253 + {
1.254 + cout << "Error: ChildObj or parObj == NULL in LinkableMapObj::setLinkStyle\n";
1.255 + }
1.256 +}
1.257 +
1.258 +LinkStyle LinkableMapObj::getLinkStyle()
1.259 +{
1.260 + return style;
1.261 +}
1.262 +
1.263 +void LinkableMapObj::setLinkPos(LinkPos lp)
1.264 +{
1.265 + linkpos=lp;
1.266 +}
1.267 +
1.268 +LinkPos LinkableMapObj::getLinkPos()
1.269 +{
1.270 + return linkpos;
1.271 +}
1.272 +
1.273 +
1.274 +void LinkableMapObj::setLinkColor()
1.275 +{
1.276 + // Overloaded in BranchObj and childs
1.277 + // here only set default color
1.278 + setLinkColor (mapEditor->getDefLinkColor());
1.279 +}
1.280 +
1.281 +void LinkableMapObj::setLinkColor(QColor col)
1.282 +{
1.283 + linkcolor=col;
1.284 + bottomline->setPen( QPen(linkcolor, 1) );
1.285 + QCanvasLine *cl;
1.286 + switch (style)
1.287 + {
1.288 + case StyleLine:
1.289 + l->setPen( QPen(col,1));
1.290 + break;
1.291 + case StyleParabel:
1.292 + for (cl=segment.first(); cl; cl=segment.next() )
1.293 + cl->setPen( QPen(col,1));
1.294 + break;
1.295 + case StylePolyLine:
1.296 + p->setBrush( QBrush(col));
1.297 + l->setPen( QPen(col,1));
1.298 + break;
1.299 + case StylePolyParabel:
1.300 + p->setBrush( QBrush(col));
1.301 + for (cl=segment.first(); cl; cl=segment.next() )
1.302 + cl->setPen( QPen(col,1));
1.303 + break;
1.304 + default:
1.305 + break;
1.306 + } // switch (style)
1.307 + updateLink();
1.308 +}
1.309 +
1.310 +QColor LinkableMapObj::getLinkColor()
1.311 +{
1.312 + return linkcolor;
1.313 +}
1.314 +
1.315 +FrameType LinkableMapObj::getFrameType()
1.316 +{
1.317 + return frame->getFrameType();
1.318 +}
1.319 +
1.320 +void LinkableMapObj::setFrameType(const FrameType &t)
1.321 +{
1.322 + frame->setFrameType(t);
1.323 + calcBBoxSize();
1.324 + positionBBox();
1.325 + requestReposition();
1.326 +}
1.327 +
1.328 +void LinkableMapObj::setFrameType(const QString &t)
1.329 +{
1.330 + frame->setFrameType(t);
1.331 + calcBBoxSize();
1.332 + positionBBox();
1.333 + requestReposition();
1.334 +}
1.335 +
1.336 +void LinkableMapObj::setVisibility (bool v)
1.337 +{
1.338 + MapObj::setVisibility (v);
1.339 + if (visible)
1.340 + {
1.341 + bottomline->show();
1.342 + // FIXME lines and segments should be done in LMO?
1.343 + if (style==StyleLine && l)
1.344 + {
1.345 + l->show();
1.346 + } else
1.347 + {
1.348 + QCanvasLine* cl;
1.349 + for (cl=segment.first(); cl; cl=segment.next() )
1.350 + cl->show();
1.351 + }
1.352 + } else
1.353 + {
1.354 + bottomline->hide();
1.355 + if (style==StyleLine && l)
1.356 + {
1.357 + l->hide();
1.358 + } else
1.359 + {
1.360 + QCanvasLine* cl;
1.361 + for (cl=segment.first(); cl; cl=segment.next() )
1.362 + cl->hide();
1.363 + }
1.364 + }
1.365 +}
1.366 +
1.367 +void LinkableMapObj::updateLink()
1.368 +{
1.369 + // needs:
1.370 + // childPos of parent
1.371 + // orient of parent
1.372 + // style
1.373 + //
1.374 + // sets:
1.375 + // orientation
1.376 + // childPos
1.377 + // parPos
1.378 + // offset
1.379 + // drawing of the link itself
1.380 +
1.381 +
1.382 + // updateLink is called from move, but called from constructor we don't
1.383 + // have parents yet...
1.384 + if (style==StyleUndef) return;
1.385 +
1.386 + if (frame->getFrameType() == NoFrame)
1.387 + linkpos=LinkBottom;
1.388 + else
1.389 + linkpos=LinkMiddle;
1.390 + switch (linkpos)
1.391 + {
1.392 + case LinkMiddle:
1.393 + offset=bbox.height() /2;
1.394 + break;
1.395 + default :
1.396 + offset=bbox.height()-1; // draw link to bottom of bbox
1.397 + break;
1.398 + }
1.399 +
1.400 + double p2x,p2y; // Set P2 Before setting
1.401 + if (!link2ParPos)
1.402 + {
1.403 + p2x=QPoint( parObj->getChildPos() ).x(); // P1, we have to look at
1.404 + p2y=QPoint( parObj->getChildPos() ).y(); // orientation
1.405 + } else
1.406 + {
1.407 + p2x=QPoint( parObj->getParPos() ).x();
1.408 + p2y=QPoint( parObj->getParPos() ).y();
1.409 + }
1.410 +
1.411 + LinkOrient orientOld=orientation;
1.412 +
1.413 + // Set orientation, first look for orientation of parent
1.414 + if (parObj->getOrientation() != OrientUndef )
1.415 + // use the orientation of the parent:
1.416 + orientation=parObj->getOrientation();
1.417 + else
1.418 + {
1.419 + // calc orientation depending on position rel to mapCenter
1.420 + if (absPos.x() < QPoint(parObj->getChildPos() ).x() )
1.421 + orientation=OrientLeftOfCenter;
1.422 + else
1.423 + orientation=OrientRightOfCenter;
1.424 + }
1.425 +
1.426 + if ((orientation!=orientOld) && (orientOld!= OrientUndef))
1.427 + {
1.428 + // Orientation just changed. Reorient this subbranch, because move is called
1.429 + // before updateLink => Position is still the old one, which could lead to
1.430 + // linking of subranch to itself => segfault
1.431 + //
1.432 + // Also possible: called in BranchObj::init(), then orientOld==OrientUndef,
1.433 + // no need to reposition now
1.434 + reposition();
1.435 + }
1.436 +
1.437 + if (orientation==OrientLeftOfCenter )
1.438 + {
1.439 + childPos=QPoint (absPos.x(),absPos.y()+offset);
1.440 + parPos=QPoint (absPos.x()+ bbox.width(), absPos.y() + offset );
1.441 + } else
1.442 + {
1.443 + childPos=QPoint (absPos.x()+ bbox.width(), absPos.y() + offset );
1.444 + parPos=QPoint (absPos.x(),absPos.y()+offset);
1.445 + }
1.446 + /* FIXME
1.447 + cout << " LMO::updateLink absPos="<<absPos<<endl;
1.448 + cout << " LMO::updateLink childPos="<<childPos<<endl;
1.449 + cout << " LMO::updateLink parPos="<<parPos<<endl;
1.450 + cout << " LMO::updateLink offset="<<offset<<endl;
1.451 + cout << " LMO::updateLink bbox.w="<<bbox.width()<<endl;
1.452 + cout << " LMO::updateLink bbox.h="<<bbox.height()<<endl;
1.453 + */
1.454 +
1.455 + double p1x=parPos.x(); // Link is drawn from P1 to P2
1.456 + double p1y=parPos.y();
1.457 +
1.458 + double vx=p2x - p1x; // V=P2-P1
1.459 + double vy=p2y - p1y;
1.460 +
1.461 + // Draw the horizontal line below heading (from ChildPos to ParPos)
1.462 + bottomline->setPoints (lrint(childPos.x()),
1.463 + lrint(childPos.y()),
1.464 + lrint(p1x),
1.465 + lrint(p1y) );
1.466 +
1.467 + double a; // angle
1.468 + if (vx > -0.000001 && vx < 0.000001)
1.469 + a=M_PI_2;
1.470 + else
1.471 + a=atan( vy / vx );
1.472 + // "turning point" for drawing polygonal links
1.473 + QPoint tp (-lrint(sin (a)*thickness_start), lrint(cos (a)*thickness_start));
1.474 +
1.475 + QCanvasLine *cl;
1.476 +
1.477 + int i;
1.478 +
1.479 + // Draw the link
1.480 + switch (style)
1.481 + {
1.482 + case StyleLine:
1.483 + l->setPoints( lrint (parPos.x()),
1.484 + lrint(parPos.y()),
1.485 + lrint(p2x),
1.486 + lrint(p2y) );
1.487 + break;
1.488 + case StyleParabel:
1.489 + parabel (pa0, p1x,p1y,p2x,p2y);
1.490 + i=0;
1.491 + for (cl=segment.first(); cl; cl=segment.next() )
1.492 + {
1.493 + cl->setPoints( pa0.point(i).x(), pa0.point(i).y(),pa0.point(i+1).x(),pa0.point(i+1).y());
1.494 + i++;
1.495 + }
1.496 + break;
1.497 + case StylePolyLine:
1.498 + pa0[0]=QPoint (lrint(p2x+tp.x()), lrint(p2y+tp.y()));
1.499 + pa0[1]=QPoint (lrint(p2x-tp.x()), lrint(p2y-tp.y()));
1.500 + pa0[2]=QPoint (lrint (parPos.x()), lrint(parPos.y()) );
1.501 + p->setPoints (pa0);
1.502 + // here too, draw line to avoid missing pixels
1.503 + l->setPoints( lrint (parPos.x()),
1.504 + lrint(parPos.y()),
1.505 + lrint(p2x),
1.506 + lrint(p2y) );
1.507 + break;
1.508 + case StylePolyParabel:
1.509 + parabel (pa1, p1x,p1y,p2x+tp.x(),p2y+tp.y());
1.510 + parabel (pa2, p1x,p1y,p2x-tp.x(),p2y-tp.y());
1.511 + for (i=0;i<=arcsegs;i++)
1.512 + {
1.513 + // Combine the arrays to a single one
1.514 + pa0[i]=pa1[i];
1.515 + pa0[i+arcsegs+1]=pa2[arcsegs-i];
1.516 + }
1.517 + p->setPoints (pa0);
1.518 + i=0;
1.519 + for (cl=segment.first(); cl; cl=segment.next() )
1.520 + {
1.521 + cl->setPoints( pa1.point(i).x(), pa1.point(i).y(),pa1.point(i+1).x(),pa1.point(i+1).y());
1.522 + i++;
1.523 + }
1.524 + break;
1.525 + default:
1.526 + break;
1.527 + } // switch (style)
1.528 +}
1.529 +
1.530 +LinkableMapObj* LinkableMapObj::getChildObj()
1.531 +{
1.532 + return childObj;
1.533 +}
1.534 +
1.535 +LinkableMapObj* LinkableMapObj::getParObj()
1.536 +{
1.537 + return parObj;
1.538 +}
1.539 +
1.540 +QPoint LinkableMapObj::getChildPos()
1.541 +{
1.542 + return childPos;
1.543 +}
1.544 +
1.545 +QPoint LinkableMapObj::getParPos()
1.546 +{
1.547 + return parPos;
1.548 +}
1.549 +
1.550 +QPoint LinkableMapObj::getRelPos()
1.551 +{
1.552 + if (!parObj) return QPoint (0,0);
1.553 + return QPoint(
1.554 + absPos.x() - parObj->x(),
1.555 + absPos.y() - parObj->y()
1.556 + );
1.557 +}
1.558 +
1.559 +LinkOrient LinkableMapObj::getOrientation()
1.560 +{
1.561 + return orientation;
1.562 +}
1.563 +
1.564 +int LinkableMapObj::getDepth()
1.565 +{
1.566 + return depth;
1.567 +}
1.568 +
1.569 +void LinkableMapObj::setMapEditor (MapEditor *me)
1.570 +{
1.571 + mapEditor=me;
1.572 +}
1.573 +
1.574 +MapEditor* LinkableMapObj::getMapEditor ()
1.575 +{
1.576 + return mapEditor;
1.577 +}
1.578 +
1.579 +QPoint LinkableMapObj::getRandPos()
1.580 +{
1.581 + // Choose a random position with given distance to parent:
1.582 + double a=rand()%360 * 2 * M_PI / 360;
1.583 + return QPoint ( (int)( + 150*cos (a)),
1.584 + (int)( + 150*sin (a)));
1.585 +}
1.586 +
1.587 +void LinkableMapObj::alignRelativeTo (QPoint ref)
1.588 +{
1.589 +}
1.590 +
1.591 +void LinkableMapObj::reposition()
1.592 +{
1.593 +cout << "LMO::reposition ???"<<endl;
1.594 + if (depth==0)
1.595 + {
1.596 + // only calculate the sizes once. If the deepest LMO changes its height,
1.597 + // all upper LMOs have to change, too.
1.598 + calcBBoxSizeWithChilds();
1.599 +
1.600 + alignRelativeTo ( QPoint (absPos.x(),
1.601 + absPos.y()-(bboxTotal.height()-bbox.height())/2) );
1.602 + } else
1.603 + {
1.604 + // This is only important for moving branches:
1.605 + // For editing a branch it isn't called...
1.606 + alignRelativeTo ( QPoint (absPos.x(),
1.607 + absPos.y()-(bboxTotal.height()-bbox.height())/2) );
1.608 + }
1.609 +}
1.610 +
1.611 +void LinkableMapObj::requestReposition()
1.612 +{
1.613 + if (!repositionRequest)
1.614 + {
1.615 + // Pass on the request to parental objects, if this hasn't
1.616 + // been done yet
1.617 + repositionRequest=true;
1.618 + if (parObj) parObj->requestReposition();
1.619 + }
1.620 +}
1.621 +
1.622 +void LinkableMapObj::forceReposition()
1.623 +{
1.624 + // Sometimes a reposition has to be done immediatly: For example
1.625 + // if the note editor flag changes, there is no user event in mapeditor
1.626 + // which could collect requests for a reposition.
1.627 + // Then we have to call forceReposition()
1.628 + // But no rule without exception: While loading a map or undoing it,
1.629 + // we want to block expensive repositioning, but just do it once at
1.630 + // the end, thus check first:
1.631 +
1.632 + if (mapEditor->blockReposition()) return;
1.633 +
1.634 + // Pass on the request to parental objects, if this hasn't been done yet
1.635 +
1.636 + if (parObj)
1.637 + parObj->forceReposition();
1.638 + else
1.639 + reposition(); }
1.640 +
1.641 +bool LinkableMapObj::repositionRequested()
1.642 +{
1.643 + return repositionRequest;
1.644 +}
1.645 +
1.646 +
1.647 +void LinkableMapObj::setSelBox()
1.648 +{
1.649 + selbox->setX (bbox.x() );
1.650 + selbox->setY (bbox.y() );
1.651 + selbox->setSize (bbox.width(), bbox.height() );
1.652 +}
1.653 +
1.654 +void LinkableMapObj::select()
1.655 +{
1.656 + setSelBox();
1.657 + selected=true;
1.658 + selbox->show();
1.659 +}
1.660 +
1.661 +
1.662 +void LinkableMapObj::unselect()
1.663 +{
1.664 + selected=false;
1.665 + selbox->hide();
1.666 +}
1.667 +
1.668 +void LinkableMapObj::parabel (QPointArray &ya, double p1x, double p1y, double p2x, double p2y)
1.669 +
1.670 +{
1.671 + double vx=p2x - p1x; // V=P2-P1
1.672 + double vy=p2y - p1y;
1.673 +
1.674 + double dx; // delta x during calculation of parabel
1.675 +
1.676 + double pnx; // next point
1.677 + double pny;
1.678 + double m;
1.679 +
1.680 + if (vx > -0.0001 && vx < 0.0001)
1.681 + m=0;
1.682 + else
1.683 + m=(vy / (vx*vx));
1.684 + dx=vx/(arcsegs);
1.685 + int i;
1.686 + ya.setPoint (0,QPoint (lrint(p1x),lrint(p1y)));
1.687 + for (i=1;i<=arcsegs;i++)
1.688 + {
1.689 + pnx=p1x+dx;
1.690 + pny=m*(pnx-parPos.x())*(pnx-parPos.x())+parPos.y();
1.691 + ya.setPoint (i,QPoint (lrint(pnx),lrint(pny)));
1.692 + p1x=pnx;
1.693 + p1y=pny;
1.694 + }
1.695 +}
1.696 +