597 |
} |
} |
598 |
}; |
}; |
599 |
|
|
600 |
|
|
601 |
|
/** 2D Rotation clockwise around a given point. |
602 |
|
* Parameter layout: angle (degrees), x, y |
603 |
|
*/ |
604 |
|
class RotateXYCenteredCoords { |
605 |
|
float a, s, c; |
606 |
|
float ox, oy; |
607 |
|
public: |
608 |
|
enum { NParams = 3, |
609 |
|
TransId = 16 }; |
610 |
|
template<class Ptr> void setParams(Ptr p, CoordSys *super) { |
611 |
|
a = p[0]; |
612 |
|
ox = p[1]; |
613 |
|
oy = p[2]; |
614 |
|
angleWasSet(); |
615 |
|
} |
616 |
|
void angleWasSet() { |
617 |
|
s = sin(a * M_PI / 180); |
618 |
|
c = cos(a * M_PI / 180); |
619 |
|
} |
620 |
|
/** Perform the internal transformation of this |
621 |
|
* coordsys. |
622 |
|
*/ |
623 |
|
void tr(const ZPt &from, ZPt &to) const { |
624 |
|
float x = from.x - ox; |
625 |
|
float y = from.y - oy; |
626 |
|
to.x = c * x + -s * y + ox; |
627 |
|
to.y = s * x + c * y + oy; |
628 |
|
to.z = from.z; |
629 |
|
} |
630 |
|
float tr_radius(const ZPt &from, float radius) const { |
631 |
|
return radius; |
632 |
|
} |
633 |
|
bool canPerformGL() { return true; } |
634 |
|
bool performGL() { |
635 |
|
glTranslatef(ox, oy, 0); |
636 |
|
glRotatef(a, 0, 0, 1); |
637 |
|
glTranslatef(-ox, -oy, 0); |
638 |
|
return true; |
639 |
|
} |
640 |
|
typedef RotateXYCenteredCoords InverseType; |
641 |
|
RotateXYCenteredCoords inverseTransform() { |
642 |
|
RotateXYCenteredCoords inv; |
643 |
|
inv.a = -a; |
644 |
|
inv.ox = ox; |
645 |
|
inv.oy = oy; |
646 |
|
inv.angleWasSet(); |
647 |
|
return inv; |
648 |
|
} |
649 |
|
float nonlinearity(const ZPt &p, float radius) { |
650 |
|
return 0; |
651 |
|
} |
652 |
|
}; |
653 |
|
|
654 |
|
/** Rotate the downwards vector at the origin |
655 |
|
* towards the given point. |
656 |
|
* XXX Document somewhere why! |
657 |
|
* XXX Think: to make more flexible, need separate parent, |
658 |
|
* nadirorigin, nadirpoint, rotatearoundpoint. |
659 |
|
* I.e. the point where the downwards vector needs to face |
660 |
|
* the nadir might not be the center of rotation. |
661 |
|
* This gets quite hairy then. |
662 |
|
*/ |
663 |
|
class NadirUniSqCoords { |
664 |
|
public: |
665 |
|
typedef RotateXYCenteredCoords BaseTransform; |
666 |
|
enum { NParams = 0, |
667 |
|
NDetermining = 1 }; |
668 |
|
void derivedParams(CoordSys *super, CoordSys **nadirCSp, |
669 |
|
float *params, float *newparams) { |
670 |
|
CoordSys *nadirCS = *nadirCSp; |
671 |
|
|
672 |
|
Pt usq = super->getSqSize(); |
673 |
|
float ox = usq.x / 2; |
674 |
|
float oy = usq.y / 2; |
675 |
|
|
676 |
|
ZPt origin = super->transform(ZPt(ox,oy,0)); |
677 |
|
|
678 |
|
ZPt nadir = nadirCS->transform(ZPt(0,0,0)); |
679 |
|
|
680 |
|
|
681 |
|
float x = origin.x - nadir.x; |
682 |
|
float y = origin.y - nadir.y; |
683 |
|
float angle = atan2(x, -y); |
684 |
|
|
685 |
|
newparams[0] = angle * 180 / M_PI; |
686 |
|
newparams[1] = ox; |
687 |
|
newparams[2] = oy; |
688 |
|
} |
689 |
|
bool shouldBeDrawn() { |
690 |
|
return true; |
691 |
|
} |
692 |
|
}; |
693 |
|
|
694 |
|
|
695 |
/** Translation. |
/** Translation. |
696 |
* Parameter layout: x, y, z |
* Parameter layout: x, y, z |
697 |
*/ |
*/ |
1377 |
new TransFactory<OrthoCoords>(), // 13 |
new TransFactory<OrthoCoords>(), // 13 |
1378 |
new WHTransFactory<OrthoBoxCoords>(), // 14 |
new WHTransFactory<OrthoBoxCoords>(), // 14 |
1379 |
new NoTransFactory<InverseCoordSys>(), // 15 |
new NoTransFactory<InverseCoordSys>(), // 15 |
1380 |
|
new TransFactory<RotateXYCenteredCoords>(), // 16 |
1381 |
|
new DerTransFactory<NadirUniSqCoords>(), // 17 |
1382 |
0 |
0 |
1383 |
}; |
}; |
1384 |
|
|