575 |
}; |
}; |
576 |
VOB_PRIMITIVETRANS_DEFINED(BuoyOnCircle1_Explicit, "buoyOnCircle1"); |
VOB_PRIMITIVETRANS_DEFINED(BuoyOnCircle1_Explicit, "buoyOnCircle1"); |
577 |
|
|
578 |
|
class BuoyOnCircle2 : |
579 |
|
public Ortho, |
580 |
|
public DependentPrimitiveTransform |
581 |
|
{ |
582 |
|
public: |
583 |
|
enum { NDepends = 2 }; // Usual super plus the anchor |
584 |
|
|
585 |
|
/** The number of units to shift the coordsyses by default. |
586 |
|
*/ |
587 |
|
float shiftamount; |
588 |
|
|
589 |
|
/** The direction of shift. |
590 |
|
*/ |
591 |
|
float direction; |
592 |
|
|
593 |
|
BuoyOnCircle2() : shiftamount(10), direction(1) { |
594 |
|
} |
595 |
|
|
596 |
|
template<class SPtr> void setParams(SPtr depends) { |
597 |
|
// Get the anchor in the root coordinate system |
598 |
|
Pt anchor = Pt(depends[0]->getInverse().transform( |
599 |
|
depends[1]->transform( |
600 |
|
.5 * depends[1]->getSqSize()))); |
601 |
|
// And transform it to the square coordsys |
602 |
|
Pt sq = depends[0]->getSqSize(); |
603 |
|
anchor.x /= sq.x; |
604 |
|
anchor.y /= sq.y; |
605 |
|
|
606 |
|
float shift = shiftamount / sq.x; |
607 |
|
|
608 |
|
// Here, the circle center is always .5, .5 |
609 |
|
// and radius .5 |
610 |
|
|
611 |
|
int dir = direction > 0 ? 1 : -1; |
612 |
|
|
613 |
|
Pt shifted(anchor.x + dir * shift, anchor.y); |
614 |
|
Pt ctr(.5,.5); |
615 |
|
Pt buoy; |
616 |
|
if((shifted-ctr).length() >= .5) { |
617 |
|
buoy = shifted; |
618 |
|
} else { |
619 |
|
if((anchor-ctr).length() >= .5) { |
620 |
|
buoy = anchor; |
621 |
|
} else { |
622 |
|
buoy = Geom::project2circle( |
623 |
|
anchor, ctr + -dir * Pt(.5,0), |
624 |
|
ctr, .5); |
625 |
|
} |
626 |
|
} |
627 |
|
|
628 |
|
float scale = 1 - (anchor-ctr).length() / .5; |
629 |
|
if(scale < shift) scale = shift; |
630 |
|
this->x = buoy.x * sq.x; |
631 |
|
this->y = buoy.y * sq.y; |
632 |
|
this->z = -scale; |
633 |
|
this->sx = scale; |
634 |
|
this->sy = scale; |
635 |
|
} |
636 |
|
}; |
637 |
|
|
638 |
|
/** A better parametrization of buoys. |
639 |
|
* The box of the first coordsys is used directly as the |
640 |
|
* circle (or ellipse). The two required numeric |
641 |
|
* parameters are the direction of projection (positive x |
642 |
|
* or negative x) and the amount to shift in terms of |
643 |
|
* the parent |
644 |
|
* coordsys. |
645 |
|
*/ |
646 |
|
class BuoyOnCircle2_Explicit : |
647 |
|
public BuoyOnCircle2, |
648 |
|
public ParametrizedPrimitiveTransform { |
649 |
|
public: |
650 |
|
enum { NParams = 2 }; |
651 |
|
|
652 |
|
template<class SPtr, class P> void setParams(SPtr depends, P params) { |
653 |
|
direction = params[0]; |
654 |
|
shiftamount = params[1]; |
655 |
|
BuoyOnCircle2::setParams(depends); |
656 |
|
} |
657 |
|
|
658 |
|
}; |
659 |
|
|
660 |
|
VOB_PRIMITIVETRANS_DEFINED(BuoyOnCircle2_Explicit, "buoyOnCircle2"); |
661 |
|
|
662 |
/** Orthonormal transformation along with setting the box |
/** Orthonormal transformation along with setting the box |
663 |
* size of the coordinate system. |
* size of the coordinate system. |