This project is read-only.

Carousel changes size based on number of items - Where do I put the camera?

Feb 27, 2013 at 6:55 PM
I'm using the Carousel layout in an ElementFlow. I had the camera location, field of view, gaps, popout distances just the way I wanted them.

But when the number of items in the carousel changes, the size of the rendered image ring changes. Which means the camera and other settings need to change in order for the desired view to be the same.

How would I programmatically determine what the settings need to be?
Feb 28, 2013 at 9:50 AM
I am pretty sure you can't, because I ran into this same problem. The ItemGap property is used to control the distance between two adjacent items, not the radius of the circle.

I ended up changing the CarouselLayout class to position the items based on a radius.

This is my code:
public class Carousel : LayoutBase
{
    private double UnitAngle
    {
        get { return 2 * Math.PI / Owner.Items.Count; }
    }

    private double Radius
    {
        get { return Owner.ItemGap; }
    }

    private double GapBetweenItems
    {
        // Cosine rule: c^2 = a^2 + b^2 - 2ab cos(r)
        get { return Math.Sqrt(2 * Math.Pow(Radius, 2) - (2 * Math.Pow(Radius, 2) * Math.Cos(UnitAngle))); }
    }

    protected override Motion GetAfterMotion (int deltaIndex)
    {
        double angle = Math.PI / 2 + UnitAngle * deltaIndex;
        Motion m = new Motion();
        m.X = -1 * Radius * Math.Cos(angle);
        m.Z = -1 * Owner.FrontItemGap + Radius * Math.Sin(angle);
        m.Y = 0;
        m.Angle = Owner.TiltAngle;
        m.Axis = new Vector3D(0, 1, 0);

        return m;
    }

    protected override Motion GetBeforeMotion (int deltaIndex)
    {
        double angle = Math.PI / 2 + UnitAngle * deltaIndex;
        Motion m = new Motion();
        m.X = -1 * Radius * Math.Cos(angle);
        m.Z = -1 * Owner.FrontItemGap + Radius * Math.Sin(angle);
        m.Y = 0;
        m.Angle = Owner.TiltAngle;
        m.Axis = new Vector3D(0, 1, 0);

        return m;
    }

    protected override Motion GetSelectionMotion ()
    {
        double angle = Math.PI / 2;
        Motion m = new Motion();
        m.X = Radius * Math.Cos(angle);
        m.Z = Owner.PopoutDistance + Radius * Math.Sin(angle);
        m.Y = 0;
        if (!double.IsNaN(Owner.FrontItemTiltAngle)) m.Angle = Owner.FrontItemTiltAngle;
        m.Axis = new Vector3D(0, 1, 0);

        return m;
    }
}