Exemplo n.º 1
0
    /// <summary>
    /// 布局标记组
    /// </summary>
    /// <param name="entitys">标记组</param>
    private void LayoutEntityGroup(EntityList entitys)
    {
        Entity first = entitys[0];
        Entity last  = entitys[entitys.Count - 1];

        int centerIndex = Mathf.FloorToInt(entitys.Count / 2.0f);
        int leftIndex   = centerIndex + (entitys.Count % 2);
        int rightIndex  = centerIndex - 1;

        float centerAngle = first.Angle + (last.Angle - first.Angle) / 2;
        float leftAngle   = centerAngle;
        float rightAngle  = centerAngle;

        if (entitys.Count % 2 == 1)
        {
            Entity             entity = entitys[centerIndex];
            EntityLayoutParams layout = GetLayoutParams(entity.ViewSize);
            float offsetAngle         = layout.GetAngleOffsetByRadius(entity.Radius);

            entity.Angle  = centerAngle;
            entity.Radius = layout.GetRadius(centerAngle);

            leftAngle  += offsetAngle;
            rightAngle -= offsetAngle;
        }

        while (rightIndex >= 0)
        {
            Entity             left       = entitys[leftIndex];
            EntityLayoutParams leftLayout = GetLayoutParams(left.ViewSize);
            float leftRadius      = leftLayout.GetLeftRadius(leftAngle);
            float leftOffsetAngle = leftLayout.GetAngleOffsetByRadius(leftRadius);

            left.Radius = leftRadius;
            left.Angle  = leftAngle + leftOffsetAngle;

            Entity             right       = entitys[rightIndex];
            EntityLayoutParams rightLayout = GetLayoutParams(right.ViewSize);
            float rightRadius      = rightLayout.GetRightRadius(rightAngle);
            float rightOffsetAngle = rightLayout.GetAngleOffsetByRadius(rightRadius);

            right.Radius = rightRadius;
            right.Angle  = rightAngle - rightOffsetAngle;

            leftAngle  += leftOffsetAngle * 2.0f;
            rightAngle -= rightOffsetAngle * 2.0f;

            leftIndex++;
            rightIndex--;
        }

        entitys.MaxAngle = leftAngle;
        entitys.MinAngle = rightAngle;
    }
Exemplo n.º 2
0
    /// <summary>
    /// 获取布局参数
    /// </summary>
    /// <param name="size">标记大小</param>
    /// <returns>布局参数</returns>
    private EntityLayoutParams GetLayoutParams(float size)
    {
        if (!m_LayoutParams.ContainsKey(size))
        {
            EntityLayoutParams layoutParams = new EntityLayoutParams();

            layoutParams.RingRadius = Mathf.Max(m_Root.rect.width, m_Root.rect.height) / 2;

            Vector3 upInChild = m_ScaleBox.InverseTransformPoint(m_Root.TransformPoint(Vector3.up)).normalized *layoutParams.RingRadius;
            Vector3 upInRoot  = m_Root.InverseTransformPoint(m_ScaleBox.TransformPoint(upInChild));

            layoutParams.MinRadius = size / 2.0f;
            layoutParams.MaxRadius = layoutParams.MinRadius / upInRoot.magnitude * layoutParams.RingRadius;

            layoutParams.MinRadiusRingAngle = Mathf.Asin(layoutParams.MinRadius / 2.0f / layoutParams.RingRadius) * Mathf.Rad2Deg * 2.0f;
            layoutParams.MaxRadiusRingAngle = Mathf.Asin(layoutParams.MaxRadius / 2.0f / layoutParams.RingRadius) * Mathf.Rad2Deg * 2.0f;

            layoutParams.LeftAngleParts  = new float[] { 0.0f - layoutParams.MinRadiusRingAngle, 90.0f - layoutParams.MaxRadiusRingAngle, 180.0f - layoutParams.MinRadiusRingAngle, 270.0f - layoutParams.MaxRadiusRingAngle, 360 - layoutParams.MinRadiusRingAngle };
            layoutParams.RightAngleParts = new float[] { 0.0f + layoutParams.MinRadiusRingAngle, 90.0f + layoutParams.MaxRadiusRingAngle, 180.0f + layoutParams.MinRadiusRingAngle, 270.0f + layoutParams.MaxRadiusRingAngle, 360 + layoutParams.MinRadiusRingAngle };

            m_LayoutParams.Add(size, layoutParams);
        }
        return(m_LayoutParams[size]);
    }
Exemplo n.º 3
0
    /// <summary>
    /// 布局标记列表
    /// </summary>
    /// <param name="entitys">标记列表</param>
    private void LayoutEntityList(EntityList entitys)
    {
        //确定初始属性
        foreach (Entity entity in entitys)
        {
            EntityLayoutParams layout = GetLayoutParams(entity.ViewSize);

            Vector2 position = m_MainCamera.transform.InverseTransformPoint(entity.TargetPosition).normalized *layout.RingRadius;
            entity.Angle  = Mathf.Atan2(position.y, position.x) * Mathf.Rad2Deg;
            entity.Radius = layout.GetRadius(entity.Angle);
        }

        //按角度排序
        entitys.SortByAngle();

        //按角度分组
        for (int i = 0; i < entitys.Count; i++)
        {
            if (i == 0 || entitys[i].Angle != entitys[i - 1].Angle)
            {
                m_GroupedEntitys.Add(EntityList.Create());
            }

            m_GroupedEntitys[m_GroupedEntitys.Count - 1].Add(entitys[i]);
        }

        //分组展开
        for (int i = 0; i < m_GroupedEntitys.Count; i++)
        {
            LayoutEntityGroup(m_GroupedEntitys[i]);
        }

        //多层次组合,再展开
        while (m_GroupedEntitys.Count > 1)
        {
            bool changed = false;

            //相邻组合并
            for (int i = 0; i < m_GroupedEntitys.Count - 1; i++)
            {
                EntityList group     = m_GroupedEntitys[i];
                EntityList nextGroup = m_GroupedEntitys[i + 1];

                if (group.MaxAngle >= nextGroup.MinAngle)
                {
                    group.AddRange(nextGroup);
                    group.MinAngle = Mathf.Min(group.MinAngle, nextGroup.MinAngle);
                    group.MaxAngle = Mathf.Max(group.MaxAngle, nextGroup.MaxAngle);

                    m_GroupedEntitys.Remove(nextGroup);
                    EntityList.Recycle(nextGroup);
                    changed = true;
                    i--;
                }
            }
            //首尾合并
            if (m_GroupedEntitys.Count > 1)
            {
                EntityList lastGroup = m_GroupedEntitys[m_GroupedEntitys.Count - 1];

                EntityList firstGroup    = m_GroupedEntitys[0];
                float      firstMinAngle = firstGroup.MinAngle + 360.0f;
                float      firstMaxAngle = firstGroup.MaxAngle + 360.0f;

                if (lastGroup.MaxAngle >= firstMaxAngle)
                {
                    lastGroup.MinAngle = Mathf.Min(lastGroup.MinAngle, firstMinAngle);
                    lastGroup.MaxAngle = Mathf.Max(lastGroup.MaxAngle, firstMaxAngle);

                    for (int j = 0; j < firstGroup.Count; j++)
                    {
                        Entity entity = firstGroup[j];
                        entity.Angle += 360.0f;
                        lastGroup.Add(entity);
                    }

                    m_GroupedEntitys.Remove(firstGroup);
                    EntityList.Recycle(firstGroup);
                    changed = true;
                }
            }

            //
            if (changed)
            {
                for (int i = 0; i < m_GroupedEntitys.Count; i++)
                {
                    EntityList group = m_GroupedEntitys[i];
                    group.SortByAngle();
                    LayoutEntityGroup(group);
                }
            }
            else
            {
                break;
            }
        }

        //回收组列表
        for (int i = 0; i < m_GroupedEntitys.Count; i++)
        {
            EntityList.Recycle(m_GroupedEntitys[i]);
        }
        m_GroupedEntitys.Clear();

        //应用坐标到视图
        foreach (Entity entity in m_EdgeEntitys)
        {
            EntityLayoutParams layout = GetLayoutParams(entity.ViewSize);

            //Debug.LogWarning(entity.Angle);
            Vector3 pos = Quaternion.Euler(0, 0, entity.Angle) * (Vector3.right * layout.RingRadius);

            Vector2 arrowPosition = m_ScaleBox.InverseTransformPoint(m_Root.TransformPoint(pos));
            arrowPosition = arrowPosition.normalized * (Mathf.Max(m_Root.rect.width, m_Root.rect.height) / 2);
            arrowPosition = m_Root.InverseTransformPoint(m_ScaleBox.TransformPoint(arrowPosition));

            entity.View.anchoredPosition = arrowPosition;
        }
    }