class BeachLineTests(unittest.TestCase):
    """ Tests for Simple Valued Beachlines (not arc-based) """
    def setUp(self):
        self.b = BeachLine(arc=False)

    def tearDown(self):
        del self.b

    def test_init(self):
        """ Check initial creation """
        self.assertIsInstance(self.b, BeachLine)
        self.assertFalse(self.b.arc)
        self.assertEqual(self.b.root, NilNode)
        self.assertEqual(len(self.b.nodes), 0)
        self.assertEqual(len(self.b.arcs_added), 0)

    def test_isEmptyOnInit(self):
        """ Check the beachline is empty on initial creation """
        self.assertTrue(self.b.isEmpty())
        self.assertEqual(len(self.b.get_chain()), 0)

    def test_minmax_on_empty_beachline(self):
        """ Check that min and max respond appropriately on an empty beachline """
        #todo: make these raise exceptions
        self.assertEqual(self.b.min(), None)
        self.assertEqual(self.b.max(), None)
class TrivialInsertBeachLineTestCase(unittest.TestCase):
    def setUp(self):
        self.b = BeachLine(arc=False)
        self.testvalue = 5
        self.b.insert(self.testvalue)

    def tearDown(self):
        del self.b

    def test_insert_singular(self):
        """ Test insertion works on a trivial case """
        self.assertFalse(self.b.isEmpty())
        self.assertIsInstance(self.b.root, Node)
        self.assertEqual(self.b.root.value, self.testvalue)
        self.assertEqual(len(self.b.nodes), 1)
        self.assertEqual(len(self.b.arcs_added), 1)

    def test_trivial_search(self):
        """ Check trivial root only search works """
        node, side = self.b.search(self.testvalue)
        self.assertIsInstance(node, Node)
        self.assertIsInstance(side, Centre)
        self.assertEqual(self.b.root, node)
        self.assertEqual(self.b.root, self.b.nodes[0])

    def test_root_is_black(self):
        """ Assert that the root is changed from red to black correctly """
        self.assertFalse(self.b.root.red)

    def test_empty_successor_and_predecessor(self):
        """ Check the successor/predecessor are empty in the trivial case """
        node, side = self.b.search(self.testvalue)
        self.assertEqual(node.get_predecessor(), NilNode)
        self.assertEqual(node.get_successor(), NilNode)
class ExpandedInsertion_tests(unittest.TestCase):
    def setUp(self):
        self.original_test_value = 5
        self.b = BeachLine(arc=False)
        self.b.insert(self.original_test_value)

    def tearDown(self):
        del self.b

    def test_greater_insert(self):
        greaterValue = self.original_test_value + 10
        self.b.insert(greaterValue)
        self.assertEqual(len(self.b.nodes), 2)
        self.assertEqual(len(self.b.arcs_added), 2)
        self.assertEqual(self.b.root.value, self.original_test_value)
        #check the value is inserted on the right, and is the successor:
        self.assertIsInstance(self.b.root.right, Node)
        self.assertFalse(self.b.root.isLeaf())
        self.assertTrue(self.b.root.right.isLeaf())
        self.assertEqual(self.b.root.get_successor(), self.b.root.right)
        self.assertEqual(self.b.nodes[1], self.b.root.get_successor())
        self.assertEqual(self.b.root.right.value, greaterValue)
        #check parentage
        self.assertEqual(self.b.root.right.parent, self.b.root)
        self.assertEqual(self.b.root.right.get_predecessor(), self.b.root)

    def test_lesser_insert(self):
        lesserValue = self.original_test_value - 10
        self.b.insert(lesserValue)
        self.assertEqual(len(self.b.nodes), 2)
        self.assertEqual(len(self.b.arcs_added), 2)
        self.assertEqual(self.b.root.value, self.original_test_value)
        #now check the value is inserted on the left, and is the predecessor
        self.assertIsInstance(self.b.root.left, Node)
        self.assertFalse(self.b.root.isLeaf())
        self.assertTrue(self.b.root.left.isLeaf())
        self.assertEqual(self.b.root.get_predecessor(), self.b.root.left)
        self.assertEqual(self.b.root.left.get_successor(), self.b.root)
        self.assertEqual(self.b.nodes[1], self.b.root.left)
        self.assertEqual(self.b.nodes[1].value, lesserValue)
        self.assertEqual(self.b.root.left.parent, self.b.root)

    def test_triple_insertions(self):
        lesserValue = self.original_test_value - 10
        greaterValue = self.original_test_value + 10
        self.b.insert(lesserValue)
        self.b.insert(greaterValue)
        self.assertEqual(len(self.b.nodes), 3)
        self.assertEqual(self.b.root.left.value, lesserValue)
        self.assertEqual(self.b.root.right.value, greaterValue)
        self.assertEqual(self.b.root.value, self.original_test_value)
class SimpleBeachLine_Deletion_tests(unittest.TestCase):
    def setUp(self):
        self.b = BeachLine(arc=False)

    def tearDown(self):
        del self.b

    def test_deletion(self):
        value = 10
        self.b.insert(10)
        self.assertIsInstance(self.b.root, Node)
        self.assertEqual(len(self.b.nodes), 1)
        self.b.delete_value(value)
        self.assertEqual(len(self.b.nodes), 0)
        self.assertEqual(self.b.root, NilNode)

    def test_multi_insert_then_delete_leaf(self):
        value1 = 10
        value2 = value1 + 10
        self.b.insert(value1)
        self.b.insert(value2)
        self.assertEqual(len(self.b.nodes), 2)
        self.assertIsInstance(self.b.root.right, Node)

        self.b.delete_value(value2)

        self.assertEqual(len(self.b.nodes), 1)
        self.assertEqual(self.b.root.right, NilNode)
 def setUp(self):
     self.b = BeachLine(arc=False)
     self.testvalue = 5
     self.b.insert(self.testvalue)
 def setUp(self):
     self.b = BeachLine(arc=False)
 def setUp(self):
     self.original_test_value = 5
     self.b = BeachLine(arc=False)
     self.b.insert(self.original_test_value)
import numpy as np
from numpy.random import random
from beachline import BeachLine
from Parabola import Parabola
import utils
import cairo

bl = BeachLine()
sweep = 0.8
p1 = np.array([0.25, 0.5])
p2 = np.array([0.75, 0.6])
p3 = np.array([0.35, 0.7])

arc1 = Parabola(*p1, sweep)
arc2 = Parabola(*p2, sweep)
arc3 = Parabola(*p3, sweep)
print('Arc1:', arc1)
print('Arc2:', arc2)
print('Arc3:', arc3)

bl.insert_root(arc1)

node1 = bl.search(p2[0], sweep)

new_head1 = bl.split(arc2, node1)
bl.balance(new_head1)
#bl.delete_leaf(bl.root.getMax())

node2 = bl.search(p3[0], sweep)

new_head2 = bl.split(arc3, node2)