00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <cmath>
00024 #include "Constraints.h"
00025
00026 namespace GCS
00027 {
00028
00030
00032
00033 Constraint::Constraint()
00034 : origpvec(0), pvec(0), scale(1.), tag(0)
00035 {
00036 }
00037
00038 void Constraint::redirectParams(MAP_pD_pD redirectionmap)
00039 {
00040 int i=0;
00041 for (VEC_pD::iterator param=origpvec.begin();
00042 param != origpvec.end(); ++param, i++) {
00043 MAP_pD_pD::const_iterator it = redirectionmap.find(*param);
00044 if (it != redirectionmap.end())
00045 pvec[i] = it->second;
00046 }
00047 }
00048
00049 void Constraint::revertParams()
00050 {
00051 pvec = origpvec;
00052 }
00053
00054 ConstraintType Constraint::getTypeId()
00055 {
00056 return None;
00057 }
00058
00059 void Constraint::rescale(double coef)
00060 {
00061 scale = coef * 1.;
00062 }
00063
00064 double Constraint::error()
00065 {
00066 return 0.;
00067 }
00068
00069 double Constraint::grad(double *param)
00070 {
00071 return 0.;
00072 }
00073
00074 double Constraint::maxStep(MAP_pD_D &dir, double lim)
00075 {
00076 return lim;
00077 }
00078
00079
00080 ConstraintEqual::ConstraintEqual(double *p1, double *p2)
00081 {
00082 pvec.push_back(p1);
00083 pvec.push_back(p2);
00084 origpvec = pvec;
00085 rescale();
00086 }
00087
00088 ConstraintType ConstraintEqual::getTypeId()
00089 {
00090 return Equal;
00091 }
00092
00093 void ConstraintEqual::rescale(double coef)
00094 {
00095 scale = coef * 1.;
00096 }
00097
00098 double ConstraintEqual::error()
00099 {
00100 return scale * (*param1() - *param2());
00101 }
00102
00103 double ConstraintEqual::grad(double *param)
00104 {
00105 double deriv=0.;
00106 if (param == param1()) deriv += 1;
00107 if (param == param2()) deriv += -1;
00108 return scale * deriv;
00109 }
00110
00111
00112 ConstraintDifference::ConstraintDifference(double *p1, double *p2, double *d)
00113 {
00114 pvec.push_back(p1);
00115 pvec.push_back(p2);
00116 pvec.push_back(d);
00117 origpvec = pvec;
00118 rescale();
00119 }
00120
00121 ConstraintType ConstraintDifference::getTypeId()
00122 {
00123 return Difference;
00124 }
00125
00126 void ConstraintDifference::rescale(double coef)
00127 {
00128 scale = coef * 1.;
00129 }
00130
00131 double ConstraintDifference::error()
00132 {
00133 return scale * (*param2() - *param1() - *difference());
00134 }
00135
00136 double ConstraintDifference::grad(double *param)
00137 {
00138 double deriv=0.;
00139 if (param == param1()) deriv += -1;
00140 if (param == param2()) deriv += 1;
00141 if (param == difference()) deriv += -1;
00142 return scale * deriv;
00143 }
00144
00145
00146 ConstraintP2PDistance::ConstraintP2PDistance(Point &p1, Point &p2, double *d)
00147 {
00148 pvec.push_back(p1.x);
00149 pvec.push_back(p1.y);
00150 pvec.push_back(p2.x);
00151 pvec.push_back(p2.y);
00152 pvec.push_back(d);
00153 origpvec = pvec;
00154 rescale();
00155 }
00156
00157 ConstraintType ConstraintP2PDistance::getTypeId()
00158 {
00159 return P2PDistance;
00160 }
00161
00162 void ConstraintP2PDistance::rescale(double coef)
00163 {
00164 scale = coef * 1.;
00165 }
00166
00167 double ConstraintP2PDistance::error()
00168 {
00169 double dx = (*p1x() - *p2x());
00170 double dy = (*p1y() - *p2y());
00171 double d = sqrt(dx*dx + dy*dy);
00172 double dist = *distance();
00173 return scale * (d - dist);
00174 }
00175
00176 double ConstraintP2PDistance::grad(double *param)
00177 {
00178 double deriv=0.;
00179 if (param == p1x() || param == p1y() ||
00180 param == p2x() || param == p2y()) {
00181 double dx = (*p1x() - *p2x());
00182 double dy = (*p1y() - *p2y());
00183 double d = sqrt(dx*dx + dy*dy);
00184 if (param == p1x()) deriv += dx/d;
00185 if (param == p1y()) deriv += dy/d;
00186 if (param == p2x()) deriv += -dx/d;
00187 if (param == p2y()) deriv += -dy/d;
00188 }
00189 if (param == distance()) deriv += -1.;
00190
00191 return scale * deriv;
00192 }
00193
00194 double ConstraintP2PDistance::maxStep(MAP_pD_D &dir, double lim)
00195 {
00196 MAP_pD_D::iterator it;
00197
00198 it = dir.find(distance());
00199 if (it != dir.end()) {
00200 if (it->second < 0.)
00201 lim = std::min(lim, -(*distance()) / it->second);
00202 }
00203
00204 double ddx=0.,ddy=0.;
00205 it = dir.find(p1x());
00206 if (it != dir.end()) ddx += it->second;
00207 it = dir.find(p1y());
00208 if (it != dir.end()) ddy += it->second;
00209 it = dir.find(p2x());
00210 if (it != dir.end()) ddx -= it->second;
00211 it = dir.find(p2y());
00212 if (it != dir.end()) ddy -= it->second;
00213 double dd = sqrt(ddx*ddx+ddy*ddy);
00214 double dist = *distance();
00215 if (dd > dist) {
00216 double dx = (*p1x() - *p2x());
00217 double dy = (*p1y() - *p2y());
00218 double d = sqrt(dx*dx + dy*dy);
00219 if (dd > d)
00220 lim = std::min(lim, std::max(d,dist)/dd);
00221 }
00222 return lim;
00223 }
00224
00225
00226 ConstraintP2PAngle::ConstraintP2PAngle(Point &p1, Point &p2, double *a, double da_)
00227 : da(da_)
00228 {
00229 pvec.push_back(p1.x);
00230 pvec.push_back(p1.y);
00231 pvec.push_back(p2.x);
00232 pvec.push_back(p2.y);
00233 pvec.push_back(a);
00234 origpvec = pvec;
00235 rescale();
00236 }
00237
00238 ConstraintType ConstraintP2PAngle::getTypeId()
00239 {
00240 return P2PAngle;
00241 }
00242
00243 void ConstraintP2PAngle::rescale(double coef)
00244 {
00245 scale = coef * 1.;
00246 }
00247
00248 double ConstraintP2PAngle::error()
00249 {
00250 double dx = (*p2x() - *p1x());
00251 double dy = (*p2y() - *p1y());
00252 double a = *angle() + da;
00253 double ca = cos(a);
00254 double sa = sin(a);
00255 double x = dx*ca + dy*sa;
00256 double y = -dx*sa + dy*ca;
00257 return scale * atan2(y,x);
00258 }
00259
00260 double ConstraintP2PAngle::grad(double *param)
00261 {
00262 double deriv=0.;
00263 if (param == p1x() || param == p1y() ||
00264 param == p2x() || param == p2y()) {
00265 double dx = (*p2x() - *p1x());
00266 double dy = (*p2y() - *p1y());
00267 double a = *angle() + da;
00268 double ca = cos(a);
00269 double sa = sin(a);
00270 double x = dx*ca + dy*sa;
00271 double y = -dx*sa + dy*ca;
00272 double r2 = dx*dx+dy*dy;
00273 dx = -y/r2;
00274 dy = x/r2;
00275 if (param == p1x()) deriv += (-ca*dx + sa*dy);
00276 if (param == p1y()) deriv += (-sa*dx - ca*dy);
00277 if (param == p2x()) deriv += ( ca*dx - sa*dy);
00278 if (param == p2y()) deriv += ( sa*dx + ca*dy);
00279 }
00280 if (param == angle()) deriv += -1;
00281
00282 return scale * deriv;
00283 }
00284
00285 double ConstraintP2PAngle::maxStep(MAP_pD_D &dir, double lim)
00286 {
00287
00288 MAP_pD_D::iterator it = dir.find(angle());
00289 if (it != dir.end()) {
00290 double step = std::abs(it->second);
00291 if (step > M_PI/18.)
00292 lim = std::min(lim, (M_PI/18.) / step);
00293 }
00294 return lim;
00295 }
00296
00297
00298 ConstraintP2LDistance::ConstraintP2LDistance(Point &p, Line &l, double *d)
00299 {
00300 pvec.push_back(p.x);
00301 pvec.push_back(p.y);
00302 pvec.push_back(l.p1.x);
00303 pvec.push_back(l.p1.y);
00304 pvec.push_back(l.p2.x);
00305 pvec.push_back(l.p2.y);
00306 pvec.push_back(d);
00307 origpvec = pvec;
00308 rescale();
00309 }
00310
00311 ConstraintType ConstraintP2LDistance::getTypeId()
00312 {
00313 return P2LDistance;
00314 }
00315
00316 void ConstraintP2LDistance::rescale(double coef)
00317 {
00318 scale = coef;
00319 }
00320
00321 double ConstraintP2LDistance::error()
00322 {
00323 double x0=*p0x(), x1=*p1x(), x2=*p2x();
00324 double y0=*p0y(), y1=*p1y(), y2=*p2y();
00325 double dist = *distance();
00326 double dx = x2-x1;
00327 double dy = y2-y1;
00328 double d = sqrt(dx*dx+dy*dy);
00329 double area = std::abs(-x0*dy+y0*dx+x1*y2-x2*y1);
00330 return scale * (area/d - dist);
00331 }
00332
00333 double ConstraintP2LDistance::grad(double *param)
00334 {
00335 double deriv=0.;
00336
00337
00338
00339 if (param == p0x() || param == p0y() ||
00340 param == p1x() || param == p1y() ||
00341 param == p2x() || param == p2y()) {
00342 double x0=*p0x(), x1=*p1x(), x2=*p2x();
00343 double y0=*p0y(), y1=*p1y(), y2=*p2y();
00344 double dx = x2-x1;
00345 double dy = y2-y1;
00346 double d2 = dx*dx+dy*dy;
00347 double d = sqrt(d2);
00348 double area = -x0*dy+y0*dx+x1*y2-x2*y1;
00349 if (param == p0x()) deriv += (y1-y2) / d;
00350 if (param == p0y()) deriv += (x2-x1) / d ;
00351 if (param == p1x()) deriv += ((y2-y0)*d + (dx/d)*area) / d2;
00352 if (param == p1y()) deriv += ((x0-x2)*d + (dy/d)*area) / d2;
00353 if (param == p2x()) deriv += ((y0-y1)*d - (dx/d)*area) / d2;
00354 if (param == p2y()) deriv += ((x1-x0)*d - (dy/d)*area) / d2;
00355 if (area < 0)
00356 deriv *= -1;
00357 }
00358 if (param == distance()) deriv += -1;
00359
00360 return scale * deriv;
00361 }
00362
00363 double ConstraintP2LDistance::maxStep(MAP_pD_D &dir, double lim)
00364 {
00365 MAP_pD_D::iterator it;
00366
00367 it = dir.find(distance());
00368 if (it != dir.end()) {
00369 if (it->second < 0.)
00370 lim = std::min(lim, -(*distance()) / it->second);
00371 }
00372
00373 double darea=0.;
00374 double x0=*p0x(), x1=*p1x(), x2=*p2x();
00375 double y0=*p0y(), y1=*p1y(), y2=*p2y();
00376 it = dir.find(p0x());
00377 if (it != dir.end()) darea += (y1-y2) * it->second;
00378 it = dir.find(p0y());
00379 if (it != dir.end()) darea += (x2-x1) * it->second;
00380 it = dir.find(p1x());
00381 if (it != dir.end()) darea += (y2-y0) * it->second;
00382 it = dir.find(p1y());
00383 if (it != dir.end()) darea += (x0-x2) * it->second;
00384 it = dir.find(p2x());
00385 if (it != dir.end()) darea += (y0-y1) * it->second;
00386 it = dir.find(p2y());
00387 if (it != dir.end()) darea += (x1-x0) * it->second;
00388
00389 darea = std::abs(darea);
00390 if (darea > 0.) {
00391 double dx = x2-x1;
00392 double dy = y2-y1;
00393 double area = 0.3*(*distance())*sqrt(dx*dx+dy*dy);
00394 if (darea > area) {
00395 area = std::max(area, 0.3*std::abs(-x0*dy+y0*dx+x1*y2-x2*y1));
00396 if (darea > area)
00397 lim = std::min(lim, area/darea);
00398 }
00399 }
00400 return lim;
00401 }
00402
00403
00404 ConstraintPointOnLine::ConstraintPointOnLine(Point &p, Line &l)
00405 {
00406 pvec.push_back(p.x);
00407 pvec.push_back(p.y);
00408 pvec.push_back(l.p1.x);
00409 pvec.push_back(l.p1.y);
00410 pvec.push_back(l.p2.x);
00411 pvec.push_back(l.p2.y);
00412 origpvec = pvec;
00413 rescale();
00414 }
00415
00416 ConstraintType ConstraintPointOnLine::getTypeId()
00417 {
00418 return PointOnLine;
00419 }
00420
00421 void ConstraintPointOnLine::rescale(double coef)
00422 {
00423 scale = coef;
00424 }
00425
00426 double ConstraintPointOnLine::error()
00427 {
00428 double x0=*p0x(), x1=*p1x(), x2=*p2x();
00429 double y0=*p0y(), y1=*p1y(), y2=*p2y();
00430 double dx = x2-x1;
00431 double dy = y2-y1;
00432 double d = sqrt(dx*dx+dy*dy);
00433 double area = -x0*dy+y0*dx+x1*y2-x2*y1;
00434 return scale * area/d;
00435 }
00436
00437 double ConstraintPointOnLine::grad(double *param)
00438 {
00439 double deriv=0.;
00440
00441
00442
00443 if (param == p0x() || param == p0y() ||
00444 param == p1x() || param == p1y() ||
00445 param == p2x() || param == p2y()) {
00446 double x0=*p0x(), x1=*p1x(), x2=*p2x();
00447 double y0=*p0y(), y1=*p1y(), y2=*p2y();
00448 double dx = x2-x1;
00449 double dy = y2-y1;
00450 double d2 = dx*dx+dy*dy;
00451 double d = sqrt(d2);
00452 double area = -x0*dy+y0*dx+x1*y2-x2*y1;
00453 if (param == p0x()) deriv += (y1-y2) / d;
00454 if (param == p0y()) deriv += (x2-x1) / d ;
00455 if (param == p1x()) deriv += ((y2-y0)*d + (dx/d)*area) / d2;
00456 if (param == p1y()) deriv += ((x0-x2)*d + (dy/d)*area) / d2;
00457 if (param == p2x()) deriv += ((y0-y1)*d - (dx/d)*area) / d2;
00458 if (param == p2y()) deriv += ((x1-x0)*d - (dy/d)*area) / d2;
00459 }
00460 return scale * deriv;
00461 }
00462
00463
00464 ConstraintParallel::ConstraintParallel(Line &l1, Line &l2)
00465 {
00466 pvec.push_back(l1.p1.x);
00467 pvec.push_back(l1.p1.y);
00468 pvec.push_back(l1.p2.x);
00469 pvec.push_back(l1.p2.y);
00470 pvec.push_back(l2.p1.x);
00471 pvec.push_back(l2.p1.y);
00472 pvec.push_back(l2.p2.x);
00473 pvec.push_back(l2.p2.y);
00474 origpvec = pvec;
00475 rescale();
00476 }
00477
00478 ConstraintType ConstraintParallel::getTypeId()
00479 {
00480 return Parallel;
00481 }
00482
00483 void ConstraintParallel::rescale(double coef)
00484 {
00485 double dx1 = (*l1p1x() - *l1p2x());
00486 double dy1 = (*l1p1y() - *l1p2y());
00487 double dx2 = (*l2p1x() - *l2p2x());
00488 double dy2 = (*l2p1y() - *l2p2y());
00489 scale = coef / sqrt((dx1*dx1+dy1*dy1)*(dx2*dx2+dy2*dy2));
00490 }
00491
00492 double ConstraintParallel::error()
00493 {
00494 double dx1 = (*l1p1x() - *l1p2x());
00495 double dy1 = (*l1p1y() - *l1p2y());
00496 double dx2 = (*l2p1x() - *l2p2x());
00497 double dy2 = (*l2p1y() - *l2p2y());
00498 return scale * (dx1*dy2 - dy1*dx2);
00499 }
00500
00501 double ConstraintParallel::grad(double *param)
00502 {
00503 double deriv=0.;
00504 if (param == l1p1x()) deriv += (*l2p1y() - *l2p2y());
00505 if (param == l1p2x()) deriv += -(*l2p1y() - *l2p2y());
00506 if (param == l1p1y()) deriv += -(*l2p1x() - *l2p2x());
00507 if (param == l1p2y()) deriv += (*l2p1x() - *l2p2x());
00508
00509 if (param == l2p1x()) deriv += -(*l1p1y() - *l1p2y());
00510 if (param == l2p2x()) deriv += (*l1p1y() - *l1p2y());
00511 if (param == l2p1y()) deriv += (*l1p1x() - *l1p2x());
00512 if (param == l2p2y()) deriv += -(*l1p1x() - *l1p2x());
00513
00514 return scale * deriv;
00515 }
00516
00517
00518 ConstraintPerpendicular::ConstraintPerpendicular(Line &l1, Line &l2)
00519 {
00520 pvec.push_back(l1.p1.x);
00521 pvec.push_back(l1.p1.y);
00522 pvec.push_back(l1.p2.x);
00523 pvec.push_back(l1.p2.y);
00524 pvec.push_back(l2.p1.x);
00525 pvec.push_back(l2.p1.y);
00526 pvec.push_back(l2.p2.x);
00527 pvec.push_back(l2.p2.y);
00528 origpvec = pvec;
00529 rescale();
00530 }
00531
00532 ConstraintPerpendicular::ConstraintPerpendicular(Point &l1p1, Point &l1p2,
00533 Point &l2p1, Point &l2p2)
00534 {
00535 pvec.push_back(l1p1.x);
00536 pvec.push_back(l1p1.y);
00537 pvec.push_back(l1p2.x);
00538 pvec.push_back(l1p2.y);
00539 pvec.push_back(l2p1.x);
00540 pvec.push_back(l2p1.y);
00541 pvec.push_back(l2p2.x);
00542 pvec.push_back(l2p2.y);
00543 origpvec = pvec;
00544 rescale();
00545 }
00546
00547 ConstraintType ConstraintPerpendicular::getTypeId()
00548 {
00549 return Perpendicular;
00550 }
00551
00552 void ConstraintPerpendicular::rescale(double coef)
00553 {
00554 double dx1 = (*l1p1x() - *l1p2x());
00555 double dy1 = (*l1p1y() - *l1p2y());
00556 double dx2 = (*l2p1x() - *l2p2x());
00557 double dy2 = (*l2p1y() - *l2p2y());
00558 scale = coef / sqrt((dx1*dx1+dy1*dy1)*(dx2*dx2+dy2*dy2));
00559 }
00560
00561 double ConstraintPerpendicular::error()
00562 {
00563 double dx1 = (*l1p1x() - *l1p2x());
00564 double dy1 = (*l1p1y() - *l1p2y());
00565 double dx2 = (*l2p1x() - *l2p2x());
00566 double dy2 = (*l2p1y() - *l2p2y());
00567 return scale * (dx1*dx2 + dy1*dy2);
00568 }
00569
00570 double ConstraintPerpendicular::grad(double *param)
00571 {
00572 double deriv=0.;
00573 if (param == l1p1x()) deriv += (*l2p1x() - *l2p2x());
00574 if (param == l1p2x()) deriv += -(*l2p1x() - *l2p2x());
00575 if (param == l1p1y()) deriv += (*l2p1y() - *l2p2y());
00576 if (param == l1p2y()) deriv += -(*l2p1y() - *l2p2y());
00577
00578 if (param == l2p1x()) deriv += (*l1p1x() - *l1p2x());
00579 if (param == l2p2x()) deriv += -(*l1p1x() - *l1p2x());
00580 if (param == l2p1y()) deriv += (*l1p1y() - *l1p2y());
00581 if (param == l2p2y()) deriv += -(*l1p1y() - *l1p2y());
00582
00583 return scale * deriv;
00584 }
00585
00586
00587 ConstraintL2LAngle::ConstraintL2LAngle(Line &l1, Line &l2, double *a)
00588 {
00589 pvec.push_back(l1.p1.x);
00590 pvec.push_back(l1.p1.y);
00591 pvec.push_back(l1.p2.x);
00592 pvec.push_back(l1.p2.y);
00593 pvec.push_back(l2.p1.x);
00594 pvec.push_back(l2.p1.y);
00595 pvec.push_back(l2.p2.x);
00596 pvec.push_back(l2.p2.y);
00597 pvec.push_back(a);
00598 origpvec = pvec;
00599 rescale();
00600 }
00601
00602 ConstraintL2LAngle::ConstraintL2LAngle(Point &l1p1, Point &l1p2,
00603 Point &l2p1, Point &l2p2, double *a)
00604 {
00605 pvec.push_back(l1p1.x);
00606 pvec.push_back(l1p1.y);
00607 pvec.push_back(l1p2.x);
00608 pvec.push_back(l1p2.y);
00609 pvec.push_back(l2p1.x);
00610 pvec.push_back(l2p1.y);
00611 pvec.push_back(l2p2.x);
00612 pvec.push_back(l2p2.y);
00613 pvec.push_back(a);
00614 origpvec = pvec;
00615 rescale();
00616 }
00617
00618 ConstraintType ConstraintL2LAngle::getTypeId()
00619 {
00620 return L2LAngle;
00621 }
00622
00623 void ConstraintL2LAngle::rescale(double coef)
00624 {
00625 scale = coef * 1.;
00626 }
00627
00628 double ConstraintL2LAngle::error()
00629 {
00630 double dx1 = (*l1p2x() - *l1p1x());
00631 double dy1 = (*l1p2y() - *l1p1y());
00632 double dx2 = (*l2p2x() - *l2p1x());
00633 double dy2 = (*l2p2y() - *l2p1y());
00634 double a = atan2(dy1,dx1) + *angle();
00635 double ca = cos(a);
00636 double sa = sin(a);
00637 double x2 = dx2*ca + dy2*sa;
00638 double y2 = -dx2*sa + dy2*ca;
00639 return scale * atan2(y2,x2);
00640 }
00641
00642 double ConstraintL2LAngle::grad(double *param)
00643 {
00644 double deriv=0.;
00645 if (param == l1p1x() || param == l1p1y() ||
00646 param == l1p2x() || param == l1p2y()) {
00647 double dx1 = (*l1p2x() - *l1p1x());
00648 double dy1 = (*l1p2y() - *l1p1y());
00649 double r2 = dx1*dx1+dy1*dy1;
00650 if (param == l1p1x()) deriv += -dy1/r2;
00651 if (param == l1p1y()) deriv += dx1/r2;
00652 if (param == l1p2x()) deriv += dy1/r2;
00653 if (param == l1p2y()) deriv += -dx1/r2;
00654 }
00655 if (param == l2p1x() || param == l2p1y() ||
00656 param == l2p2x() || param == l2p2y()) {
00657 double dx1 = (*l1p2x() - *l1p1x());
00658 double dy1 = (*l1p2y() - *l1p1y());
00659 double dx2 = (*l2p2x() - *l2p1x());
00660 double dy2 = (*l2p2y() - *l2p1y());
00661 double a = atan2(dy1,dx1) + *angle();
00662 double ca = cos(a);
00663 double sa = sin(a);
00664 double x2 = dx2*ca + dy2*sa;
00665 double y2 = -dx2*sa + dy2*ca;
00666 double r2 = dx2*dx2+dy2*dy2;
00667 dx2 = -y2/r2;
00668 dy2 = x2/r2;
00669 if (param == l2p1x()) deriv += (-ca*dx2 + sa*dy2);
00670 if (param == l2p1y()) deriv += (-sa*dx2 - ca*dy2);
00671 if (param == l2p2x()) deriv += ( ca*dx2 - sa*dy2);
00672 if (param == l2p2y()) deriv += ( sa*dx2 + ca*dy2);
00673 }
00674 if (param == angle()) deriv += -1;
00675
00676 return scale * deriv;
00677 }
00678
00679 double ConstraintL2LAngle::maxStep(MAP_pD_D &dir, double lim)
00680 {
00681
00682 MAP_pD_D::iterator it = dir.find(angle());
00683 if (it != dir.end()) {
00684 double step = std::abs(it->second);
00685 if (step > M_PI/18.)
00686 lim = std::min(lim, (M_PI/18.) / step);
00687 }
00688 return lim;
00689 }
00690
00691
00692 ConstraintMidpointOnLine::ConstraintMidpointOnLine(Line &l1, Line &l2)
00693 {
00694 pvec.push_back(l1.p1.x);
00695 pvec.push_back(l1.p1.y);
00696 pvec.push_back(l1.p2.x);
00697 pvec.push_back(l1.p2.y);
00698 pvec.push_back(l2.p1.x);
00699 pvec.push_back(l2.p1.y);
00700 pvec.push_back(l2.p2.x);
00701 pvec.push_back(l2.p2.y);
00702 origpvec = pvec;
00703 rescale();
00704 }
00705
00706 ConstraintMidpointOnLine::ConstraintMidpointOnLine(Point &l1p1, Point &l1p2, Point &l2p1, Point &l2p2)
00707 {
00708 pvec.push_back(l1p1.x);
00709 pvec.push_back(l1p1.y);
00710 pvec.push_back(l1p2.x);
00711 pvec.push_back(l1p2.y);
00712 pvec.push_back(l2p1.x);
00713 pvec.push_back(l2p1.y);
00714 pvec.push_back(l2p2.x);
00715 pvec.push_back(l2p2.y);
00716 origpvec = pvec;
00717 rescale();
00718 }
00719
00720 ConstraintType ConstraintMidpointOnLine::getTypeId()
00721 {
00722 return MidpointOnLine;
00723 }
00724
00725 void ConstraintMidpointOnLine::rescale(double coef)
00726 {
00727 scale = coef * 1;
00728 }
00729
00730 double ConstraintMidpointOnLine::error()
00731 {
00732 double x0=((*l1p1x())+(*l1p2x()))/2;
00733 double y0=((*l1p1y())+(*l1p2y()))/2;
00734 double x1=*l2p1x(), x2=*l2p2x();
00735 double y1=*l2p1y(), y2=*l2p2y();
00736 double dx = x2-x1;
00737 double dy = y2-y1;
00738 double d = sqrt(dx*dx+dy*dy);
00739 double area = -x0*dy+y0*dx+x1*y2-x2*y1;
00740 return scale * area/d;
00741 }
00742
00743 double ConstraintMidpointOnLine::grad(double *param)
00744 {
00745 double deriv=0.;
00746
00747
00748
00749 if (param == l1p1x() || param == l1p1y() ||
00750 param == l1p2x() || param == l1p2y()||
00751 param == l2p1x() || param == l2p1y() ||
00752 param == l2p2x() || param == l2p2y()) {
00753 double x0=((*l1p1x())+(*l1p2x()))/2;
00754 double y0=((*l1p1y())+(*l1p2y()))/2;
00755 double x1=*l2p1x(), x2=*l2p2x();
00756 double y1=*l2p1y(), y2=*l2p2y();
00757 double dx = x2-x1;
00758 double dy = y2-y1;
00759 double d2 = dx*dx+dy*dy;
00760 double d = sqrt(d2);
00761 double area = -x0*dy+y0*dx+x1*y2-x2*y1;
00762 if (param == l1p1x()) deriv += (y1-y2) / (2*d);
00763 if (param == l1p1y()) deriv += (x2-x1) / (2*d);
00764 if (param == l1p2x()) deriv += (y1-y2) / (2*d);
00765 if (param == l1p2y()) deriv += (x2-x1) / (2*d);
00766 if (param == l2p1x()) deriv += ((y2-y0)*d + (dx/d)*area) / d2;
00767 if (param == l2p1y()) deriv += ((x0-x2)*d + (dy/d)*area) / d2;
00768 if (param == l2p2x()) deriv += ((y0-y1)*d - (dx/d)*area) / d2;
00769 if (param == l2p2y()) deriv += ((x1-x0)*d - (dy/d)*area) / d2;
00770 }
00771 return scale * deriv;
00772 }
00773
00774 }