// Update is called once per frame
    void Update()
    {
        var             player           = field_builder.player;
        var             target           = field_builder.target;
        CirclePrimitive player_primitive = new CirclePrimitive();

        player_primitive.center = ConvertTo2d(player.gameObject.transform.position);
        player_primitive.radius = player.radius * player.gameObject.transform.localScale.magnitude;

        CirclePrimitive target_primitive = new CirclePrimitive();

        target_primitive.center = ConvertTo2d(target.gameObject.transform.position);
        target_primitive.radius = target.radius * target.gameObject.transform.localScale.magnitude;

        Face2D field = field_builder.Build(field_builder.scene_loader.Scene, player_primitive, target_primitive);

        Vector2 anchor_pos = ConvertTo2d(anchor.position);

        if (!field.IsPointInside(anchor_pos))
        {
            anchor_pos = field.GetClosestPointOnBorder(anchor_pos);
        }

        var new_lookat = field_builder.MakeMiddlePrimitive(player_primitive, target_primitive).center;

        lookat.position = new Vector3(new_lookat.x, lookat.position.y, new_lookat.y);

        cam_operator.RefreshDestination(new Vector3(anchor_pos.x, anchor.position.y, anchor_pos.y), Vector3.zero, 0, time);
        cam_operator.DBG_Show(0);
    }
    public Face2D Intersect(Face2D target, List <ICuttableEdge> tool)
    {
        // 1. for each edge determine if intersection number is even, then find these intersections.
        // Then make new loops.
        // TODO : loops without intersections

        IList <TopologyIntersection> intersections = /*FilterIntersections(*/ FindAllIntersections(target, tool) /*, target, tool )*/;

        List <bool> loop_has_intersections = new List <bool>(target.Loops.Count);

        for (int i = 0; i < target.Loops.Count; ++i)
        {
            loop_has_intersections.Add(false);
        }

        List <List <ICuttableEdge> > new_loops = new List <List <ICuttableEdge> >();

        if (intersections.Count == 0)
        {
            // test point on tool loop, if in target, add it to the target
            if (target.IsPointInside(tool[0].Eval(0).pt))
            {
                new_loops.Add(tool);
                foreach (var loop in target.Loops)
                {
                    new_loops.Add(loop);
                }
                return(new Face2D(new_loops));
            }
            else
            {
                return(target);
            }
        }

        BopMap bop_map = new BopMap();

        {
            bop_map.edge2intersections = MakeIntersectionMap(intersections, target.Loops, tool);
            bop_map.target             = target.Loops;
            bop_map.tool_edges         = tool;
        };

        // find valid intersection and start from it
        bool unprocessed_found = false;

        int deadloop = 0;

        do
        {
            unprocessed_found = false;
            foreach (var intersection in intersections)
            {
                loop_has_intersections[intersection.LoopIdx] = true;
                if (intersection.Valid)
                {
                    unprocessed_found = true;
                    var new_loop = MakeLoop(intersection, bop_map);
                    if (new_loop != null)
                    {
                        if (new_loop.Count >= 2)
                        {
                            for (int i = 0; i < new_loop.Count; ++i)
                            {
                                new_loop[i].Connect(new_loop[(i + new_loop.Count - 1) % new_loop.Count], true);
                            }

                            new_loops.Add(new_loop);
                        }
                    }
                }
                if (deadloop++ > DeadloopMaxIters)
                {
                    Debug.LogError("deadloop");
                    throw new UnityException("deadloop");
                }
            }
            if (deadloop++ > DeadloopMaxIters)
            {
                Debug.LogError("deadloop");
                throw new UnityException("deadloop");
            }
        } while (unprocessed_found);

        for (int i = 0; i < loop_has_intersections.Count; ++i)
        {
            if (!loop_has_intersections[i])
            {
                new_loops.Add(target.Loops[i]);   // todo: test if inside
            }
        }

        return(new Face2D(new_loops));
    }