cgal Documentation

The public CGAL repository, see the README below

RAW Doc

Technical Documentation: CGAL/cgal

ℹ️ Provenance: Multi-Tier Ingestion · CodeWiki Reference

Overview (README.md)

The Computational Geometry Algorithms Library (CGAL) is a C++ library that
aims to provide easy access to efficient and reliable algorithms in
computational geometry.

CGAL Releases

The primary vector of distribution of CGAL are source tarballs, released
twice a year, announced on the web site of CGAL.

Getting Started with CGAL

Since version 5.0, CGAL is a header-only library, meaning that
it is no longer needed to build CGAL libraries before it can be used.

Head over to the CGAL manual
for usage guides and tutorials that will get you started smoothly.

License

See the file LICENSE.md.

CGAL Git Repository Layout

The Git repository of CGAL has a different layout from release tarballs. It
contains a CMakeLists.txt file that serves as anchor for configuring and building programs,
and a set of subfolders, so called packages. Most packages
implement a data structure or an algorithm for CGAL (e.g., Convex_hull_2,
or Triangulation_3); however some packages serve special needs:

  • Installation - meta-files and CMake-support
  • Maintenance - infrastructural support
  • Core, CGALimageIO, Qt_widget, GraphicsView - component libraries
  • Scripts - scripts to simplify developer's and user's work
  • Testsuite - infrastructure for testsuite
  • Documentation - infrastructure for CGAL's manual
  • STL_Extension - extensions to the standard template library

More Information


Documentation Doc CMakeLists (`Documentation/doc/CMakeLists.txt`)

cmake_minimum_required(VERSION 3.12...3.31)
project(Documentation NONE)

Check whether this cmake script is the top level one

if(${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR})

decide if this is a branch build

if(NOT EXISTS "${CMAKE_SOURCE_DIR}/../VERSION")
set(CGAL_BRANCH_BUILD
ON
CACHE INTERNAL "CGAL Branch build")
endif()

if(CGAL_BRANCH_BUILD)
set(CGAL_ROOT "${CMAKE_SOURCE_DIR}/../..")
else()
set(CGAL_ROOT "${CMAKE_SOURCE_DIR}/..")
endif()
get_filename_component(CGAL_ROOT ${CGAL_ROOT} REALPATH)
else()
option(BUILD_DOC "Build the doxygen documentation" OFF)
if(NOT BUILD_DOC)
return()
endif()
set(CGAL_ROOT "${CMAKE_SOURCE_DIR}")
endif()

cmake_minimum_required(VERSION 3.18...3.31) # for list(SORT ... COMPARE NATURAL)

find_package(Doxygen REQUIRED)
find_package(Python3 REQUIRED COMPONENTS Interpreter)

if (NOT Python3_EXECUTABLE)
message(FATAL_ERROR "Cannot build the documentation without Python3!")
return()
endif()

message(VERBOSE "Using Python version ${Python3_VERSION}: ${Python3_EXECUTABLE}")

if(NOT DOXYGEN_FOUND)
message(WARNING "Cannot build the documentation without Doxygen!")
return()
endif()

#starting from cmake 3.9 the usage of DOXYGEN_EXECUTABLE is deprecated
if(TARGET Doxygen::doxygen)
get_property(
DOXYGEN_EXECUTABLE
TARGET Doxygen::doxygen
PROPERTY IMPORTED_LOCATION)
endif()

macro(subdirlist result curdir)
file(
GLOB children
RELATIVE ${curdir}
${curdir}/*)
set(dirlist "")
foreach(child ${children})
if(IS_DIRECTORY ${curdir}/${child})
set(dirlist ${dirlist} ${child})
endif()
endforeach()
set(${result} ${dirlist})
endmacro()

function(configure_doxygen_package CGAL_PACKAGE_NAME)
if(CGAL_BRANCH_BUILD)
set(CGAL_PACKAGE_DIR ${CGAL_ROOT}/${CGAL_PACKAGE_NAME})
else()
set(CGAL_PACKAGE_DIR ${CGAL_ROOT})
endif()

set(CGAL_PACKAGE_DOC_DIR ${CGAL_PACKAGE_DIR}/doc/${CGAL_PACKAGE_NAME})
set(CGAL_PACKAGE_INCLUDE_DIR ${CGAL_PACKAGE_DIR}/include/)

if(NOT EXISTS ${CGAL_PACKAGE_DOC_DIR}/Doxyfile.in)
return()
endif()
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${CGAL_PACKAGE_DOC_DIR}/Doxyfile.in)

set(CGAL_DOC_PACKAGE_DEFAULTS
${CGAL_DOC_DXY_DIR}/${CGAL_PACKAGE_NAME}_defaults.dxy)
file(REMOVE ${CGAL_DOC_PACKAGE_DEFAULTS})
file(APPEND ${CGAL_DOC_PACKAGE_DEFAULTS}
"@INCLUDE = ${CGAL_DOC_DOXY_DEFAULT}\n")
file(APPEND ${CGAL_DOC_PACKAGE_DEFAULTS}
"OUTPUT_DIRECTORY = ${CGAL_DOC_OUTPUT_DIR}/${CGAL_PACKAGE_NAME}\n")
file(APPEND ${CGAL_DOC_PACKAGE_DEFAULTS} "HTML_OUTPUT = .\n")

if(CGAL_DOC_CREATE_LOGS)
file(APPEND ${CGAL_DOC_PACKAGE_DEFAULTS}
"WARN_LOGFILE = ${CGAL_DOC_LOG_DIR}/${CGAL_PACKAGE_NAME}.log\n")
endif()

if(CGAL_DOC_RELEASE)
file(APPEND ${CGAL_DOC_PACKAGE_DEFAULTS} "GENERATE_TODOLIST = NO\n")
file(APPEND ${CGAL_DOC_PACKAGE_DEFAULTS} "GENERATE_BUGLIST = NO\n")
endif()

if(EXISTS "${CGAL_PACKAGE_DIR}/examples")
file(APPEND ${CGAL_DOC_PACKAGE_DEFAULTS}
"EXAMPLE_PATH = ${CGAL_PACKAGE_DIR}/examples\n")
endif()
if(CGAL_GENERATE_XML)
file(APPEND ${CGAL_DOC_PACKAGE_DEFAULTS} "GENERATE_XML = YES\n")
endif()

file(APPEND ${CGAL_DOC_PACKAGE_DEFAULTS}
"GENERATE_TAGFILE = ${CGAL_DOC_TAG_GEN_DIR}/${CGAL_PACKAGE_NAME}.tag\n")
file(APPEND ${CGAL_DOC_PACKAGE_DEFAULTS}
"STRIP_FROM_PATH = ${CGAL_PACKAGE_DOC_DIR}/\n")
file(APPEND ${CGAL_DOC_PACKAGE_DEFAULTS}
"STRIP_FROM_PATH += ${CGAL_PACKAGE_DIR}/include/\n")
file(APPEND ${CGAL_DOC_PACKAGE_DEFAULTS}
"STRIP_FROM_INC_PATH = ${CGAL_PACKAGE_DOC_DIR}/\n")
file(APPEND ${CGAL_DOC_PACKAGE_DEFAULTS}
"STRIP_FROM_INC_PATH += ${CGAL_PACKAGE_DIR}/include/\n")
file(APPEND ${CGAL_DOC_PACKAGE_DEFAULTS}
"ALIASES += "cgalPkgDescriptionBegin{2}=\details "\n")
file(
APPEND ${CGAL_DOC_PACKAGE_DEFAULTS}
"ALIASES += "cgalPkgManuals{2}="\n")
file(APPEND ${CGAL_DOC_PACKAGE_DEFAULTS} "INPUT = ${CGAL_PACKAGE_DOC_DIR}\n")

#special cases for Stream_support and Documentation package: stream support also needs include/CGAL while Documentation
if((NOT EXISTS "${CGAL_PACKAGE_DOC_DIR}/CGAL" AND (NOT ${CGAL_PACKAGE_NAME} STREQUAL "Documentation")) OR ${CGAL_PACKAGE_NAME} STREQUAL "Stream_support")
# This package has in-source documentation.
if(CGAL_BRANCH_BUILD) # use the entire include subdir
file(APPEND ${CGAL_DOC_PACKAGE_DEFAULTS}
"INPUT += ${CGAL_PACKAGE_DIR}/include/\n")
else() # use the filelist
if(EXISTS "${CGAL_PACKAGE_DOC_DIR}/filelist.txt")
file(STRINGS "${CGAL_PACKAGE_DOC_DIR}/filelist.txt" CGAL_PKG_FILES)
foreach(pkg_file ${CGAL_PKG_FILES})
file(APPEND ${CGAL_DOC_PACKAGE_DEFAULTS}
"INPUT += ${CGAL_PACKAGE_DIR}/include/${pkg_file}\n")
endforeach()
endif()
endif()
endif()
if(EXISTS "${CGAL_PACKAGE_DIR}/include/CGAL/${CGAL_PACKAGE_NAME}/internal")
file(APPEND ${CGAL_DOC_PACKAGE_DEFAULTS}
"EXCLUDE += ${CGAL_PACKAGE_DIR}/include/CGAL/${CGAL_PACKAGE_NAME}/internal\n")
endif()

IMAGE_PATH is set by default. For Documentation, we generate the extra path using packages.txt

set(IMAGE_PATHS "${CGAL_PACKAGE_DOC_DIR}/fig")
set(DEPENDENCIES "")

figure out the dependencies, using the file `dependencies` or `packages.txt` for Documentation

if(${CGAL_PACKAGE_NAME} STREQUAL "Documentation")
set(PackageFile ${CGAL_PACKAGE_DOC_DIR}/packages.txt)
file(STRINGS ${PackageFile} EntriesAsList REGEX "^\\package_listing{.+}$")
foreach(Line ${EntriesAsList})
string(REGEX REPLACE "^\\package_listing{(.+)}$" "\1" PKG "${Line}")
list(APPEND DEPENDENCIES ${PKG})

text
if(CGAL_BRANCH_BUILD)
    set(IMG_DIR "${CGAL_ROOT}/${PKG}/doc/${PKG}/fig")
  else()
    set(IMG_DIR "${CGAL_ROOT}/doc/${PKG}/fig")
  endif()

  if(EXISTS ${IMG_DIR})
    list(APPEND IMAGE_PATHS ${IMG_DIR})
  endif()
endforeach()

else()
if(EXISTS ${CGAL_PACKAGE_DOC_DIR}/dependencies)
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${CGAL_PACKAGE_DOC_DIR}/dependencies)
file(STRINGS ${CGAL_PACKAGE_DOC_DIR}/dependencies DEPENDENCIES)
endif()
endif()

foreach(depend ${DEPENDENCIES})
file(APPEND ${CGAL_DOC_PACKAGE_DEFAULTS}
"TAGFILES += ${CGAL_DOC_TAG_DIR}/${depend}.tag=../${depend}\n")
endforeach()

foreach(image_path ${IMAGE_PATHS})
file(APPEND ${CGAL_DOC_PACKAGE_DEFAULTS} "IMAGE_PATH += ${image_path}\n")
endforeach()

configure_file(${CGAL_PACKAGE_DOC_DIR}/Doxyfile.in
${CGAL_DOC_DXY_DIR}/${CGAL_PACKAGE_NAME}.dxy)

TODO we also want to run html_post_process per package as a custom_command with POST_BUILD

target that build the doc and put the tag file in the generation directory CGAL_DOC_TAG_GEN_DIR

add_custom_target(
${CGAL_PACKAGE_NAME}_internal_doxygen_run
${DOXYGEN_EXECUTABLE} ${CGAL_DOC_DXY_DIR}/${CGAL_PACKAGE_NAME}.dxy)

set_target_properties(${CGAL_PACKAGE_NAME}_internal_doxygen_run
PROPERTIES FOLDER Documentation/Packages)

#target moving the tag file into the read directory CGAL_DOC_TAG_DIR
if("${CGAL_PACKAGE_NAME}" STREQUAL "Documentation")
set(CGAL_PACKAGE_TAGFILE "Manual.tag")
else()
set(CGAL_PACKAGE_TAGFILE "${CGAL_PACKAGE_NAME}.tag")
endif()
add_custom_target(
${CGAL_PACKAGE_NAME}_copy_doc_tags
${CMAKE_COMMAND} -E copy "${CGAL_DOC_TAG_GEN_DIR}/${CGAL_PACKAGE_TAGFILE}"
"${CGAL_DOC_TAG_DIR}/${CGAL_PACKAGE_TAGFILE}")

#add the doc target doing both the doc generation and then the tag file copy
add_custom_target(
${CGAL_PACKAGE_NAME}_doc
${DOXYGEN_EXECUTABLE} ${CGAL_DOC_DXY_DIR}/${CGAL_PACKAGE_NAME}.dxy
COMMAND
${CMAKE_COMMAND} -E copy
"${CGAL_DOC_TAG_GEN_DIR}/${CGAL_PACKAGE_TAGFILE}"
"${CGAL_DOC_TAG_DIR}/${CGAL_PACKAGE_TAGFILE}")

${depend}_doc)

don't do this for now

foreach(depend ${DEPENDENCIES})

add_dependencies(${CGAL_PACKAGE_NAME}_doc

${depend}_doc)

endforeach()

endfunction()

set up the directories and variables

if(CGAL_DOC_MATHJAX_LOCATION)
set(CGAL_DOC_MATHJAX_LOCATION_FULL_OPTION_LINE
"MATHJAX_RELPATH = ${CGAL_DOC_MATHJAX_LOCATION}")
else()
set(CGAL_DOC_MATHJAX_LOCATION
"https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.2")
endif()

set(CGAL_DOC_OUTPUT_DIR "${CMAKE_BINARY_DIR}/doc_output")
file(MAKE_DIRECTORY "${CGAL_DOC_OUTPUT_DIR}")

option(
CGAL_DOC_CREATE_LOGS
"Write log files or print warnings and errors to cerr when building the doc."
OFF)

if(CGAL_DOC_CREATE_LOGS)
set(CGAL_DOC_LOG_DIR "${CMAKE_BINARY_DIR}/doc_log")
file(MAKE_DIRECTORY "${CGAL_DOC_LOG_DIR}")
endif()

option(CGAL_EXTRACT_ALL_NO_DETAILED_IF_EMPTY
"Use CGAL special doxygen setting EXTRACT_ALL_NO_DETAILED_IF_EMPTY." ON)
if(CGAL_EXTRACT_ALL_NO_DETAILED_IF_EMPTY)
set(CGAL_OPT_EXTRACT_ALL_NO_DETAILED_IF_EMPTY
"EXTRACT_ALL_NO_DETAILED_IF_EMPTY = YES")
else()

The default is NO, so we could leave it out, but it is better to have a commented out placeholder

this will work for versions with and without the setting.

set(CGAL_OPT_EXTRACT_ALL_NO_DETAILED_IF_EMPTY
"#EXTRACT_ALL_NO_DETAILED_IF_EMPTY = NO")
endif()

option(CGAL_NO_ADDITIONAL_DETAILS
"Use CGAL special doxygen setting NO_ADDITIONAL_DETAILS." ON)
if(CGAL_NO_ADDITIONAL_DETAILS)
set(CGAL_OPT_NO_ADDITIONAL_DETAILS
"NO_ADDITIONAL_DETAILS = YES")
else()

The default is NO, so we could leave it out, but it is better to have a commented out placeholder

this will work for versions with and without the setting.

set(CGAL_OPT_NO_ADDITIONAL_DETAILS
"#NO_ADDITIONAL_DETAILS = NO")
endif()

#we use two directories for the generation/reading of tag files to prevent issues
#if the targets are built in parallel
set(CGAL_DOC_TAG_GEN_DIR "${CMAKE_BINARY_DIR}/doc_gen_tags")
file(MAKE_DIRECTORY "${CGAL_DOC_TAG_GEN_DIR}")
set(CGAL_DOC_TAG_DIR "${CMAKE_BINARY_DIR}/doc_tags")
file(MAKE_DIRECTORY "${CGAL_DOC_TAG_DIR}")
set(CGAL_DOC_DXY_DIR "${CMAKE_BINARY_DIR}/doc_dxy")
file(MAKE_DIRECTORY "${CGAL_DOC_DXY_DIR}")

#Setting the resource directory depending on the version of doxygen
set(CGAL_DOC_RESOURCE_PREFIX_DIR "${CMAKE_CURRENT_LIST_DIR}/resources")

first look if resources for the specific doxygen version is available, fallback

on the default otherwise

#select only the version number (not the commit hash)
string(REPLACE " " ";" DOXYGEN_VERSION ${DOXYGEN_VERSION})
list(GET DOXYGEN_VERSION 0 DOXYGEN_VERSION)
message(VERBOSE "Doxygen version ${DOXYGEN_VERSION}: ${DOXYGEN_EXECUTABLE}")

The Doxygen version is search in that sorted list (to find the index for which the version is less or equal)

set(CGAL_DOXYGEN_RESOURCES_VERSIONS 1.9.6 1.14.0)
list(SORT CGAL_DOXYGEN_RESOURCES_VERSIONS COMPARE NATURAL)

The GLOB is here to check that the list in CGAL_DOXYGEN_RESOURCES_VERSIONS is correct.

CGAL_DOXYGEN_RESOURCES_DIRS is also used below.

file(GLOB CGAL_DOXYGEN_RESOURCES_DIRS
RELATIVE "${CGAL_DOC_RESOURCE_PREFIX_DIR}"
"${CGAL_DOC_RESOURCE_PREFIX_DIR}/*")
list(SORT CGAL_DOXYGEN_RESOURCES_DIRS COMPARE NATURAL)

if(NOT CGAL_DOXYGEN_RESOURCES_DIRS STREQUAL CGAL_DOXYGEN_RESOURCES_VERSIONS)
message(WARNING "The directories in ${CGAL_DOC_RESOURCE_PREFIX_DIR} do not match the expected versions:\n"
" [${CGAL_DOXYGEN_RESOURCES_DIRS}] vs [${CGAL_DOXYGEN_RESOURCES_VERSIONS}]")
endif()

function(CGAL_insert_in_sorted_list list_name value)
set(list ${${list_name}})
if(NOT value IN_LIST list)
list(APPEND list "${value}")
list(SORT list COMPARE NATURAL)
endif()
set(${list_name} ${list} PARENT_SCOPE)
endfunction()

if(DOXYGEN_VERSION IN_LIST CGAL_DOXYGEN_RESOURCES_DIRS)
list(FIND CGAL_DOXYGEN_RESOURCES_DIRS "${DOXYGEN_VERSION}" DOXYGEN_VERSION_INDEX)
else()
CGAL_insert_in_sorted_list(CGAL_DOXYGEN_RESOURCES_DIRS ${DOXYGEN_VERSION})
list(FIND CGAL_DOXYGEN_RESOURCES_DIRS ${DOXYGEN_VERSION} DOXYGEN_VERSION_INDEX)
math(EXPR DOXYGEN_VERSION_INDEX "${DOXYGEN_VERSION_INDEX} - 1")
endif()
list(GET CGAL_DOXYGEN_RESOURCES_DIRS "${DOXYGEN_VERSION_INDEX}" CGAL_DOC_RESOURCE_DIR)

set(CGAL_DOC_RESOURCE_DIR "${CGAL_DOC_RESOURCE_PREFIX_DIR}/${CGAL_DOC_RESOURCE_DIR}")
if(NOT EXISTS "${CGAL_DOC_RESOURCE_DIR}")
message(FATAL_ERROR "Doxygen resources for version ${DOXYGEN_VERSION} not found")
else()
message(VERBOSE "Using Doxygen resources from ${CGAL_DOC_RESOURCE_DIR}")
endif()

set(CGAL_DOC_BIBLIO_DIR "${CMAKE_CURRENT_LIST_DIR}/biblio")
set(CGAL_DOC_SCRIPT_DIR "${CMAKE_CURRENT_LIST_DIR}/scripts")

set(CGAL_DOC_HEADER ${CGAL_DOC_DXY_DIR}/header.html)
configure_file(${CGAL_DOC_RESOURCE_DIR}/header.html ${CGAL_DOC_HEADER} @ONLY)
set(CGAL_DOC_HEADER_PACKAGE ${CGAL_DOC_DXY_DIR}/header_package.html)
configure_file(${CGAL_DOC_RESOURCE_DIR}/header_package.html
${CGAL_DOC_HEADER_PACKAGE} @ONLY)

#Generate the bibtex file
#this is needed also for BaseDoxyfile.in
string(TIMESTAMP CGAL_BUILD_YEAR4 "%Y")
string(TIMESTAMP CGAL_BUILD_YEAR2 "%y")
string(TIMESTAMP CGAL_BUILD_MONTH "%m")

if(${CGAL_BUILD_MONTH} GREATER 6)
set(CGAL_RELEASE_YEAR_ID "${CGAL_BUILD_YEAR2}b")
else()
set(CGAL_RELEASE_YEAR_ID "${CGAL_BUILD_YEAR2}a")
endif()

if(NOT CGAL_CREATED_VERSION_NUM)
if(CGAL_BRANCH_BUILD)
include(${CGAL_ROOT}/CGALConfigVersion.cmake)

text
# Prefer the public release version (e.g. "6.0-beta1") which includes
# pre-release suffixes; fall back to computing from components when it
# is not available (issue #8322).
if(CGAL_VERSION_PUBLIC_RELEASE_VERSION)
  set(CGAL_CREATED_VERSION_NUM "${CGAL_VERSION_PUBLIC_RELEASE_VERSION}")
elseif(CGAL_BUGFIX_VERSION AND CGAL_BUGFIX_VERSION GREATER 0)
  set(CGAL_CREATED_VERSION_NUM
      "${CGAL_MAJOR_VERSION}.${CGAL_MINOR_VERSION}.${CGAL_BUGFIX_VERSION}")
else()
  set(CGAL_CREATED_VERSION_NUM
      "${CGAL_MAJOR_VERSION}.${CGAL_MINOR_VERSION}")
endif()

else()
if(EXISTS "${CGAL_ROOT}/doc/public_release_name")
file(STRINGS "${CGAL_ROOT}/doc/public_release_name" CGAL_VERSION_LINE)
string(REGEX REPLACE "CGAL-" "" CGAL_CREATED_VERSION_NUM
"${CGAL_VERSION_LINE}")
else()
#read version.h and get the line with CGAL_VERSION
file(STRINGS "${CGAL_ROOT}/include/CGAL/version.h" CGAL_VERSION_LINE
REGEX "CGAL_VERSION ")
#extract release id, including any pre-release suffix like -beta1, -dev,
#or multi-segment ids such as -Ic-33
string(REGEX MATCH "[0-9]+\.[0-9]+(\.[0-9]+)?(-[a-zA-Z0-9]+)*" CGAL_CREATED_VERSION_NUM
"${CGAL_VERSION_LINE}")
endif()
endif()
endif()

Introduce our own version variable. This way we avoid tying this too

closely to the convoluted versioning code and can adapt without a

huge diff.

set(CGAL_DOC_VERSION ${CGAL_CREATED_VERSION_NUM})

generate how_to_cite files

execute_process(
COMMAND ${Python3_EXECUTABLE} ${CGAL_DOC_SCRIPT_DIR}/generate_how_to_cite.py
${CGAL_ROOT} ${CMAKE_BINARY_DIR} "${CGAL_BRANCH_BUILD}"
RESULT_VARIABLE GENERATE_HOW_TO_CITE_RESULT)
if(NOT GENERATE_HOW_TO_CITE_RESULT EQUAL "0")
message(FATAL_ERROR "generate_how_to_cite did not exit correctly")
endif()

configure_file(${CMAKE_BINARY_DIR}/how_to_cite_cgal.bib.in
${CMAKE_BINARY_DIR}/how_to_cite_cgal.bib)
configure_file(${CMAKE_BINARY_DIR}/how_to_cite_cgal.txt.in
${CMAKE_BINARY_DIR}/how_to_cite_cgal.txt)
configure_file(${CMAKE_BINARY_DIR}/how_to_cite.html.in
${CMAKE_BINARY_DIR}/how_to_cite.html)

configure_file(${CGAL_DOC_RESOURCE_DIR}/BaseDoxyfile.in
${CGAL_DOC_DXY_DIR}/BaseDoxyfile)

set(CGAL_DOC_DOXY_DEFAULT "${CGAL_DOC_DXY_DIR}/BaseDoxyfile")

if (BE_QUIET)
file(APPEND ${CGAL_DOC_DOXY_DEFAULT} "WARN_LOGFILE=doxygen.log\n")
endif()

pkglist_filter gets the path to the pkglist_filter of this source

directory.

if(WIN32)
configure_file(${CGAL_DOC_SCRIPT_DIR}/pkglist_filter.bat
${CMAKE_BINARY_DIR}/pkglist_filter.bat)
endif()
configure_file(${CGAL_DOC_SCRIPT_DIR}/pkglist_filter
${CMAKE_BINARY_DIR}/pkglist_filter)
configure_file(${CGAL_DOC_SCRIPT_DIR}/pkglist_filter.py
${CMAKE_BINARY_DIR}/pkglist_filter.py)

set(CGAL_DOC_PACKAGES "")
if(CGAL_BRANCH_BUILD)
file(
GLOB CGAL_ALL_PACKAGES
RELATIVE ${CGAL_ROOT}
"${CGAL_ROOT}/*")
foreach(pkg ${CGAL_ALL_PACKAGES})
#detect packages with documentation to process
if(IS_DIRECTORY ${CGAL_ROOT}/${pkg})
if(EXISTS "${CGAL_ROOT}/${pkg}/doc/${pkg}/PackageDescription.txt")
list(APPEND CGAL_DOC_PACKAGES ${pkg})
endif()
endif()
#set up directories of packages
if(IS_DIRECTORY ${CGAL_ROOT}/${pkg}/examples)
set(CGAL_${pkg}EXAMPLE_DIR "${CGAL_ROOT}/${pkg}/examples")
endif()
if(IS_DIRECTORY ${CGAL_ROOT}/${pkg}/include)
set(CGAL
${pkg}INCLUDE_DIR "${CGAL_ROOT}/${pkg}/include")
endif()
if(IS_DIRECTORY ${CGAL_ROOT}/${pkg}/demo)
set(CGAL
${pkg}_DEMO_DIR "${CGAL_ROOT}/${pkg}/demo")
endif()
endforeach()
else()
subdirlist(CGAL_DOC_PACKAGES_TMP ${CGAL_ROOT}/doc)
set(CGAL_DOC_PACKAGES)
foreach(package ${CGAL_DOC_PACKAGES_TMP})
if(EXISTS "${CGAL_ROOT}/doc/${package}/PackageDescription.txt")
list(APPEND CGAL_DOC_PACKAGES "${package}")
endif()
endforeach()

subdirlist(CGAL_EXAMPLE_PACKAGES ${CGAL_ROOT}/examples)
subdirlist(CGAL_DEMO_PACKAGES ${CGAL_ROOT}/demo)
list(APPEND CGAL_EXAMPLE_PACKAGES "BGL"
)# manually add BGL to the list of packages
foreach(pkg ${CGAL_EXAMPLE_PACKAGES})
set(CGAL_${pkg}EXAMPLE_DIR "${CGAL_ROOT}/examples")
# This might not be entirely correct, but there is no reliable,
# easy way to get a list of all package names when not in a
# branch build.
set(CGAL
${pkg}INCLUDE_DIR "${CGAL_ROOT}/include")
endforeach()
foreach(pkg ${CGAL_DEMO_PACKAGES})
set(CGAL
${pkg}_DEMO_DIR "${CGAL_ROOT}/demo")
endforeach()
endif()

#special cases
if(NOT CGAL_BRANCH_BUILD)
foreach(pkg "Mesher_level" "Surface_mesh_decomposition")
set(CGAL_${pkg}_INCLUDE_DIR "${CGAL_ROOT}/include")
endforeach()
endif()

option(CGAL_BUILD_THREE_DOC "Build the documentation of the Three package" OFF)

if(NOT CGAL_BUILD_THREE_DOC)
list(REMOVE_ITEM CGAL_DOC_PACKAGES "Three")
endif()

foreach(package ${CGAL_DOC_PACKAGES})
configure_doxygen_package(${package})
endforeach()

Add a custom target "doc"

add_custom_target(doc)
add_custom_target(doc_pre)
add_custom_target(doc_post)

do the main package manually, it isn't part of ${CGAL_CONFIGURED_PACKAGES_NAMES}

configure_doxygen_package("Documentation")
set_target_properties(Documentation_doc PROPERTIES FOLDER Documentation)

hard-code that doc depends on all packages

foreach(depend ${CGAL_DOC_PACKAGES})
add_dependencies(doc_pre ${depend}_internal_doxygen_run)
add_dependencies(doc_post ${depend}_copy_doc_tags)
add_dependencies(${depend}_copy_doc_tags doc_pre)
endforeach()
add_dependencies(doc_pre Documentation_internal_doxygen_run)
add_dependencies(doc_post Documentation_copy_doc_tags)
add_dependencies(Documentation_copy_doc_tags doc_pre)

#total level doc dependencies
add_dependencies(doc doc_post)

set(CGAL_DOC_TESTSUITE_SCRIPT "${CGAL_DOC_SCRIPT_DIR}/testsuite.py")

add_custom_target(
doc_with_postprocessing
${Python3_EXECUTABLE} ${CGAL_DOC_SCRIPT_DIR}/html_output_post_processing.py
--output ${CGAL_DOC_OUTPUT_DIR} --resources ${CGAL_DOC_RESOURCE_DIR})
add_dependencies(doc_with_postprocessing doc)

if(CGAL_DOC_CREATE_LOGS)
add_custom_target(
Documentation_test
${Python3_EXECUTABLE} ${CGAL_DOC_TESTSUITE_SCRIPT} --output-dir
${CGAL_DOC_OUTPUT_DIR} --doc-log-dir ${CGAL_DOC_LOG_DIR})
add_dependencies(Documentation_test doc)

add_custom_target(
Documentation_test_publish
${Python3_EXECUTABLE}
${CGAL_DOC_TESTSUITE_SCRIPT}
--output-dir
${CGAL_DOC_OUTPUT_DIR}
--doc-log-dir
${CGAL_DOC_LOG_DIR}
--publish
${CGAL_DOC_PUBLISH_DIR}
--do-copy-results)
add_dependencies(Documentation_test_publish doc)

add_custom_target(
doc_and_publish_testsuite
${Python3_EXECUTABLE}
${CGAL_DOC_TESTSUITE_SCRIPT}
--output-dir
${CGAL_DOC_OUTPUT_DIR}
--doc-log-dir
${CGAL_DOC_LOG_DIR}
--publish
${CGAL_DOC_PUBLISH_DIR}
--do-copy-results
--cgal-version
"${CGAL_FULL_VERSION}"
--version-to-keep
10)
add_dependencies(doc_and_publish_testsuite doc_with_postprocessing)

endif()


AABB Tree Doc AABB Tree PackageDescription (`AABB_tree/doc/AABB_tree/PackageDescription.txt`)

/// \defgroup PkgAABBTreeRef Reference Manual

/// \defgroup PkgAABBTreeConcepts Concepts
/// \ingroup PkgAABBTreeRef

/*!
\addtogroup PkgAABBTreeRef
\cgalPkgDescriptionBegin{2D and 3D Fast Intersection and Distance Computation,PkgAABBTree}
\cgalPkgPicture{aabb-teaser-thumb.png}
\cgalPkgSummaryBegin
\cgalPkgAuthors{Pierre Alliez, Stéphane Tayeb, and Camille Wormser}
\cgalPkgDesc{The AABB (axis-aligned bounding box) tree component offers a static data structure and algorithms to perform efficient intersection and distance queries on sets of finite 2D and 3D geometric objects.}
\cgalPkgManuals{Chapter_Fast_Intersection_and_Distance_Computation,PkgAABBTreeRef}
\cgalPkgSummaryEnd
\cgalPkgShortInfoBegin
\cgalPkgSince{3.5}
\cgalPkgBib{cgal:atw-aabb}
\cgalPkgLicense{\ref licensesGPL "GPL"}
\cgalPkgDemo{AABB Tree,AABB_demo.zip}
\cgalPkgShortInfoEnd
\cgalPkgDescriptionEnd

\cgalClassifedRefPages

\cgalCRPSection{Concepts}

  • AABBPrimitive
  • AABBPrimitiveWithSharedData
  • AABBGeomTraits_2
  • AABBGeomTraits_3
  • AABBTraits
  • AABBRayIntersectionGeomTraits_2
  • AABBRayIntersectionGeomTraits_3
  • AABBRayIntersectionTraits

\cgalCRPSection{Classes}

  • CGAL::AABB_traits<GeomTraits,Primitive> (deprecated, use CGAL::AABB_traits_3<GeomTraits,Primitive>)
  • CGAL::AABB_traits_2<GeomTraits,Primitive>
  • CGAL::AABB_traits_3<GeomTraits,Primitive>
  • CGAL::AABB_tree<AT>

\cgalCRPSection{Primitives}

  • CGAL::AABB_triangle_primitive_2<GeomTraits, Iterator, CacheDatum>
  • CGAL::AABB_indexed_triangle_primitive_2<GeomTraits, IndexIterator, PointRange, CacheDatum, PointMap>
  • CGAL::AABB_segment_primitive_2<GeomTraits, Iterator, CacheDatum>
  • CGAL::AABB_polyline_segment_primitive_2<GeomTraits, Iterator, PointRange, CacheDatum, PointMap>
  • CGAL::AABB_triangle_primitive<GeomTraits, Iterator, CacheDatum> (deprecated, use CGAL::AABB_triangle_primitive_3<GeomTraits, Iterator, CacheDatum>)
  • CGAL::AABB_triangle_primitive_3<GeomTraits, Iterator, CacheDatum>
  • CGAL::AABB_segment_primitive<GeomTraits, Iterator, CacheDatum> (deprecated, use CGAL::AABB_segment_primitive_3<GeomTraits, Iterator, CacheDatum>)
  • CGAL::AABB_segment_primitive_3<GeomTraits, Iterator, CacheDatum>
  • CGAL::AABB_primitive
  • CGAL::AABB_halfedge_graph_segment_primitive<HalfedgeGraph,Vpm,OneHalfedgeGraphPerTree,CacheDatum>
  • CGAL::AABB_face_graph_triangle_primitive<FaceGraph,Vpm,OneFaceGraphPerTree,CacheDatum>

\cgalCRPSection{Functions}

  • CGAL::AABB_trees::do_intersect()
  • CGAL::AABB_trees::all_pairs_of_intersecting_primitives()
    */

AABB Tree Doc AABB Tree Aabb Tree (`AABB_tree/doc/AABB_tree/aabb_tree.txt`)

namespace CGAL {

/*!

\mainpage User Manual
\anchor Chapter_Fast_Intersection_and_Distance_Computation
\cgalAutoToc

\authors Pierre Alliez, Stephane Tayeb, and Camille Wormser

\section aabb_tree_introduction Introduction

The AABB tree component offers a static data structure and algorithms
to perform efficient intersection and distance queries against sets of
finite 2D or 3D geometric objects. The set of geometric objects stored in
the data structure can be queried for intersection detection,
intersection computation and distance. The intersection queries can be
of any type, provided that the corresponding intersection predicates
and constructors are implemented in the traits class. The distance
queries are limited to point queries. Examples of intersection queries
include line objects (rays, lines, segments) against sets of
triangles, or plane objects (planes, triangles) against sets of
segments. An example of a distance query consists of finding the
closest point from a point query to a set of triangles.

Similarly to the package \ref PkgBoxIntersectionD,
this component might also be used for finding all intersecting pairs of objects,
and can even achieve a better performance when running on several threads.

The AABB tree data structure takes as input an iterator range of
geometric data, which is then converted into primitives. From these
primitives a hierarchy of axis-aligned bounding boxes (AABBs) is
constructed and used to speed up intersection and distance queries.
Each primitive gives access to both one input geometric object
(so-called datum) and one reference id to this object. A typical
example primitive wraps a 3D triangle as datum and a face handle of a
polyhedral surface as id. Each intersection query can return the
intersection objects (e.g., 3D points or segments for ray queries) as
well as the id (here the face handle) of the intersected
primitives. Similarly, each distance query can return the closest
point from the point query as well as the id of the closest primitive.

\cgalFigureBegin{aabbtree_meca,anchor.png}
Left: surface triangle mesh of a mechanical part. Right: AABB tree constructed.
\cgalFigureEnd

\section aabb_tree_interface Interface

The main entry point to the component is the class AABB_tree
which represents a static AABB tree constructed from an iterator range
of geometric data. Once instantiated an AABB tree can be queried for
intersection and distance queries.

\b Intersections. Assume for example that the tree contains triangle
primitives. The tree can be queried for intersection against line
objects (rays, segments or line) in various ways. We distinguish
intersection tests which do not construct any intersection
objects, from intersections which construct the intersection
objects.

Tests:

  • Function AABB_tree::do_intersect() tests if the input primitives are
    intersected by the query. This function is fast as it involves only
    predicates and stops after the first encountered intersection.
  • Function AABB_tree::number_of_intersected_primitives() counts all
    intersected primitives.
  • Function AABB_tree::all_intersected_primitives() enumerates all intersected
    primitives ids without constructing the corresponding intersection
    objects.
  • Function AABB_tree::any_intersected_primitive() returns the first
    encountered intersecting primitive id (if any) without constructing
    the corresponding intersection object, and stops after the first
    encountered intersection. Note that the traversal order of the tree is
    such that first herein does not refer to any particular ordering of
    the intersections with respect to the query.
  • Function AABB_tree::first_intersected_primitive() returns
    the intersecting primitive id (if any) of the corresponding
    intersection object that is closest to the source of the ray.

Constructions:

  • Function AABB_tree::all_intersections() detects and constructs all
    intersection objects with the input primitives.
  • Function AABB_tree::any_intersection() detects and constructs the first
    encountered intersection and constructs the corresponding object. This
    function is fast as it stops after the first encountered intersection.
  • Function AABB_tree::first_intersection() detects and constructs
    the intersection object that is closest to the source of the ray.

\b Distance. An AABB tree computes the closest point from a
given point query to the input primitives through the function
AABB_tree::closest_point(). In addition, it can compute the id of the
closest primitive from a given point query through the function
AABB_tree::closest_point_and_primitive(), i.e., the id of the
primitive which realizes the minimum distance from the point
query. The AABB tree uses a secondary search structure to speed up the
distance queries. The construction of this secondary structure should
be requested by the user by a call to
AABB_tree::accelerate_distance_queries() before the first the distance
computation. This data structure is not generated by default because
it is used only for distance computations.

\warning Having degenerate primitives in the AABB-tree is not recommended as the underlying
predicates and constructions of the traits class might not be able to handle them.
For example if one is using CGAL::AABB_traits with a Kernel from \cgal,
having degenerate triangles or segments in the AABB-tree will result in an undefined
behavior or a crash.

\section two_aabb_tree_interface Operations between Two AABB Trees

Given two AABB trees, the function CGAL::AABB_trees::do_intersect() determines whether any
primitive of the first tree intersects a primitive of the second tree.
To enumerate all intersecting pairs of primitives, use CGAL::AABB_trees::all_pairs_of_intersecting_primitives().

These functions provide an alternative to CGAL::box_intersection_d(). In practice, CGAL::AABB_trees::all_pairs_of_intersecting_primitives() generally provides better performance,
particularly when using a parallel execution tag (see \ref aabb_tree_perf).

Note that compared to CGAL::box_intersection_d(), the tree of primitives is actually constructed. It becomes even more interesting in term of runtime
if several calls to the aforementioned intersection functions are done with the same tree.

\section aabb_tree_examples Examples

\subsection aabb_tree_examples_1 Tree of Triangles, for Intersection and Distance Queries

In the following example a set of 3D triangles is stored in a
list. The AABB primitive wraps a triangle as datum and an
iterator in the list as id. We compute the number of input
triangles intersected by a ray query, as well as the closest point and
the squared distance from a point query.

\cgalExample{AABB_tree/AABB_triangle_3_example.cpp}

\subsection aabb_tree_examples_2 Tree of Polyhedron Triangle Facets for Intersection Queries

In the following example the AABB primitive wraps a facet handle of a
triangle polyhedral surface as id and the corresponding 3D
triangle as geometric object. From a segment query we test the
intersections, then compute the number of intersections, compute the
first encountered intersection (generally a point), compute all
intersections (where each intersection is a pair of one \cgal object
and one primitive id - here a face handle) and compute all intersected
primitives. The latter involves only tests and no predicates and is
hence faster than computing all intersections. We also compute the
first encountered intersection with a plane query, which is generally
a segment. We finally compute the first intersection along a ray.

\cgalExample{AABB_tree/AABB_polyhedron_facet_intersection_example.cpp}

\subsection aabb_ray_shooting Ray Shooting

In the following example we load a closed polyhedral surface and perform a
ray shooting query from the centroid of each face, orthogonally to the face
towards the interior. As the centroid is computed with floating point
arithmetic the first face hit by the ray may be the face of the centroid.
The skip functor takes care of ignoring the face.

\cgalExample{AABB_tree/AABB_ray_shooting_example.cpp}

\subsection aabb_tree_examples_3 Tree of Polyhedron Triangle Facets for Distance Queries

In the following example the AABB primitive wraps a facet handle of a
triangle polyhedral surface as id and the corresponding 3D
triangle as geometric object. From a point query we compute the
squared distance, the closest point as well as the closest point and
primitive id. The latter returns a pair composed of a point and a face
handle.

\cgalExample{AABB_tree/AABB_polyhedron_facet_distance_example.cpp}

\subsection aabb_tree_examples_4 Tree of Segments for Intersection and Distance Queries

In the following example the segments are stored into a list, and the
AABB primitive wraps a segment as datum and an iterator in the
list as id. We compute the number of intersections with plane
and triangles queries, and the closest point from a point query.
\cgalExample{AABB_tree/AABB_segment_3_example.cpp}

\subsection aabb_tree_examples_8 Tree of Polyline and Polygon Segments for Intersection and Distance Queries

The following example uses segments given by a polyline and a polygon. The difference is that the polygon is closed. The id in this case is the iterator pointing to a Point_2 in the polyline or the polygon. The datum, a Segment_2, is created on the fly from the points using the id as the source and the following Point_2 as the target. We count the intersections with a Segment_2 and the closest point and id from a point query.
\cgalExample{AABB_tree/AABB_polyline_segment_2_example.cpp}

\subsection aabb_tree_examples_5 Tree of Polyhedron Edge Segments for Intersection and Distance Queries

In the following example the AABB primitive wraps a halfedge handle as
id and generates a 3D segment on the fly, each time its method
datum is called. We compute the number of intersections with a
triangle query and the closest point from a point query.
\cgalExample{AABB_tree/AABB_polyhedron_edge_example.cpp}

\subsection aabb_tree_examples_6 Incremental Insertion of Primitives

The AABB tree is a static data structure, but it allows to insert
primitives, and will internally rebuild triggered by the first query,
or because the user calls the AABB_tree::build() method. The following
example illustrates this for two polyhedral surfaces.

\cgalExample{AABB_tree/AABB_insertion_example.cpp}

\subsection aabb_tree_examples_7 Trees of Custom Primitives

The AABB tree example folder contains three examples of trees
constructed with custom primitives. In \ref AABB_tree/AABB_custom_example.cpp "AABB_custom_example.cpp"
the primitive contains triangles which are defined by three pointers
to custom points. In \ref AABB_tree/AABB_custom_triangle_soup_example.cpp "AABB_custom_triangle_soup_example.cpp" all input
triangles are stored into a single array as to form a triangle
soup. The primitive internally uses a boost::iterator_adaptor
as to provide the three functions AABBPrimitive::id(), AABBPrimitive::datum(),
and AABBPrimitive::reference_point() required by the primitive concept. In
\ref AABB_tree/AABB_custom_indexed_triangle_set_example.cpp "AABB_custom_indexed_triangle_set_example.cpp" the input is an indexed
triangle set stored through two arrays: one array of points and one
array of indices which refer to the point array. Here also the
primitive internally uses a boost::iterator_adaptor.

\subsection aabb_tree_examples_9 Intersection of Two Trees

In the following example, we compute all the intersections between two triangle soups both representing a tetrahedron. The triangle soups
are stored as a vector of Triangle_3. We first compute if the tetrahedra do intersect and then we
compute the indices of the intersecting triangles.

\cgalExample{AABB_tree/AABB_intersection_example.cpp}

\section aabb_tree_perf Performances

We provide some performance numbers for the case where the AABB tree
contains a set of polyhedron triangle facets. We measure the tree
construction time, the memory occupancy and the number of queries per
second for a variety of intersection and distance queries. The machine
used is a PC running Linux Mint with an Intel CPU Core Ultra 7 155H with 16 cores and 32GB of RAM.
By default, the kernel used is Simple_cartesian<double> (the fastest in our experiments). The
program has been compiled with the compiler gcc 13.3 2023 with the O3
option which maximizes speed.

\subsection aabb_tree_perf_cons Construction

The surface triangle mesh chosen for benchmarking the tree
construction is the knot model (14,400 triangles) depicted by
\cgalFigureRef{figAABB-tree-bench}. We measure the tree construction time (both
AABB tree alone and AABB tree with internal KD-tree) for four denser versions of the knot model.

Number of triangles Construction (in ms) (Parallel) (Sequential) Construction with internal KD-tree (in ms) (Parallel) (Sequential)
230,400 20 36 48 66
921,600 72 187 155 306
3,686,400 292 816 729 1426
14,745,600 1,425 4,196 3,028 7,016

\subsection aabb_tree_perf_mem Memory

When using the polyhedron triangle facet primitive (defined in
CGAL/AABB_face_graph_triangle_primitive.h) the AABB tree occupies
approximately 61 bytes per primitive (without constructing the
internal KD-tree). It increases to approximately 150 bytes per
primitive when constructing the internal KD-tree with one reference
point per primitive (the default mode when calling the function
AABB_tree::accelerate_distance_queries()). Note that the polyhedron
facet primitive stores only one facet handle as primitive id
and computes on the fly a 3D triangle from the facet handle stored
internally. When explicitly storing a 3D triangle in the primitive the
tree occupies approximately 140 bytes per primitive instead of 60
(without constructing the internal KD-tree).

The following table provides orders of memory occupancy in MBytes for
an increasing number of triangles. As the internal KD-tree used to
accelerate the distance queries dominates the memory occupancy, we
recommend to specify for large models a lower number of reference
point (evenly distributed) to construct the internal KD-tree through
the function AABB_tree::accelerate_distance_queries() which
takes an iterator range as input.

Number of triangles AABB tree (in MBytes) AABB tree with internal KD-tree (in MBytes)
18,400 1.10 2.76
102,400 6.33 14.73
1,022,400 59.56 151.31
1,822,400 108.34 291.84

\subsection aabb_tree_perf_inter Intersections

The following table measures the number of intersection queries per
second on one core on the 14,400 triangle version of the knot mesh model for ray,
line, segment and plane queries. Each ray query is generated by
choosing a random source point within the mesh bounding box and a
random vector. A line or segment query is generated by choosing two
random points inside the bounding box. A plane query is generated by
picking a random point inside the bounding box and a random normal
vector. Note that a plane query generally intersects many triangles of
the input surface mesh. This explains the low performance numbers for
the intersection functions which enumerate all intersections.

Function Segment Ray Line Plane
AABB_tree::do_intersect() 513,505 788,246 773,947 1,863,721
AABB_tree::any_intersected_primitive() 521,651 852,929 831,919 2,125,582
AABB_tree::any_intersection() 504,836 835,164 821,369 1,730,017
AABB_tree::number_of_intersected_primitives() 186,102 397,069 210,052 49,941
AABB_tree::all_intersected_primitives() 178,769 397,458 192,482 49,324
AABB_tree::all_intersections() 178,536 352,541 193,700 21,745

Curve of \cgalFigureRef{figAABB-tree-bench} plots the number of queries per second
(here the AABB_tree::all_intersections() function with random segment
queries) against the number of input triangles for the knot triangle
surface mesh.

\cgalFigureBegin{figAABB-tree-bench,bench.png, knot.png}
Number of queries per second against number of triangles for the knot model with 14K (shown) to 15M triangles. We call the all_intersections() function with segment queries randomly chosen within the bounding box.
\cgalFigureEnd

The following table measures the number of AABB_tree::all_intersections()
queries per second against several kernels. We use the 14,400 triangle
version of the knot mesh model for random segment queries.

Kernel Queries/s (all_intersections() with segment queries)
Simple_cartesian<double> 201,618
Simple_cartesian<float> 193,414
Cartesian<double> 164,784
Cartesian<float> 159,686
Exact_predicates_inexact_constructions_kernel 119,590

\subsection aabb_tree_perf_dist Distances

The surface triangle mesh chosen for benchmarking distances is again
the knot model in six increasing resolutions. In the following table we first measure the tree
construction time (which includes the construction of the internal
KD-tree data structure used to accelerate the distance queries by up
to one order of magnitude in our experiments). We then measure the
number of queries per second for the three types distance queries
(AABB_tree::closest_point(), AABB_tree::squared_distance() and
AABB_tree::closest_point_and_primitive()) from point queries randomly chosen
inside the bounding box.

Nb triangles Closest_point() Squared_distance() Closest_point_and_primitive()
14,400 196,043 196,356 196,708
57,600 123,388 123,844 123,567
230,400 54,480 53,235 54,329
921,600 25,761 26,890 25,386
3,686,400 13,696 13,389 13,440
14,745,600 7,158 6,913 7,010

\subsection aabb_two_trees_perf Intersection of Two AABB Trees

We test the intersection of two AABB trees using 3 models: two common models of mesh processing (Iphigenia and Nefertiti), and twisted knot to maximize the number of intersection. For each model,
we test their intersection with a translated version of themselves (Note: We do not exploit the fact that it is the same model, the tree is built twice).
We compare here CGAL::AABB_trees::all_pairs_of_intersecting_primitives() and CGAL::box_intersection_d().

\cgalFigureBegin{figAABB-tree-model,iphigenia.png, nefertiti.png, twisted_knot.png}
The three input models used to illustrate AABB trees intersection performance. Iphigenia (left), Nefertiti (center), Twisted knot (right).
\cgalFigureEnd

| Models | Nb Triangles | Nb Intersections | AABB | Tree (ms) | | | Box d || AABB | Tree Seq. | (ms) | | Box d Seq. |
| ----: | ----: | ----: | ----: | ----: | ----: | ----: | ----: || ----: | ----: | ----: | ----: | ----: |
| | | | Build | Do intersect | All pairs | All pairs + Build | || Build | Do intersect | All pairs | All pairs + Build | |
| Iphigenia × Iphigenia Tr. | 703,512 × 703,512 | 47,677 | 91 | <0.1 | 37 | 128 | 424 || 318 | <0.1 | 169 | 488 | 868 |
| Nefertiti × Nefertiti Tr. | 2,018,232 × 2,018,232 | 14,246 | 261 | <0.1 | 10 | 271 | 1,006 ||1,087 | <0.1 | 46 | 1,134 | 2,348 |
| Twisted knot × Twisted knot Rot. | 600,000 × 600,000 | 240,144 | 154 | <0.1 | 57 | 211 | 850 || 541 | <0.1 | 440 | 981 | 2,993 |

\subsection aabb_tree_perf_summary Summary

The experiments described above are neither exhaustive nor conclusive
as we have chosen one specific case where the input primitives are the
facets of a triangle surface polyhedron. Nevertheless, we now provide
some general observations and advises about how to put the AABB tree
to use with satisfactory performances. While the tree construction
times and memory occupancy do not fluctuate much in our experiments
depending on the input surface triangle mesh, the performance
expressed in number of queries varies greatly depending on a complex
combination of criteria: type of kernel, number of input primitives,
distribution of primitives in space, type of function queried, type of
query and location of query in space.

  • %Kernel: The type of \cgal kernel turns out to dominate the final
    execution times, the maximum performances being obtained with the
    Simple_cartesian kernel parameterized with the double precision
    number type. In applications where the intersection and distance
    execution times are crucial it is possible to use this kernel for
    the AABB tree in combination with a more robust kernel for the main
    data structure.

  • Primitives: Although the number of input primitives plays an obvious
    role in the final performance, their distribution in space is at
    least equally important in order to obtain a well-balanced AABB
    tree. Ideally the primitives must be evenly distributed in space and
    the long primitives spanning the bounding box of the tree root node
    must be avoided as much as possible. It is often beneficial to split
    these long primitives into smaller ones before constructing the
    tree, e.g., through recursive longest edge bisection for triangle
    surface meshes.

  • Function: The type of function queried plays another important
    role. Obviously the exhaustive functions, which list all
    intersections, are slower than the ones stopping after the first
    intersection. Within each of these functions the ones which call
    only intersection tests (AABB_tree::do_intersect(),
    AABB_tree::number_of_intersected_primitives(),
    AABB_tree::any_intersected_primitive(), AABB_tree::all_intersected_primitives()) are
    faster than the ones which explicitly construct the intersections
    (AABB_tree::any_intersection() and AABB_tree::all_intersections()).

  • Query: The type of query (e.g., line, ray, segment or plane used
    above) plays another role, strongly correlated with the type of
    function (exhaustive or not, and whether or not it constructs the
    intersections). When all intersection constructions are needed, the
    final execution times highly depend on the complexity of the general
    intersection object. For example a plane query generally intersects
    a surface triangle mesh into many segments while a segment query
    generally intersects a surface triangle mesh into few
    points. Finally, the location of the query in space also plays an
    obvious role in the performances, especially for the distance
    queries. Assuming the internal KD-tree constructed through the
    function AABB_tree::accelerate_distance_queries(), it is preferable
    to specify a query point already close to the surface triangle mesh
    so that the query traverses only few AABBs of the tree. For a large
    number of primitive data (greater than 2M faces in our experiments)
    however we noticed that it is not necessary (and sometimes even
    slower) to use all reference points when constructing the
    KD-tree. In these cases we recommend to specify through the function
    AABB_tree::accelerate_distance_queries() fewer reference
    points (typically not more than 100K) evenly distributed over the
    input primitives.

\section aabb_tree_impl Implementation Details

The AABB tree construction is initialized by computing the AABB of the
whole set of input primitives. All primitives are then sorted along
the longest coordinate axis of this box, and the primitives are
separated into two equal size sets. This procedure is applied
recursively until an AABB contains a single primitive. The tree is
leafless as presented in OPCODE \cgalCite{cgal:t-ocdl-05}. An
intersection query traverses the tree by computing intersection tests
only with respect to the AABBs during traversal, and with respect to
the input primitives at the end of traversal (in the leafs of the
tree).

The reference id is not used internally but simply used by the AABB
tree to refer to the primitive in the results provided to the user. It
follows that, while in most cases each reference id corresponds to a
unique primitive, this is not a requirement of the component. This way
a user may use these reference ids as labels, each of them being
shared by several geometric objects.

A distance query between a query point q and the input primitives is
turned into a ball query centered at q. The ball traverses the
tree while recursively querying intersections with the AABBs, and
computes the closest point p from the query point to the input
primitives at the leafs of the tree. The ball radius is then shrunk to
the distance between p and q for all remaining recursive
traversals of the tree. Efficiency is achieved through setting the
initial ball radius to a small value still guaranteed to intersect the
input primitives. This is achieved by constructing an internal secondary data
structure which provides a good hint to the algorithm at the beginning
of the traversal (done by default).
Calling AABB_tree::do_not_accelerate_distance_queries() will disable
the construction and the usage of this internal secondary data structure.

\section aabb_tree_history Design and Implementation History

Camille Wormser and Pierre Alliez started working on a data structure
for efficient collision detection in 2007. The generic design for
implementing both intersection and distance queries, and for generic
queries and primitives was developed by Camille Wormser. In 2009,
Pierre Alliez, Stéphane Tayeb and Camille Wormser made the
implementation CGAL-compliant, with the help of Laurent Rineau for
optimizing the tree construction. Additionally, Andreas
Fabri, Jane Tournois, Mariette Yvinec and Sylvain Lefèbvre are
given thanks for helpful comments and discussions during that period.
Later, Sébastien Loriot contributed several improvements:
thread-safe queries, introduction of shared data stored in the traits
for lighter primitive types, ...
In 2024, the package was made compatible with 2D and 3D primitives by
Andreas Fabri, Sébastien Loriot, and Sven Oesau.
In 2026, the package was extended to support the intersection of two AABB trees.
This work also introduced performance optimizations and parallelization, contributed by Leo Valque.

*/

}


AABB Tree Doc AABB Tree Examples (`AABB_tree/doc/AABB_tree/examples.txt`)

/*!
\example AABB_tree/AABB_custom_example.cpp
\example AABB_tree/AABB_custom_indexed_triangle_set_array_example.cpp
\example AABB_tree/AABB_custom_indexed_triangle_set_example.cpp
\example AABB_tree/AABB_custom_triangle_soup_example.cpp
\example AABB_tree/AABB_insertion_example.cpp
\example AABB_tree/AABB_polyhedron_edge_example.cpp
\example AABB_tree/AABB_polyhedron_facet_distance_example.cpp
\example AABB_tree/AABB_polyhedron_facet_intersection_example.cpp
\example AABB_tree/AABB_polyline_segment_2_example.cpp
\example AABB_tree/AABB_segment_3_example.cpp
\example AABB_tree/AABB_segment_2_example.cpp
\example AABB_tree/AABB_ray_shooting_example.cpp
\example AABB_tree/AABB_indexed_triangle_2_example.cpp
\example AABB_tree/AABB_triangle_2_example.cpp
\example AABB_tree/AABB_triangle_3_example.cpp
\example AABB_tree/AABB_halfedge_graph_edge_example.cpp
\example AABB_tree/AABB_face_graph_triangle_example.cpp
\example AABB_tree/AABB_intersection_example.cpp
*/


Advancing Front Surface Reconstruction Doc Advancing Front Surface Reconstruction Advancing Front Surface Reconstruction (`Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Advancing_front_surface_reconstruction.txt`)

namespace CGAL {
/*!

\mainpage User Manual
\anchor Chapter_Advancing_Front_Surface_Reconstruction
\anchor I1ChapterAdvancingFrontSurfaceReconstruction
\cgalAutoToc
\author Tran Kai Frank Da and David Cohen-Steiner

Surface reconstruction from an unstructured point cloud amounts to
generate a plausible surface that approximates well the input
points. This problem is ill-posed as many surfaces can be generated. A
wide range of approaches have been proposed to tackle this
problem. Among them are variational methods
\cgalCite{s-lsm-96}\cgalCite{zomk-insru-00}, tensor voting
\cgalCite{cgal:ml-cfsg-00}, implicit surface
\cgalCite{hddhjmss-pssr-94}\cgalCite{bc-ssrnn-00}, and Delaunay
triangulations.

For Delaunay based algorithms the output surface is commonly generated
as the union of some triangles selected in the 3D Delaunay
triangulation of the input points. Such algorithms are either
volume-based by generating as output the boundary of selected
tetrahedra \cgalCite{abe-cbscc-97}\cgalCite{ack-pcubm-01},
or surface-based by selecting a set of triangles.

In most surface based Delaunay algorithms the triangles are
selected independently, that is in parallel \cgalCite{agj-lcsr-00}\cgalCite{ab-srvf-98}.

This chapter presents a surface-based Delaunay surface
reconstruction algorithm that sequentially selects the triangles, that
is it uses previously selected triangles to select a new triangle for
advancing the front. At each advancing step the most plausible
triangle is selected, and such that the triangles selected
generates an orientable manifold triangulated surface.

Two other examples of this greedy approach are the ball pivoting
algorithm and Boyer-Petitjean's algorithm \cgalCite{bmrst-bpasr-99}\cgalCite{pb-rnrps-01}. In both algorithms
a triangulated surface is incrementally grown starting from a seed
triangle. Ball pivoting is fast, but the quality of the reconstruction
depends on user defined parameters corresponding to the sampling
density. The Boyer-Petitjean approach can handle non-uniform sampling,
but fails when near co-circular points are encountered, and it does
not provide any guarantee on the topology of the surface.

We describe next the algorithm and provide examples.

\note A \ref tuto_reconstruction "detailed tutorial on surface reconstruction"
is provided with a guide to choose the most appropriate method along
with pre- and postprocessing.

\section AFSR_Definitions Definitions and the Algorithm

A detailed description of the algorithm and the underlying theory are provided
in \cgalCite{cgal:csd-gdbsra-04}.

The first step of the algorithm is the construction of a 3D Delaunay
triangulation of the point set.
The radius of a triangle \f$ t \f$ is the radius of the smallest sphere
passing through the vertices of \f$ t\f$ and enclosing no sample
point. In other words, the radius \f$ r_t\f$ is the distance from any
vertex of \f$ t\f$ to the Voronoi edge dual to \f$ t\f$. This triangle with
three boundary edges is the initial triangulated surface, and its
boundary is the advancing front.
The Delaunay triangle with the smallest radius is the starting point
for the greedy algorithm.

The algorithm maintains a priority queue of candidate triangles, that
is of valid triangles incident to the boundary edges of the current
surface. The priority is the plausibility. While the priority queue is
not empty, the algorithm pops from the queue the most plausible
candidate triangle and adds it to the surface. New candidate triangles
are pushed to the priority queue when new boundary edges appear on the
advancing front. As the algorithm creates a two-manifold surface some
candidate triangles can not be selected due to topological constraints
which are explained next.

\subsection AFSR_Topology Topological Constraints

Any triangle \f$t\f$ considered as the next potential candidate shares an
edge \f$e\f$ with the front of the current reconstruction. Let \f$b\f$
be the vertex of \f$t\f$ opposite to \f$e\f$. There are four
configurations where \f$t\f$ is added to the surface.

  • extension, if \f$b\f$ is not yet on the surface.
  • hole filling, if \f$b\f$ is on the front and both neighbors of \f$b\f$ on the front are on edge \f$e\f$.
  • ear filling, if \f$b\f$ is on the front and one neighbor of \f$b\f$ on the front is on edge \f$e\f$.
  • glueing, if \f$b\f$ is on the front and no neighbor of \f$b\f$ on the front is on edge \f$e\f$.

\cgalFigureBegin{figAFSRvalid,valid.png}
Valid candidates.
\cgalFigureEnd

While the first three operations never induce a non-manifold edge or vertex,
we only can perform gluing, if triangle \f$t\f$ has a twin facet, that is a
triangle with an edge on the front and incident to \f$b\f$, and the
third vertex on edge \f$e\f$.

A triangle is said valid when the above operations can be applied.

\subsection AFSR_Selection Plausibility of a Candidate Triangle

Valid triangles for an edge on the front are compared through their
radius. While the radius is a good criterion in the case of 2D smooth
curve reconstruction \cgalCite{b-cccda-94}, we need another criterion
for 3D surface reconstruction, namely the dihedral angle between
triangles on the surface, that is the angle between the normals of the
triangles. There are three bounds namely \f$ \alpha_\mathrm{sliver} \f$,
\f$ \beta \f$, and \f$ \delta \f$.

The candidate triangle of an edge \f$ e \f$ is the triangle
with the smallest radius:

  • that is valid for \f$ e \f$, and
  • that has \f$ \beta_t < \alpha_\mathrm{sliver} \f$, and
  • that has its internal angles with \f$ e \f$ smaller than \f$ \delta \f$.

There may be no such triangle. In the implementation
of the algorithm \f$ \alpha_\mathrm{sliver} \f$ and \f$ \delta\f$ are equal
to \f$ 5\pi/6 \f$.

We denote by \f$ \beta_t\f$ the angle between the normal of a triangle
\f$ t\f$ incident on a boundary edge \f$ e \f$ and the normal of the
triangle on the surface incident to \f$ e \f$.

We define the plausibility grade \f$ p(t) \f$ as \f$ 1/r_t \f$, if
\f$ \beta_t < \beta \f$, and \f$ -\beta_t \f$ else. The parameter \f$
\beta \f$ can be specified by the user and is set by default to \f$ \pi/6\f$.

Let's have a look at the figure below.
\cgalFigureBegin{figAFSRplausible,wedges.png}
Plausibility. Triangle t' and incident triangles sharing edge e seen from the side.
\cgalFigureEnd

\f$ \alpha_\mathrm{sliver}\f$ corresponds to the red wedge. The algorithm will never select triangle t1
even if it is the only candidate triangle.

\f$\beta\f$ corresponds to the green wedge. If there is a candidate triangle in this zone,
the one with the smallest radius is the most plausible.

If there is no candidate triangle in the green wedge, the triangle with the smallest
angle between its normal and the normal of t' is chosen. In the figure above
this would be triangle t4.

\subsection AFSR_Boundaries Dealing with Multiple Components, Boundaries and Sharp Edges

By construction the output of the algorithm is a connected orientable
manifold with or without boundary. To cope with multiple components we
merely look for a new seed facet among facets disjoint from the
surface. In case of noisy data or outliers, the user must filter out
small surface components.

It is impossible to handle all kinds of boundaries and non uniform sampling
at the same time, as a void can either be an undersampled area of the surface,
or a hole.

As we do not want the algorithm to rely on a uniformity condition on
the sampling it will fill holes cut off from "flat" regions of the
surface. However, in many cases a boundary component cannot be closed
by adding a spanning disk such that the resulting disk is well
sampled. Typically, closing a boundary component due to a transversal
clipping of the operation, would yield large dihedral angles at
boundary edges. Moreover, if the boundary is sufficiently well
sampled, the radii of the two triangles incident on a boundary edge
would be very different. These heuristic facts can be used for
boundary detection.

More specifically, we discard any candidate triangle \f$ t \f$, for an edge \f$ e \f$
such that \f$ p(t) < 0\f$, and \f$ r_t > \mathrm{radius_ratio_bound} \times r_{t'}\f$ where \f$ t'\f$ is
the triangle on the surface incident on \f$ e \f$. The parameter \f$\mathrm{radius_ratio_bound}\f$
is specified by the user and is set by default to 5.

For the example given in \cgalFigureRef{figAFSRplausible}, we said that if there
was no triangle t3 in the green wedge, triangle t4 would be chosen as it has
the smallest angle between its normal and the normal of triangle t'.
However, in case its radius was \f$\mathrm{radius_ratio_bound}\f$ times larger than the radius of triangle t',
triangle t2 would be chosen, assuming that its radius is not \f$\mathrm{radius_ratio_bound}\f$ times larger.

Note that this heuristic implies that
where the sampling is too sparse with respect to curvature, it must
be sufficiently uniform for our algorithm to work.

\section AFSR_Examples Examples

The first of the following three examples presents a free function for doing surface
reconstruction. For a sequence of points the function produces a sequence
of triplets of indices describing the triangles of the surface.
The second example presents a class that enables to traverse the
surface represented in a 2D triangulation data structure where
the faces are connected with the facets of underlying 3D Delaunay triangulation.
The third example shows how to get outliers and the boundaries of
the surface. The last example shows how to combine this algorithm with
two \cgal algorithms in order to reconstruct surfaces with sharp
features.

\subsection AFSR_Example_function Examples for Global Function

The global function advancing_front_surface_reconstruction()
takes an iterator range of points as input and writes for each face of the
reconstructed surface a triplet of point indices into an output iterator.
The following example writes the output triangulated surface to std::cout
in accordance to the OFF format.

The function has an overload with an additional argument that allows
to choose how to prioritize facets. It can be written in a way to
avoid the generation of triangles with a perimeter larger than a given
bound.

\cgalExample{Advancing_front_surface_reconstruction/reconstruction_fct.cpp}

While the first example just writes index triples, the second example
uses as output iterator a wrapper around a reference to a Surface_mesh
and calls the function add_face().

\cgalExample{Advancing_front_surface_reconstruction/reconstruction_surface_mesh.cpp}

\subsection AFSR_Example_class Example for the Reconstruction Class

The class Advancing_front_surface_reconstruction provides
access to a 2D triangulation data structure describing the output surface.
The latter can be explored by hopping from a face to its neighboring faces,
and by hopping from faces of the 2D triangulation data structure to
corresponding facets of the underlying 3D Delaunay triangulation.

The type of the 2D triangulation data structure describing the
reconstructed surface is the nested type
\link Advancing_front_surface_reconstruction::Triangulation_data_structure_2 Advancing_front_surface_reconstruction::Triangulation_data_structure_2\endlink.

The type Advancing_front_surface_reconstruction::Triangulation_data_structure_2::Vertex is model of the
concept TriangulationDataStructure_2::Vertex and has additionally
the method vertex_3() that returns an Advancing_front_surface_reconstruction::Vertex_handle to the
associated 3D vertex.

The type Advancing_front_surface_reconstruction::Triangulation_data_structure_2::Face is model of the concept
TriangulationDataStructure_2::Face and has additionally the method
facet() that returns the associated Advancing_front_surface_reconstruction::Facet,
and a method is_on_surface() for testing if a face is part of the reconstructed
surface.

In case the surface
has boundaries, the 2D surface has one vertex which is associated to
the infinite vertex of the 3D triangulation.

The underlying 3D Delaunay triangulation can be accessed as well,
using the API of the class Delaunay_triangulation_3.

The following example writes the surface to std::cout in accordance
to the STL (Stereo Lithography) format.

\cgalExample{Advancing_front_surface_reconstruction/reconstruction_class.cpp}

\subsection AFSR_Example_boundaries Example for Outliers and Boundaries

Input points which are not on
a surface are outliers. The member function \link Advancing_front_surface_reconstruction::outliers() outliers()\endlink
returns an iterator range of those points.

Boundary edges can be traversed with the member function \link Advancing_front_surface_reconstruction::boundaries() boundaries()\endlink
It returns an iterator range type \link Advancing_front_surface_reconstruction::Boundary_range Boundary_range\endlink whose iterators have the value type
\link Advancing_front_surface_reconstruction::Vertex_on_boundary_range Vertex_on_boundary_range\endlink. This is again an iterator range whose iterators have the value type
\link Advancing_front_surface_reconstruction::Vertex_handle Vertex_handle\endlink.

\cgalExample{Advancing_front_surface_reconstruction/boundaries.cpp}

\subsection AFSR_Example_sharp_features Example for Sharp Features

The priority queue used by the advancing front surface reconstruction
algorithm can be modified to achieve robustness to sharp edges and
provide piecewise-planar or hybrid reconstruction as described in
\cgalCite{cgal:la-srpss-13}. Two other algorithms available in \cgal
must be applied first as a preprocessing to the point set:

  • \ref Chapter_Shape_Detection "Shape detection": detect planar sections of the input.

  • \ref Point_set_processing_3Structuring "Point set structuring":
    resample the planar sections and edges and corners detected among
    them.

\cgalFigureBegin{figAFSRstruct,structured_example.png}
Comparison of advancing front output.

  • Top: input point set and raw advancing front reconstruction

  • Bottom: structured point set and advancing front reconstruction with
    structure-dependent priority functor

\cgalFigureEnd

The quality of the reconstruction can be significantly improved thanks
to point set structuring when dealing with shapes with sharp features,
as shown on the previous figure. The following example shows how to
define a priority functor that favors structurally coherent facets and
makes the advancing front algorithm robust to sharp features.

\cgalExample{Advancing_front_surface_reconstruction/reconstruction_structured.cpp}

/
} /
namespace CGAL */


Advancing Front Surface Reconstruction Doc Advancing Front Surface Reconstruction PackageDescription (`Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/PackageDescription.txt`)

/// \defgroup PkgAdvancingFrontSurfaceReconstructionRef Reference Manual

/// \defgroup PkgAdvancingFrontSurfaceReconstructionRefConcepts Concepts
/// \ingroup PkgAdvancingFrontSurfaceReconstructionRef

/*!
\addtogroup PkgAdvancingFrontSurfaceReconstructionRef

\cgalPkgDescriptionBegin{Advancing Front Surface Reconstruction,PkgAdvancingFrontSurfaceReconstruction}
\cgalPkgPicture{afsr-detail.png}
\cgalPkgSummaryBegin
\cgalPkgAuthors{Tran Kai Frank Da and David Cohen-Steiner}
\cgalPkgDesc{This package provides a greedy algorithm for surface reconstruction from an
unorganized point set. Starting from a seed facet, a piecewise linear
surface is grown by adding Delaunay triangles one by one. The most
plausible triangles are added first, in a way that avoids the appearance
of topological singularities. }
\cgalPkgManuals{Chapter_Advancing_Front_Surface_Reconstruction,PkgAdvancingFrontSurfaceReconstructionRef}
\cgalPkgSummaryEnd
\cgalPkgShortInfoBegin
\cgalPkgSince{4.7}
\cgalPkgDependsOn{\ref PkgTriangulation3}
\cgalPkgBib{cgal:dc-afsr}
\cgalPkgLicense{\ref licensesGPL "GPL"}
\cgalPkgShortInfoEnd
\cgalPkgDescriptionEnd

\cgalClassifedRefPages

\cgalCRPSection{Concepts}

  • AdvancingFrontSurfaceReconstructionTraits_3

\cgalCRPSection{Classes}

  • CGAL::Advancing_front_surface_reconstruction
  • CGAL::Advancing_front_surface_reconstruction_vertex_base_3
  • CGAL::Advancing_front_surface_reconstruction_cell_base_3

\cgalCRPSection{Functions}

  • CGAL::advancing_front_surface_reconstruction()

*/


Advancing Front Surface Reconstruction Doc Advancing Front Surface Reconstruction Examples (`Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/examples.txt`)

/*!
\example Advancing_front_surface_reconstruction/reconstruction_fct.cpp
\example Advancing_front_surface_reconstruction/reconstruction_class.cpp
\example Advancing_front_surface_reconstruction/reconstruction_surface_mesh.cpp
\example Advancing_front_surface_reconstruction/boundaries.cpp
\example Advancing_front_surface_reconstruction/reconstruction_structured.cpp
*/


Algebraic Foundations Doc Algebraic Foundations Algebraic Foundations (`Algebraic_foundations/doc/Algebraic_foundations/Algebraic_foundations.txt`)

namespace CGAL {
/*!

\mainpage User Manual
\anchor Chapter_Algebraic_Foundations

\cgalAutoToc
\author Michael Hemmer

\section Algebraic_foundationsIntroduction Introduction

\cgal is targeting towards exact computation with non-linear objects,
in particular objects defined on algebraic curves and surfaces.
As a consequence types representing polynomials, algebraic extensions and
finite fields play a more important role in related implementations.
This package has been introduced to stay abreast of these changes.
Since in particular polynomials must be supported by the introduced framework
the package avoids the term number type. Instead, the package distinguishes
between the algebraic structure of a type and whether a type is embeddable on
the real axis, or real embeddable for short.
Moreover, the package introduces the notion of interoperable types which
allows an explicit handling of mixed operations.

\section Algebraic_foundationsAlgebraic Algebraic Structures

The algebraic structure concepts introduced within this section are
motivated by their well-known counterparts in traditional algebra,
but we also had to pay tribute to existing types and their restrictions.
To keep the interface minimal,
it was not desirable to cover all known algebraic structures,
e.g., we did not introduce concepts for such basic structures as groups or
exceptional structures as skew fields.

\cgalFigureBegin{figConceptHierarchyOfAlgebraicStructures,AlgebraicConceptHierarchy.png}
Concept Hierarchy of Algebraic Structures
\cgalFigureEnd

\cgalFigureRef{figConceptHierarchyOfAlgebraicStructures} shows the refinement
relationship of the algebraic structure concepts.
IntegralDomain, UniqueFactorizationDomain, EuclideanRing and
Field correspond to the algebraic structures with the
same name. FieldWithSqrt, FieldWithKthRoot and
FieldWithRootOf are fields that in addition are closed under
the operations 'sqrt', 'k-th root' and 'real root of a polynomial',
respectively. The concept IntegralDomainWithoutDivision also
corresponds to integral domains in the algebraic sense, the
distinction results from the fact that some implementations of
integral domains lack the (algebraically always well-defined) integral
division.
Note that Field refines IntegralDomain. This is because
most ring-theoretic notions like greatest common divisors become trivial for
Fields. Hence, we see Field as a refinement of
IntegralDomain and not as a
refinement of one of the more advanced ring concepts.
If an algorithm wants to rely on gcd or remainder computation, it is trying
to do things it should not do with a Field in the first place.

The main properties of an algebraic structure are collected in the class
Algebraic_structure_traits.
In particular the (most refined) concept each concrete model AS
fulfills is encoded in the tag
\link AlgebraicStructureTraits::Algebraic_category Algebraic_structure_traits<AS>::Algebraic_category \endlink .
An algebraic structure is at least Assignable,
CopyConstructible, DefaultConstructible and
EqualityComparable. Moreover, we require that it is
constructible from int.
For ease of use and since their semantic is sufficiently standard to presume
their existence, the usual arithmetic and comparison operators are required
to be realized via \cpp operator overloading.
The division operator is reserved for division in fields.
All other unary (e.g., sqrt) and binary functions
(e.g., gcd, div) must be models of the well-known \stl-concepts
AdaptableUnaryFunction or AdaptableBinaryFunction
concept and local to the traits class
(e.g., \link AlgebraicStructureTraits::Sqrt Algebraic_structure_traits<AS>::Sqrt()(x) \endlink).
This design allows us to profit from all parts in the
\stl and its programming style and avoids the name-lookup and
two-pass template compilation problems experienced with the old design
using overloaded functions. However, for ease of use and backward
compatibility all functionality is also
accessible through global functions defined within namespace CGAL,
e.g., \link sqrt CGAL::sqrt(x) \endlink. This is realized via function templates using
the according functor of the traits class. For an overview see the section "Global Functions" in the
\ref PkgAlgebraicFoundationsRef.

\subsection Algebraic_foundationsTagsinAlgebraicStructure Tags in Algebraic Structure Traits

\subsubsection Algebraic_foundationsAlgebraicCategory Algebraic Category

For a type AS, Algebraic_structure_traits<AS>
provides several tags. The most important tag is the Algebraic_category
tag, which indicates the most refined algebraic concept the type AS
fulfills. The tag is one of;
Integral_domain_without_division_tag, Integral_domain_tag,
Field_tag, Field_with_sqrt_tag, Field_with_kth_root_tag,
Field_with_root_of_tag, Unique_factorization_domain_tag,
Euclidean_ring_tag, or even Null_tag
in case the type is not a model of an algebraic structure concept.
The tags are derived from each other such that they reflect the
hierarchy of the algebraic structure concept, e.g.,
Field_with_sqrt_tag is derived from Field_tag.

\subsubsection Algebraic_foundationsExactandNumericalSensitive Exact and Numerical Sensitive

Moreover, Algebraic_structure_traits<AS> provides the tags Is_exact
and Is_numerical_sensitive, which are both Boolean_tags.

An algebraic structure is considered exact,
if all operations required by its concept are computed such that a comparison
of two algebraic expressions is always correct.

An algebraic structure is considered as numerically sensitive,
if the performance of the type is sensitive to the condition number of an
algorithm.
Note that there is really a difference among these two notions,
e.g., the fundamental type int is not numerical sensitive but
considered inexact due to overflow.
Conversely, types as leda_real or CORE::Expr are exact but sensitive
to numerical issues due to the internal use of multi precision floating point
arithmetic. We expect that Is_numerical_sensitive is used for dispatching
of algorithms, while Is_exact is useful to enable assertions that can be
checked for exact types only.

Tags are very useful to dispatch between alternative implementations.
The following example illustrates a dispatch for Fields using overloaded
functions. The example only needs two overloads since the algebraic
category tags reflect the algebraic structure hierarchy.

\cgalExample{Algebraic_foundations/algebraic_structure_dispatch.cpp}

\section Algebraic_foundationsRealE Real Embeddable

\anchor secRealEmbeddable

Most number types represent some subset of the real numbers. From those types
we expect functionality to compute the sign, absolute value or double
approximations. In particular, we can expect an order on such a type that
reflects the order along the real axis.
All these properties are gathered in the concept ::RealEmbeddable.
The concept is orthogonal to the algebraic structure concepts,
i.e., it is possible
that a type is a model of RealEmbeddable only,
since the type may just represent values on the real axis
but does not provide any arithmetic operations.

As for algebraic structures this concept is also traits class oriented.
The main functionality related to RealEmbeddable is gathered in
the class Real_embeddable_traits. In particular, it provides the boolean
tag Is_real_embeddable indicating whether a type is a model of
RealEmbeddable. The comparison operators are required to be realized via
\cpp operator overloading.
All unary functions (e.g. sign, to_double) and
binary functions (e.g. compare ) are models of the \stl-concepts
AdaptableUnaryFunction and AdaptableBinaryFunction and are local
to Real_embeddable_traits.

In case a type is a model of IntegralDomainWithoutDivision and
RealEmbeddable the number represented by an object of this type is
the same for arithmetic and comparison.
It follows that the ring represented by this type is a superset of the integers
and a subset of the real numbers and hence has characteristic zero.

In case the type is a model of Field and RealEmbeddable it is a
superset of the rational numbers.

\section Algebraic_foundationsRealN Real Number Types

Every \cgal Kernel comes with two real number types
(number types embeddable into the real numbers). One of them is a
FieldNumberType, and the other a RingNumberType. The
coordinates of the basic kernel objects (points, vectors, etc.) come
from one of these types (the FieldNumberType in case of %Cartesian
kernels, and the RingNumberType for %Homogeneous kernels).

The concept FieldNumberType combines the requirements of the
concepts Field and RealEmbeddable, while
RingNumberType combines IntegralDomainWithoutDivision and
RealEmbeddable. Algebraically, the real number types do not form
distinct structures and are therefore not listed in the concept
hierarchy of \cgalFigureRef{figConceptHierarchyOfAlgebraicStructures}.

\section Algebraic_foundationsInteroperability Interoperability

This section introduces two concepts for interoperability of types,
namely ImplicitInteroperable and ExplicitInteroperable. While
ExplicitInteroperable is the base concept, we start with
ImplicitInteroperable since it is the more intuitive one.

In general mixed operations are provided by overloaded operators and
functions or just via implicit constructor calls.
This level of interoperability is reflected by the concept
ImplicitInteroperable. However, within template code the result type,
or so-called coercion type, of a mixed arithmetic operation may be unclear.
Therefore, the package introduces Coercion_traits
giving access to the coercion type via \link Coercion_traits::Type Coercion_traits<A,B>::Type \endlink
for two interoperable types A and B.

Some trivial examples are int and double with coercion type double
or Gmpz and Gmpq with coercion type Gmpq.
However, the coercion type is not necessarily one of the input types,
e.g. the coercion type of a polynomial
with integer coefficients that is multiplied by a rational type
is supposed to be a polynomial with rational coefficients.

Coercion_traits is also
required to provide a functor \link Coercion_traits::Cast Coercion_traits<A,B>::Cast() \endlink, that
converts from an input type into the coercion type. This is in fact the core
of the more basic concept ExplicitInteroperable.
ExplicitInteroperable has been introduced to cover more complex cases
for which it is hard or impossible to guarantee implicit interoperability.
Note that this functor can be useful for ImplicitInteroperable types
as well, since it can be used to void redundant type conversions.

In case two types A and B are ExplicitInteroperable with
coercion type C they are valid argument types for all binary functors
provided by Algebraic_structure_traits and Real_embeddable_traits of
C. This is also true for the according global functions.

\subsection Algebraic_foundationsExamples Examples

The following example illustrates how two write code for
ExplicitInteroperable types.

\cgalExample{Algebraic_foundations/interoperable.cpp}

The following example illustrates a dispatch for ImplicitInteroperable and
ExplicitInteroperable types.
The binary function (that just multiplies its two arguments) is supposed to
take two ExplicitInteroperable arguments. For ImplicitInteroperable
types a variant that avoids the explicit cast is selected.

\cgalExample{Algebraic_foundations/implicit_interoperable_dispatch.cpp}

\section Algebraic_foundationsFractions Fractions

Beyond the need for performing algebraic operations on objects as a
whole, there are also number types which one would like to decompose into
numerator and denominator. This does not only hold for rational numbers
as Quotient, Gmpq, mpq_class or leda_rational, but
also for compound objects as Sqrt_extension or Polynomial
which may decompose into a (scalar)
denominator and a compound numerator with a simpler coefficient type
(e.g. integer instead of rational). Often operations can be performed faster on
these denominator-free multiples. In case a type is a Fraction
the relevant functionality as well as the numerator and denominator
type are provided by Fraction_traits. In particular
Fraction_traits provides a tag \link FractionTraits::Is_fraction Is_fraction \endlink that can be
used for dispatching.

A related class is Rational_traits which has been kept for backward
compatibility reasons. However, we recommend to use Fraction_traits since
it is more general and offers dispatching functionality.

\subsection Algebraic_foundationsExamples_1 Examples

The following example show a simple use of Fraction_traits:
\cgalExample{Algebraic_foundations/fraction_traits.cpp}

The following example illustrates the integralization of a vector,
i.e., the coefficient vector of a polynomial. Note that for minimizing
coefficient growth \link FractionTraits::Common_factor Fraction_traits<Type>::Common_factor \endlink is used to
compute the least common multiple of the denominators.

\cgalExample{Algebraic_foundations/integralize.cpp}

\section Algebraic_foundationsDesign Design and Implementation History

The package is part of \cgal since release 3.3. Of course the package is based
on the former Number type support of CGAL. This goes back to Stefan Schirra and Andreas Fabri. But on the other hand the package is to a large extend influenced
by the experience with the number type support in \exacus \cgalCite{beh-eeeafcs-05},
which in the main goes back to
Lutz Kettner, Susan Hert, Arno Eigenwillig, and Michael Hemmer.
However, the package abstracts from the pure support for
number types that are embedded on the real axis which allows the support of
polynomials, finite fields, and algebraic extensions as well. See also related
subsequent chapters.

/
} /
namespace CGAL */


Algebraic Foundations Doc Algebraic Foundations PackageDescription (`Algebraic_foundations/doc/Algebraic_foundations/PackageDescription.txt`)

/// \defgroup PkgAlgebraicFoundationsRef Reference Manual

/// \defgroup PkgAlgebraicFoundationsAlgebraicStructuresConcepts Concepts
/// \ingroup PkgAlgebraicFoundationsRef

/*!
\addtogroup PkgAlgebraicFoundationsRef

\cgalPkgDescriptionBegin{Algebraic Foundations,PkgAlgebraicFoundations}
\cgalPkgPicture{Algebraic_foundations2.png}
\cgalPkgSummaryBegin
\cgalPkgAuthor{Michael Hemmer}
\cgalPkgDesc{This package defines what algebra means for \cgal, in terms of concepts, classes and functions. The main features are: (i) explicit concepts for interoperability of types (ii) separation between algebraic types (not necessarily embeddable into the reals), and number types (embeddable into the reals).}
\cgalPkgManuals{Chapter_Algebraic_Foundations,PkgAlgebraicFoundationsRef}
\cgalPkgSummaryEnd
\cgalPkgShortInfoBegin
\cgalPkgSince{3.3}
\cgalPkgBib{cgal:h-af}
\cgalPkgLicense{\ref licensesLGPL "LGPL"}
\cgalPkgShortInfoEnd
\cgalPkgDescriptionEnd

\cgalClassifedRefPages

\cgalCRPSection{Algebraic Structures}

\cgalCRPSubsection{Concepts}

  • IntegralDomainWithoutDivision

  • IntegralDomain

  • UniqueFactorizationDomain

  • EuclideanRing

  • Field

  • FieldWithSqrt

  • FieldWithKthRoot

  • FieldWithRootOf

  • AlgebraicStructureTraits

  • AlgebraicStructureTraits_::IsZero

  • AlgebraicStructureTraits_::IsOne

  • AlgebraicStructureTraits_::Square

  • AlgebraicStructureTraits_::Simplify

  • AlgebraicStructureTraits_::UnitPart

  • AlgebraicStructureTraits_::IntegralDivision

  • AlgebraicStructureTraits_::Divides

  • AlgebraicStructureTraits_::Gcd

  • AlgebraicStructureTraits_::DivMod

  • AlgebraicStructureTraits_::Div

  • AlgebraicStructureTraits_::Mod

  • AlgebraicStructureTraits_::Inverse

  • AlgebraicStructureTraits_::Sqrt

  • AlgebraicStructureTraits_::IsSquare

  • AlgebraicStructureTraits_::KthRoot

  • AlgebraicStructureTraits_::RootOf

\cgalCRPSubsection{Classes}

  • CGAL::Algebraic_structure_traits<T>
  • CGAL::Integral_domain_without_division_tag
  • CGAL::Integral_domain_tag
  • CGAL::Field_tag
  • CGAL::Field_with_sqrt_tag
  • CGAL::Unique_factorization_domain_tag
  • CGAL::Euclidean_ring_tag

\cgalCRPSubsection{Global Functions}

  • CGAL::is_zero()
  • CGAL::is_one()
  • CGAL::square()
  • CGAL::simplify()
  • CGAL::unit_part()
  • CGAL::integral_division()
  • CGAL::is_square()
  • CGAL::gcd()
  • CGAL::div_mod()
  • CGAL::div()
  • CGAL::mod()
  • CGAL::inverse()
  • CGAL::sqrt()
  • CGAL::kth_root()
  • CGAL::root_of()

\cgalCRPSection{Real Embeddable}

\cgalCRPSubsection{Concepts}

  • RealEmbeddable

  • RealEmbeddableTraits

  • RealEmbeddableTraits_::IsZero

  • RealEmbeddableTraits_::Abs

  • RealEmbeddableTraits_::Sgn

  • RealEmbeddableTraits_::IsPositive

  • RealEmbeddableTraits_::IsNegative

  • RealEmbeddableTraits_::Compare

  • RealEmbeddableTraits_::ToDouble

  • RealEmbeddableTraits_::ToInterval

\cgalCRPSubsection{Classes}

  • CGAL::Real_embeddable_traits<T>

\cgalCRPSubsection{Global Functions}

  • CGAL::is_zero()
  • CGAL::abs()
  • CGAL::sign()
  • CGAL::is_positive()
  • CGAL::is_negative()
  • CGAL::compare()
  • CGAL::to_double()
  • CGAL::to_interval()

\cgalCRPSection{Real Number Types}

\cgalCRPSubsection{Concepts}

  • RingNumberType
  • FieldNumberType

\cgalCRPSection{Interoperability}

\cgalCRPSubsection{Concepts}

  • ExplicitInteroperable
  • ImplicitInteroperable

\cgalCRPSubsection{Classes}

  • CGAL::Coercion_traits<A,B>

\cgalCRPSection{Fractions}

\cgalCRPSubsection{Concepts}

  • Fraction
  • FractionTraits
  • FractionTraits_::Decompose
  • FractionTraits_::Compose
  • FractionTraits_::CommonFactor

\cgalCRPSubsection{Classes}

  • CGAL::Fraction_traits<T>

\cgalCRPSection{Miscellaneous}

\cgalCRPSubsection{Concepts}

  • FromIntConstructible
  • FromDoubleConstructible

*/


Algebraic Foundations Doc Algebraic Foundations Examples (`Algebraic_foundations/doc/Algebraic_foundations/examples.txt`)

/*!
\example Algebraic_foundations/algebraic_structure_dispatch.cpp
\example Algebraic_foundations/fraction_traits.cpp
\example Algebraic_foundations/implicit_interoperable_dispatch.cpp
\example Algebraic_foundations/integralize.cpp
\example Algebraic_foundations/interoperable.cpp
*/


Algebraic Kernel D Doc Algebraic Kernel D Algebraic Kernel D (`Algebraic_kernel_d/doc/Algebraic_kernel_d/Algebraic_kernel_d.txt`)

namespace CGAL {
/*!

\mainpage User Manual
\anchor Chapter_Algebraic_Kernel
\anchor chapteralgebraickerneld
\cgalAutoToc
\authors Eric Berberich, Michael Hemmer, Michael Kerber, Sylvain Lazard, Luis Peñaranda, and Monique Teillaud

\section Algebraic_kernel_dIntroduction Introduction

Real solving of polynomials is a fundamental problem with a wide application range.
This package provides black-box implementations of
algorithms to determine, compare, and approximate real roots of univariate polynomials
and bivariate polynomial systems. Such a black-box is called an Algebraic Kernel.
Since this package is aimed at providing more than one implementation, the interface of
the algebraic kernels is expressed in concepts. The main concepts provided by this package are the
AlgebraicKernel_d_1 for univariate polynomial systems and AlgebraicKernel_d_2
for bivariate polynomial systems, the latter being a refinement of the first.

\section Algebraic_kernel_dAlgebraic Algebraic Kernel Concepts

\subsection Algebraic_kernel_dUnivariateAlgebraicKernel Univariate Algebraic Kernel

\subsection Algebraic_kernel_dMajorTypes Major Types

First of all, the univariate algebraic kernel provides construction, comparison and
approximation of real roots of univariate polynomials.
Thus, the major public types the AlgebraicKernel_d_1 provides are:

AlgebraicKernel_d_1::Polynomial_1 - the type representing univariate polynomials,

AlgebraicKernel_d_1::Coefficient - the coefficient type of these polynomials,

AlgebraicKernel_d_1::Algebraic_real_1 - the type representing real roots,

AlgebraicKernel_d_1::Bound - the type which is used to approximate these algebraic reals,
in particular, it is used to represent the boundaries of isolating intervals.

\subsection Algebraic_kernel_dConstructionofAlgebraic Construction of Algebraic Real Numbers

The kernel provides two different function objects to construct an
AlgebraicKernel_d_1::Algebraic_real_1. The most general way
is to use AlgebraicKernel_d_1::Isolate_1; The function object
takes a univariate polynomial and writes all real roots into a given
output iterator. It is also possible to retrieve the multiplicity of
each root. The second option is to construct one particular algebraic
real using AlgebraicKernel_d_1::Construct_algebraic_real_1.
This function object provides construction from the native int type, the
coefficient type as well as the bound type. Moreover, it is possible
to construct an algebraic real by giving a polynomial and either an
isolating interval or the index of the root. A related function object
is AlgebraicKernel_d_1::Number_of_solutions_1 computing the number
of real roots of a polynomial.

\subsection Algebraic_kernel_dComparisonandApproximation Comparison and Approximation of Algebraic Real Numbers

An AlgebraicKernel_d_1::Algebraic_real_1 is model of
RealEmbeddable, for instance, it is possible to compare two
algebraic reals, to determine the sign of an algebraic real or to ask
for its double approximation, see also section \ref secRealEmbeddable.
Moreover, AlgebraicKernel_d_1::Compare_1 provides
comparison with int, the coefficient type and the bound type.

There are several ways to approximate an AlgebraicKernel_d_1::Algebraic_real_1:

AlgebraicKernel_d_1::Approximate_absolute_1 - provides an approximation that is
better than the passed absolute error bound,

AlgebraicKernel_d_1::Approximate_relative_1 - provides an approximation that is
better than the passed relative error bound,

AlgebraicKernel_d_1::Isolate_1 - returns an isolating interval with respect to
a given univariate polynomial,

A related function object is AlgebraicKernel_d_1::Bound_between_1, which computes
a number that isolates two algebraic real numbers.

\subsection Algebraic_kernel_dInterplaywithPolynomials Interplay with Polynomials

It is also possible to retrieve a representing polynomial from an
algebraic real using AlgebraicKernel_d_1::Compute_polynomial_1,
which guarantees that the algebraic real is a root of the returned
polynomial. As the name already indicates, this operation may be very
costly since the polynomial may not be computed yet. Moreover, it is
not guaranteed that the returned polynomial is the minimal polynomial
of the number. Together with AlgebraicKernel_d_1::Isolate_1, it
is possible to retrieve the traditional representation of an algebraic
real as a square free polynomial and an isolating interval.

Though the AlgebraicKernel_d_1 does not provide arithmetic
operations on AlgebraicKernel_d_1::Algebraic_real_1, it is
possible to compute the sign of a polynomial at a given algebraic
real using AlgebraicKernel_d_1::Sign_at_1. Or alternatively,
just compute whether the polynomial is zero at an algebraic real number
using AlgebraicKernel_d_1::Is_zero_at_1. Note that this operation
can be significantly less expensive, in particular if the polynomial
is not zero at the given algebraic real.

\subsection Algebraic_kernel_dAuxiliaryFunctionality Auxiliary Functionality for Polynomials

First of all the type AlgebraicKernel_d_1::Polynomial_1 is required
to be a model of the concept Polynomial_1, which is defined
in the Polynomial package (see chapter \ref Chapter_Polynomial).
This implies that all essential functionality is provided via
Polynomial_traits_d. However, the algebraic kernel also
provides several function objects to handle polynomials:

AlgebraicKernel_d_1::Is_square_free_1 - determines whether a polynomial is square free,

AlgebraicKernel_d_1::Make_square_free_1 - computes the square free part of a polynomial,

AlgebraicKernel_d_1::Square_free_factorize_1 - computes a square free factorization of a polynomial,

AlgebraicKernel_d_1::Is_coprime_1 - computes whether a pair of polynomials is square free,

AlgebraicKernel_d_1::Make_coprime_1 - decomposes two polynomials into the coprime factors and their common factor.

Though the polynomial package provides similar functionality we suggest to use
the function objects provided by the kernel, since the design of the algebraic kernel
allows for instance internal caching by the kernel.

Also note that AlgebraicKernel_d_1::Square_free_factorize_1 only computes the square free
factorization up to a constant factor. This is a slight modification with respect to its
counterpart in Polynomial_traits_d. In this way it was possible that the concepts just require
the coefficient type to be a model of IntegralDomain, instead of Field or UniqueFactorizationDomain.
For more details see also:

  • \ref PolynomialTraits_d::SquareFreeFactorize
  • \ref PolynomialTraits_d::SquareFreeFactorizeUpToConstantFactor

\subsection Algebraic_kernel_dDesignRationale Design Rationale

Most implementations of an AlgebraicKernel_d_1 will represent
an algebraic real number by the root of a square free polynomial and
an isolating interval, that is, the number is defined as the only
root of the polynomial within the interval. Usually, one will refrain
from computing the minimal polynomial since the computation of the
minimal polynomial is much more expensive and does not pay of. However,
besides the representation by a polynomial and an isolating interval
one can also imagine the representation by a polynomial and the index
of the root, e.g., as the \f$ i\f$th real root when enumerated from minus
to plus infinity. Moreover, it may very well be that the kernel just
computes an approximation of the number, whereas the representing
polynomial is not computed yet.
This is in particular relevant in relation to the AlgebraicKernel_d_2,
where AlgebraicKernel_d_1::Algebraic_real_1 is used to represent coordinates of solutions of bivariate systems.
Hence, the design does
not allow direct access to any, seemingly obvious, members of an
AlgebraicKernel_d_1::Algebraic_real_1. Instead, there is, e.g.,
AlgebraicKernel_d_1::Compute_polynomial_1 which emphasizes
that the requested polynomial may not be computed yet. Similarly,
there is no way to directly ask for the refinement of the current
isolating interval since this would impose a state to every object of
an AlgebraicKernel_d_1::Algebraic_real_1.

\subsection Algebraic_kernel_dBivariateAlgebraicKernel Bivariate Algebraic Kernel

The concept AlgebraicKernel_d_2 is a refinement of AlgebraicKernel_d_1,
that is, a model of AlgebraicKernel_d_2 is also a model of AlgebraicKernel_d_1.
Hence, the AlgebraicKernel_d_2 concept is designed such that occurring
names and functionalities are as similar as possible to those in the
AlgebraicKernel_d_1 concept.
The following are a direct generalization of their univariate counterparts:

AlgebraicKernel_d_2::Polynomial_2,

AlgebraicKernel_d_2::Algebraic_real_2,

AlgebraicKernel_d_2::Construct_algebraic_real_2,

AlgebraicKernel_d_2::Isolate_2,

AlgebraicKernel_d_2::Is_square_free_2,

AlgebraicKernel_d_2::Make_square_free_2,

AlgebraicKernel_d_2::Square_free_factorize_2,

AlgebraicKernel_d_2::Is_coprime_2,

AlgebraicKernel_d_2::Make_coprime_2,

AlgebraicKernel_d_2::Solve_2,

AlgebraicKernel_d_2::Number_of_solutions_2,

AlgebraicKernel_d_2::Compare_xy_2,

AlgebraicKernel_d_2::Sign_at_2,

AlgebraicKernel_d_2::Is_zero_at_2.

For instance, AlgebraicKernel_d_2::Solve_2
provides the solution for a bivariate polynomial system.
However, it is also possible to obtain the coordinates of these
solutions with the additional functors:

AlgebraicKernel_d_2::Compute_x_2,

AlgebraicKernel_d_2::Compute_y_2.

In principal this would be sufficient generalization,
since functions such as isolating, approximating algebraic real numbers
could be implemented using these access functions ant
the corresponding functionalities in the univariate algebraic kernel.
However, one should be aware that an AlgebraicKernel_d_2::Algebraic_real_2
is not necessarily represented as a pair of univariate solutions, that is,
using AlgebraicKernel_d_2::Compute_y_2 may entail considerable
computations. Therefore, the concept also requires the following
additional functors that may allow a model to bypass this issue:

AlgebraicKernel_d_2::Compute_polynomial_x_2,

AlgebraicKernel_d_2::Compute_polynomial_y_2,

AlgebraicKernel_d_2::Isolate_x_2,

AlgebraicKernel_d_2::Isolate_y_2,

AlgebraicKernel_d_2::Compare_x_2,

AlgebraicKernel_d_2::Compare_y_2,

AlgebraicKernel_d_2::Approximate_absolute_x_2,

AlgebraicKernel_d_2::Approximate_relative_x_2,

AlgebraicKernel_d_2::Approximate_absolute_y_2,

AlgebraicKernel_d_2::Approximate_relative_y_2,

AlgebraicKernel_d_2::Bound_between_x_2,

AlgebraicKernel_d_2::Bound_between_y_2.

\section Algebraic_kernel_dModels Models

\subsection Algebraic_kernel_dGenericAlgebraicKernels Generic Algebraic Kernels

The package provides generic models of the univariate and bivariate algebraic
kernel, namely Algebraic_kernel_d_1<Coeff> and Algebraic_kernel_d_2<Coeff>,
respectively. Both kernels support a large set of number types as their
template argument, which defines the supported coefficient type. The supported
types are, for instance, Gmpz and Gmpq as well as the corresponding types
of LEDA and CORE.

The Algebraic_kernel_d_1<Coeff> represents an algebraic real root by a square
free polynomial and an isolating interval that uniquely defines the root.
The current method to isolate roots is the Bitstream Descartes
method \cgalCite{eigenwillig-phd-08}.
The used method to refine the approximation of an algebraic real root is a
slightly modified (filtered) version of the one presented in \cgalCite{abbott-qir-06}.
The method has quadratic convergence.

Algebraic_kernel_d_2<Coeff> is based on an algorithm computing a
geometric-topological analysis of a single curve \cgalCite{ekw-fast-07} and of a
pair of curves \cgalCite{ek-exact-08}.
The main idea behind both analyses is to compute the critical
x-coordinates of curves and curve pairs by projection (resultants), and compute
additional information about the critical fibers using subresultants
and Sturm-Habicht sequences \cgalCite{grlr-sturm-habicht-98}.
With that information, the fiber at
critical x-coordinates is computed by a variant of the Bitstream
Descartes method.
See also \cgalCite{kerber-phd-09} for a comprehensive description of
these techniques.
Almost all functors in the class that take a Polynomial_2
object as argument trigger such an analysis as a main computation
step. For efficiency, these analyses (of single curves and curve
pairs) are therefore cached internally for efficiency. For instance,
computing the pairwise solutions of 10 Polynomial_2 objects
requires 10 curve analyses and 45 curve pair analyses to be computed
internally.

A point \f$ p\f$ of type Algebraic_real_2 is represented
by its \f$ x\f$-coordinate \f$ x_0\f$ (as described in the Algebraic_kernel_d_1
paragraph above), an algebraic curve where \f$ p\f$ lies on, and an
integer \f$ i\f$, denoting that \f$ p\f$ is the \f$ i\f$th point in the fiber at \f$ x_0\f$,
counted from the bottom (ignoring a possible vertical line at \f$ x_0\f$).
Note that this determines the point uniquely, but the \f$ y\f$-coordinate
is not stored internally in terms of an Algebraic_real_1 object.
Querying such a representation by calling Compute_y_2 is a
time-consuming step, and should be avoided for efficiency reasons if possible.

\section Algebraic_kernel_dExamples Examples

\subsection CGALAK1ConstructionExamples Construction of Algebraic Real Numbers

The following example illustrates the construction of AlgebraicKernel_d_1::Algebraic_real_1
using AlgebraicKernel_d_1::Construct_algebraic_real_1:
\cgalExample{Algebraic_kernel_d/Construct_algebraic_real_1.cpp}

\subsection CGALAK1Solving Solving Univariate Polynomials

The following example illustrates the construction of AlgebraicKernel_d_1::Algebraic_real_1
using AlgebraicKernel_d_1::Solve_1: \cgalExample{Algebraic_kernel_d/Solve_1.cpp}

\subsection CGALAK1EGCompare_1 Comparison and Approximation of Algebraic Real Numbers

The following example illustrates the comparison of AlgebraicKernel_d_1::Algebraic_real_1 numbers:
\cgalExample{Algebraic_kernel_d/Compare_1.cpp}

\subsection CGALAK1EGIsolate_1 Isolation of Algebraic Real Numbers with respect to roots of other polynomials

The following example illustrates the isolation of AlgebraicKernel_d_1::Algebraic_real_1 numbers:
\cgalExample{Algebraic_kernel_d/Isolate_1.cpp}

\subsection CGALAK1EGSign_at_1 Interplay with Polynomials

The following example illustrates the sign evaluation of AlgebraicKernel_d_1::Algebraic_real_1 numbers in polynomials:
\cgalExample{Algebraic_kernel_d/Sign_at_1.cpp}

\section Algebraic_kernel_dDesign Design and Implementation History

This package is clearly split into a univariate and bivariate
kernel. However, with respect to its history the package splits into
a design part and an implementation part.

The concepts, which make up the design part,
were written by Eric Berberich, Michael Hemmer, and
Monique Teillaud.
The design history of the package is fairly old and several
ideas that influenced this package can already be found
in \cgalCite{cgal:bhkt-risak-07}. Since then, the initial design underwent
considerable changes. For instance, it was decided that the algebraic
numbers should be under the control of the algebraic kernel. On the other
hand the initial support for polynomials was extended to a separate
and independent package that is not restricted to a certain number of
variables. Thus, the authors want to thank for all the useful feedback and
ideas that was brought to them throughout the last years. In particular,
they want to thank Menelaos Karavelas and Elias Tsigaridas for their
initial contributions.

The two generic models where initially developed as part of the \exacus \cgalCite{beh-eeeafcs-05} project.
However, the models are now fully integrated into the \cgal library,
since also the relevant layers of \exacus are now part of \cgal.
The main authors for Algebraic_kernel_d_1<Coeff> and Algebraic_kernel_d_2<Coeff> are
Michael Hemmer and Michael Kerber, respectively. Notwithstanding, the authors also want to emphasize the
contribution of all authors of the \exacus project,
particularly the contribution of Arno Eigenwillig, Sebastian Limbach and Pavel Emeliyanenko.

In 2010, two univariate kernels that interface the library RS \cgalCite{cgal:r-rs} were
written by Luis Peñaranda and Sylvain Lazard \cgalCite{cgal:2009-ESA}.
Both models interface the library RS \cgalCite{cgal:r-rs} by Fabrice Rouillier.
The authors want to thank Fabrice Rouillier and Elias Tsigaridas for
strong support and many useful discussions that lead to the integration of RS.
Due to lack of maintenance, these kernels have been removed in 2024.

/
} /
namespace CGAL */


Algebraic Kernel D Doc Algebraic Kernel D PackageDescription (`Algebraic_kernel_d/doc/Algebraic_kernel_d/PackageDescription.txt`)

/// \defgroup PkgAlgebraicKernelDRef Reference Manual

/// \defgroup PkgAlgebraicKernelDConcepts Concepts
/// \ingroup PkgAlgebraicKernelDRef

/// \defgroup PkgAlgebraicKernelDConceptsUni Univariate Algebraic Kernel
/// \ingroup PkgAlgebraicKernelDConcepts

/// \defgroup PkgAlgebraicKernelDConceptsBi Bivariate Algebraic Kernel
/// \ingroup PkgAlgebraicKernelDConcepts

/// \defgroup PkgAlgebraicKernelDModels Models
/// \ingroup PkgAlgebraicKernelDRef

/*!
\addtogroup PkgAlgebraicKernelDRef
\cgalPkgDescriptionBegin{Algebraic Kernel,PkgAlgebraicKernelD}
\cgalPkgPicture{Algebraic_kernel_d.png}
\cgalPkgSummaryBegin
\cgalPkgAuthors{Eric Berberich, Michael Hemmer, Michael Kerber, Sylvain Lazard, Luis Peñaranda, and Monique Teillaud}
\cgalPkgDesc{Real solving of polynomials is a fundamental problem with a wide application range. This package is targeted to provide black-box implementation algorithms to determine, compare and approximate real roots of univariate polynomials and bivariate polynomial systems. Such a black-box is called an Algebraic %Kernel. So far the package only provides models for the univariate kernel. Nevertheless, it already defines concepts for the bivariate kernel, since this settles the interface for upcoming implementations.}
\cgalPkgManuals{Chapter_Algebraic_Kernel,PkgAlgebraicKernelDRef}
\cgalPkgSummaryEnd
\cgalPkgShortInfoBegin
\cgalPkgSince{3.6}
\cgalPkgBib{cgal:bht-ak}
\cgalPkgLicense{\ref licensesLGPL "LGPL"}
\cgalPkgShortInfoEnd
\cgalPkgDescriptionEnd

\cgalClassifedRefPages

\cgalCRPSection{Concepts}

\cgalCRPSubsection{Univariate Algebraic %Kernel}

  • AlgebraicKernel_d_1

  • AlgebraicKernel_d_1::ConstructAlgebraicReal_1

  • AlgebraicKernel_d_1::ComputePolynomial_1

  • AlgebraicKernel_d_1::Isolate_1

  • AlgebraicKernel_d_1::IsSquareFree_1

  • AlgebraicKernel_d_1::MakeSquareFree_1

  • AlgebraicKernel_d_1::SquareFreeFactorize_1

  • AlgebraicKernel_d_1::IsCoprime_1

  • AlgebraicKernel_d_1::MakeCoprime_1

  • AlgebraicKernel_d_1::Solve_1

  • AlgebraicKernel_d_1::NumberOfSolutions_1

  • AlgebraicKernel_d_1::SignAt_1

  • AlgebraicKernel_d_1::IsZeroAt_1

  • AlgebraicKernel_d_1::Compare_1

  • AlgebraicKernel_d_1::BoundBetween_1

  • AlgebraicKernel_d_1::ApproximateAbsolute_1

  • AlgebraicKernel_d_1::ApproximateRelative_1

\cgalCRPSubsection{Bivariate Algebraic %Kernel}

  • AlgebraicKernel_d_2

  • AlgebraicKernel_d_2::ConstructAlgebraicReal_2

  • AlgebraicKernel_d_2::ComputePolynomialX_2

  • AlgebraicKernel_d_2::ComputePolynomialY_2

  • AlgebraicKernel_d_2::Isolate_2

  • AlgebraicKernel_d_2::IsolateX_2

  • AlgebraicKernel_d_2::IsolateY_2

  • AlgebraicKernel_d_2::IsSquareFree_2

  • AlgebraicKernel_d_2::MakeSquareFree_2

  • AlgebraicKernel_d_2::SquareFreeFactorize_2

  • AlgebraicKernel_d_2::IsCoprime_2

  • AlgebraicKernel_d_2::MakeCoprime_2

  • AlgebraicKernel_d_2::Solve_2

  • AlgebraicKernel_d_2::NumberOfSolutions_2

  • AlgebraicKernel_d_2::SignAt_2

  • AlgebraicKernel_d_2::IsZeroAt_2

  • AlgebraicKernel_d_2::ComputeX_2

  • AlgebraicKernel_d_2::ComputeY_2

  • AlgebraicKernel_d_2::CompareX_2

  • AlgebraicKernel_d_2::CompareY_2

  • AlgebraicKernel_d_2::CompareXY_2

  • AlgebraicKernel_d_2::ApproximateAbsoluteX_2

  • AlgebraicKernel_d_2::ApproximateRelativeX_2

  • AlgebraicKernel_d_2::ApproximateAbsoluteY_2

  • AlgebraicKernel_d_2::ApproximateRelativeY_2

  • AlgebraicKernel_d_2::BoundBetweenX_2

  • AlgebraicKernel_d_2::BoundBetweenY_2

\cgalCRPSection{Models}

  • CGAL::Algebraic_kernel_d_1<Coeff>
  • CGAL::Algebraic_kernel_d_2<Coeff>

*/


Algebraic Kernel D Doc Algebraic Kernel D Examples (`Algebraic_kernel_d/doc/Algebraic_kernel_d/examples.txt`)

/*!
\example Algebraic_kernel_d/Construct_algebraic_real_1.cpp
\example Algebraic_kernel_d/Solve_1.cpp
\example Algebraic_kernel_d/Compare_1.cpp
\example Algebraic_kernel_d/Isolate_1.cpp
\example Algebraic_kernel_d/Sign_at_1.cpp
*/


Alpha Shapes 2 Doc Alpha Shapes 2 Alpha Shapes 2 (`Alpha_shapes_2/doc/Alpha_shapes_2/Alpha_shapes_2.txt`)

namespace CGAL {
/*!

\mainpage User Manual
\anchor Chapter_2D_Alpha_Shapes
\anchor I1ChapterAlphashapes2D
\cgalAutoToc
\author Tran Kai Frank Da

\image html alphashape.png
\image latex alphashape.png

Assume we are given a set \f$ S\f$ of points in 2D or 3D and we would like to
have something like "the shape formed by these points". This is
quite a vague notion, and there are probably many possible
interpretations, the \f$ \alpha\f$-shape being one of them. Alpha shapes
can be used for shape reconstruction from a dense unorganized set of
data points. Indeed, an \f$ \alpha\f$-shape is demarcated by a frontier,
which is a linear approximation of the original shape \cgalCite{bb-srmua-97t}.

As mentioned in Edelsbrunner's and Mücke's paper \cgalCite{em-tdas-94},
one can intuitively think of an \f$ \alpha\f$-shape as the
following. Imagine a huge mass of ice-cream making up the space \f$ \mathbb{R}^3\f$
and containing the points as "hard" chocolate pieces. Using one of
these sphere-formed ice-cream spoons, we carve out all parts of the
ice-cream block we can reach without bumping into chocolate pieces,
thereby even carving out holes in the inside (e.g. parts not reachable
by simply moving the spoon from the outside). We will eventually end
up with a (not necessarily convex) object bounded by caps, arcs, and
points. If we now straighten all "round" faces to triangles and line
segments, we have an intuitive description of what is called the
\f$ \alpha\f$-shape of \f$ S\f$. The drawing above provides an example
of this process in 2D (where our ice-cream spoon is simply a circle).

Alpha shapes depend on a parameter \f$ \alpha\f$ after which they are named.
In the ice-cream analogy above, \f$ \alpha\f$ is the squared radius of the
carving spoon. A very small value will allow us to eat up all the
ice-cream except the chocolate points themselves. Thus, we already see
that the \f$ \alpha\f$-shape degenerates to the point-set \f$ S\f$ for
\f$ \alpha \rightarrow 0\f$. On the other hand, a huge value of \f$ \alpha\f$
will prevent us even from moving the spoon between two points since
it is too large. So we will never spoon up the ice-cream lying in the
inside of the convex hull of \f$ S\f$. Hence, the alpha shape becomes
the convex hull of \f$ S\f$ as \f$ \alpha \rightarrow \infty\f$.

\cgal offers 2D and 3D alpha shapes. The GUDHI library offers a
dD Alpha complex.

\section Alpha_shapes_2Definitions Definitions

We distinguish two versions of alpha shapes. Basic alpha shapes
are based on the Delaunay triangulation. Weighted alpha shapes
are based on its generalization, the regular triangulation
(cf. Section \ref Section_2D_Triangulations_Regular "Regular Triangulations"),
replacing the Euclidean distance by the power to weighted points.

There is a close connection between alpha shapes and the underlying
triangulations. More precisely, the \f$ \alpha\f$-complex of \f$ S\f$ is a
subcomplex of this triangulation of \f$ S\f$, containing the \f$ \alpha\f$-exposed
\f$ k\f$-simplices, \f$ 0 \leq k \leq d\f$. A simplex is said to be \f$ \alpha\f$-exposed, if there is an
open disk (resp. ball) of radius \f$ \sqrt{\alpha}\f$ through the vertices of the
simplex that does not contain any other point of \f$ S\f$, for the metric used in
the computation of the underlying triangulation. The corresponding
\f$ \alpha\f$-shape is defined as the underlying interior space of the
\f$ \alpha\f$-complex (see \cgalCite{em-tdas-94}).

In general, an \f$ \alpha\f$-complex is a non-connected and non-pure polytope,
meaning that one \f$ k\f$-simplex, with \f$ 0 \leq k \leq d-1\f$, is not necessarily
adjacent to a \f$ (k+1)\f$-simplex.

The \f$ \alpha\f$-shapes of \f$ S\f$ form a discrete family, even though they
are defined for all real numbers \f$ \alpha\f$ with \f$ 0 \leq \alpha
\leq \infty\f$. Thus, we can represent the entire family of \f$ \alpha\f$-shapes
of \f$ S\f$ by the underlying triangulation of \f$ S\f$. In this representation
each \f$ k\f$-simplex of the underlying triangulation is associated with an
interval that specifies for which values of \f$ \alpha\f$ the \f$ k\f$-simplex
belongs to the \f$ \alpha\f$-shape. Relying on this fact, the family of
\f$ \alpha\f$-shapes can be computed efficiently and relatively
easily. Furthermore, we can select an appropriate \f$ \alpha\f$-shape from a
finite number of different \f$ \alpha\f$-shapes and corresponding
\f$ \alpha\f$-values.

\section I1_SectAlpha_Shape_2 Functionality

The class Alpha_shape_2<Dt> represents the family of
\f$ \alpha\f$-shapes of points in a plane for all positive
\f$ \alpha\f$. It maintains the underlying triangulation Dt which
represents connectivity and order among squared radius of its faces. Each
\f$ k\f$-dimensional face of the Dt is associated with an interval
that specifies for which values of \f$ \alpha\f$ the face belongs to the
\f$ \alpha\f$-shape. There are links between the intervals and the
\f$ k\f$-dimensional faces of the triangulation.

The class Alpha_shape_2<Dt> provides functions to set and
get the current \f$ \alpha\f$-value, as well as an iterator that enumerates
the \f$ \alpha\f$-values where the \f$ \alpha\f$-shape changes.

It provides iterators to enumerate the vertices and edges that are in
the \f$ \alpha\f$-shape, and functions that allow to classify vertices,
edges, and faces with respect to the \f$ \alpha\f$-shape. They can be in
the interior of a face that belongs or does not belong to the \f$ \alpha\f$-shape.
They can be singular/regular, that is, they can be on the boundary of the \f$ \alpha\f$-shape,
but not incident/incident to a triangle of the \f$ \alpha\f$-complex.

Finally, it provides a function to determine the \f$ \alpha\f$-value
such that the \f$ \alpha\f$-shape satisfies the following two properties,
or at least the second one if there is no such \f$ \alpha\f$ that both
are satisfied:

  1. the number of components equals a number of your choice, and
  2. all data points are either on the boundary or in the interior of the regularized version of the \f$ \alpha\f$-shape (no singular edges).

The current implementation is static, that is after its construction
points cannot be inserted or removed.

\section I1_SectDtClass2D Concepts and Models

We currently do not specify concepts for the underlying triangulation
type. Models that work for a basic alpha shape are the classes
Delaunay_triangulation_2, Periodic_2_Delaunay_triangulation_2, and
Triangulation_hierarchy_2 templated with a Delaunay
triangulation. A model that works for a weighted alpha shape is
the class Regular_triangulation_2.

\subsection AlphaShape2D_ConceptAndModelsAlphaShapes Alpha Shapes

The triangulation needs a geometric traits class as argument.
The requirements of this class are described in the concepts AlphaShapeTraits_2
in the non-weighted case and WeightedAlphaShapeTraits_2 in the weighted case.
All \cgal kernels are models of both concepts.

The triangulation data structure of the triangulation
has to be a model of the concept TriangulationDataStructure_2,
whose vertex and face classes are models of the concepts
AlphaShapeVertex_2 and AlphaShapeFace_2, respectively.
The classes Alpha_shape_vertex_base_2<Gt, Vb> and Alpha_shape_face_base_2<Gt, Fb>
are models of these concepts and can be used for all type of alpha shapes,
provided that the template parameters Vb and Fb are appropriately chosen,
as we shall see in the following section.

\subsection AlphaShape2D_ConceptAndModelsTDS Triangulation data structure

Additional requirements are put when using weighted or
periodic triangulations as underlying triangulation:

  • When using a weighted triangulation (`Regular_triangulation_2`), the vertex and face classes must respectively be models to both `AlphaShapeVertex_2` and `RegularTriangulationVertexBase_2`, and to both `AlphaShapeFace_2` and `RegularTriangulationFaceBase_2` (see example: \ref I1_SectWeightedAS2D).
  • When using a periodic triangulation (`Periodic_2_Delaunay_triangulation_2`), the vertex and face classes must respectively be models to both `AlphaShapeVertex_2` and `Periodic_2TriangulationVertexBase_2`, and to both `AlphaShapeFace_2` and `Periodic_2TriangulationFaceBase_2` (see example: \ref AlphaShape_2DExampleForPeriodicAlphaShapes).

    \section Alpha_shapes_2Examples Examples

    \subsection I1_SectClassicAS2D Example for Basic Alpha Shapes

    The basic alpha shape requires a Delaunay triangulation as
    underlying triangulation Dt. The Delaunay triangulation class is
    parameterized with a geometric and a triangulation data structure traits.

    For the geometric traits class we can use a \cgal kernel.

    For the triangulation data structure traits, we have to
    choose the vertex and face classes needed for alpha shapes,
    namely Alpha_shape_vertex_base_2<Gt, Vb> and Alpha_shape_face_base_2<Gt,Fb>.
    The parameter Vb and Fb must be filled by classes that are models of the
    TriangulationVertexBase_2 and TriangulationFaceBase_2 concepts. The classes
    Triangulation_vertex_base_2<Gt> and Triangulation_face_base_2<Gt> fit these
    requirements.

    The example below illustrates how to construct a basic alpha shape.
    Note that Triangulation_vertex_base_2<Gt> and Triangulation_face_base_2<Gt>
    are the default parameters for Vb and Fb in the classes
    Alpha_shape_vertex_base_2<Gt, Vb> and Alpha_shape_face_base_2<Gt,Fb>. They
    are thus omitted in the code below.
    \cgalExample{Alpha_shapes_2/ex_alpha_shapes_2.cpp}

    \subsection I1_SectWeightedAS2D Example for Weighted Alpha Shapes

    A weighted alpha shape requires a regular triangulation as
    underlying triangulation Dt.
    Here again, we can use the vertex and face Alpha_shape_vertex_base_2<Gt, Vb>
    and Alpha_shape_face_base_2<Gt,Fb>, but for weighted alpha shapes, Vb and Fb
    must be models of the concepts RegularTriangulationVertexBase_2 and
    RegularTriangulationFaceBase_2. The classes Regular_triangulation_vertex_base_2<Gt>
    Regular_triangulation_face_base_2<Gt> fit these requirements.

    Note that there is no special weighted alpha shape class.

    The example below illustrates how to construct a weighted alpha shape.
    \cgalExample{Alpha_shapes_2/ex_weighted_alpha_shapes_2.cpp}

    \subsection AlphaShape_2DExampleForPeriodicAlphaShapes Example for Periodic Alpha Shapes
    The following example shows how to use a periodic Delaunay
    triangulation as underlying triangulation for the alpha shape computation.

    In order to define the original domain and to benefit from the
    built-in heuristic optimizations of the periodic triangulation computation,
    it is recommended to first construct the triangulation and
    then construct the alpha shape from it. The alpha
    shape constructor that takes a point range can be used as well but in
    this case the original domain cannot be specified and the default unit
    cube will be chosen and no optimizations will be used.

    It is also recommended to switch the triangulation to 1-sheeted
    covering if possible. Note that a periodic triangulation in 9-sheeted
    covering space is degenerate. In this case, an exact constructions
    kernel needs to be used to compute the alpha shapes. Otherwise, the
    results will suffer from round-off problems.

    \cgalExample{Alpha_shapes_2/ex_periodic_alpha_shapes_2.cpp}

    /
    } /
    namespace CGAL */


    Alpha Shapes 2 Doc Alpha Shapes 2 PackageDescription (`Alpha_shapes_2/doc/Alpha_shapes_2/PackageDescription.txt`)

    /// \defgroup PkgAlphaShapes2Ref Reference Manual
    /// \defgroup PkgAlphaShapes2Concepts Concepts
    /// \ingroup PkgAlphaShapes2Ref

    /*!
    \addtogroup PkgAlphaShapes2Ref

    \cgalPkgDescriptionBegin{2D Alpha Shapes,PkgAlphaShapes2}
    \cgalPkgPicture{alpha-detail.png}
    \cgalPkgSummaryBegin
    \cgalPkgAuthor{Tran Kai Frank Da}
    \cgalPkgDesc{This package offers a data structure encoding the whole family of alpha-complexes related to a given 2D Delaunay or regular triangulation. In particular, the data structure allows to retrieve the alpha-complex for any alpha value, the whole spectrum of critical alpha values and a filtration on the triangulation faces (this filtration is based on the first alpha value for which each face is included on the alpha-complex).}
    \cgalPkgManuals{Chapter_2D_Alpha_Shapes,PkgAlphaShapes2Ref}
    \cgalPkgSummaryEnd
    \cgalPkgShortInfoBegin
    \cgalPkgSince{2.1}
    \cgalPkgDependsOn{\ref PkgTriangulation2}
    \cgalPkgBib{cgal:d-as2}
    \cgalPkgLicense{\ref licensesGPL "GPL"}
    \cgalPkgDemo{2D Alpha Shapes,alpha_shapes_2.zip}
    \cgalPkgShortInfoEnd
    \cgalPkgDescriptionEnd

    This chapter presents a framework for alpha shapes. The description is based on
    the articles \cgalCite{em-tdas-94}, \cgalCite{e-was-92}. Alpha shapes are
    the generalization of the convex hull of a point set. Let \f$ S\f$ be a finite set of
    points in \f$ \mathbb{R}^d\f$, \f$ d = 2,3\f$ and \f$ \alpha\f$ a parameter with \f$ 0 \leq \alpha \leq
    \infty\f$. For \f$ \alpha = \infty\f$, the \f$ \alpha\f$-shape is the convex hull of \f$ S\f$. As
    \f$ \alpha\f$ decreases, the \f$ \alpha\f$-shape shrinks and develops cavities, as soon as
    a sphere of radius \f$ \sqrt{\alpha}\f$ can be put inside.
    Finally, for \f$ \alpha = 0\f$, the \f$ \alpha\f$-shape is the set \f$ S\f$ itself.

    We distinguish two versions of alpha shapes, one is based on the Delaunay
    triangulation and the other on its generalization, the regular triangulation,
    replacing the natural distance by the power to weighted points. The metric used
    determines an underlying triangulation of the alpha shape and thus, the version
    computed.
    The basic alpha shape (cf. \ref I1_SectClassicAS2D) is associated with the Delaunay triangulation
    (cf. Section \ref Section_2D_Triangulations_Delaunay "Delaunay Triangulations").
    The weighted alpha shape (cf. \ref I1_SectWeightedAS2D ) is associated with the regular triangulation
    (cf. Section \ref Section_2D_Triangulations_Regular "Regular Triangulations").

    There is a close connection between alpha shapes and the underlying
    triangulations. More precisely, the \f$ \alpha\f$-complex of \f$ S\f$ is a
    subcomplex of this triangulation of \f$ S\f$, containing the \f$ \alpha\f$-exposed
    \f$ k\f$-simplices, \f$ 0 \leq k \leq d\f$. A simplex is \f$ \alpha\f$-exposed, if there is an
    open disk (resp. ball) of radius \f$ \sqrt{\alpha}\f$ through the vertices of the
    simplex that does not contain any other point of \f$ S\f$, for the metric used in
    the computation of the underlying triangulation. The corresponding
    \f$ \alpha\f$-shape is defined as the underlying interior space of the
    \f$ \alpha\f$-complex.

    In general, an \f$ \alpha\f$-complex is a non-connected and non-pure polytope,
    meaning that a \f$ k\f$-simplex, with \f$ 0 \leq k \leq d-1\f$, is not necessarily
    adjacent to a \f$ (k+1)\f$-simplex.

    The \f$ \alpha\f$-shapes of \f$ S\f$ form a discrete family, even though they
    are defined for all real numbers \f$ \alpha\f$ with \f$ 0 \leq \alpha
    \leq \infty\f$. Thus, we can represent the entire family of \f$ \alpha\f$-shapes
    of \f$ S\f$ by the underlying triangulation of \f$ S\f$. In this representation
    each \f$ k\f$-simplex of the underlying triangulation is associated with an
    interval that specifies for which values of \f$ \alpha\f$ the \f$ k\f$-simplex
    belongs to the \f$ \alpha\f$-shape. Relying on this result, the family of
    \f$ \alpha\f$-shapes can be computed efficiently and relatively
    easily. Furthermore, we can select an appropriate \f$ \alpha\f$-shape from a
    finite number of different \f$ \alpha\f$-shapes and corresponding
    \f$ \alpha\f$-values.

    \cgalClassifedRefPages

    \cgalCRPSection{Concepts}

    • AlphaShapeTraits_2
    • WeightedAlphaShapeTraits_2
    • AlphaShapeFace_2
    • AlphaShapeVertex_2

    \cgalCRPSection{Classes}

    • CGAL::Alpha_shape_2<Dt>
    • CGAL::Alpha_shape_vertex_base_2<AlphaShapeTraits_2>
    • CGAL::Alpha_shape_face_base_2<AlphaShapeTraits_2, TriangulationFaceBase_2>

    */


    Alpha Shapes 2 Doc Alpha Shapes 2 Examples (`Alpha_shapes_2/doc/Alpha_shapes_2/examples.txt`)

    /*!
    \example Alpha_shapes_2/ex_alpha_shapes_2.cpp
    \example Alpha_shapes_2/ex_periodic_alpha_shapes_2.cpp
    \example Alpha_shapes_2/ex_weighted_alpha_shapes_2.cpp
    \example Alpha_shapes_2/ex_alpha_projection_traits.cpp
    */


    Alpha Shapes 3 Doc Alpha Shapes 3 Alpha Shapes 3 (`Alpha_shapes_3/doc/Alpha_shapes_3/Alpha_shapes_3.txt`)

    namespace CGAL {
    /*!

    \mainpage User Manual
    \anchor Chapter_3D_Alpha_Shapes
    \cgalAutoToc
    \authors Tran Kai Frank Da, Sébastien Loriot, and Mariette Yvinec

    \image html alphashape.png
    \image latex alphashape.png

    Assume we are given a set \f$ S\f$ of points in 2D or 3D and we would like to
    have something like "the shape formed by these points". This is
    quite a vague notion and there are probably many possible
    interpretations, the alpha shape being one of them. Alpha shapes
    can be used for shape reconstruction from a dense unorganized set of
    data points. Indeed, an alpha shape is demarcated by a frontier,
    which is a linear approximation of the original shape \cgalCite{bb-srmua-97t}.

    As mentioned in Edelsbrunner's and Mücke's paper \cgalCite{em-tdas-94},
    one can intuitively think of an alpha shape as the
    following. Imagine a huge mass of ice-cream making up the space \f$ \mathbb{R}^3\f$
    and containing the points as "hard" chocolate pieces. Using one of
    those sphere-formed ice-cream spoons, we carve out all parts of the
    ice-cream block we can reach without bumping into chocolate pieces,
    thereby even carving out holes in the inside (e.g. parts not reachable
    by simply moving the spoon from the outside). We will eventually end
    up with a (not necessarily convex) object bounded by caps, arcs and
    points. If we now straighten all "round" faces to triangles and line
    segments, we have an intuitive description of what is called the
    alpha shape of \f$ S\f$. The drawing above provides an example
    of this process in 2D (where our ice-cream spoon is simply a circle).

    Alpha shapes depend on a parameter \f$ \alpha\f$ after which they are named.
    In the ice-cream analogy above, \f$ \alpha\f$ is the squared radius of the
    carving spoon. A very small value will allow us to eat up all the
    ice-cream except the chocolate points themselves. Thus, we already see
    that the alpha shape degenerates to the point-set \f$ S\f$ for
    \f$ \alpha \rightarrow 0\f$. On the other hand, a huge value of \f$ \alpha\f$
    will prevent us even from moving the spoon between two points since
    it is too large and we will never spoon up the ice-cream lying in the
    inside of the convex hull of \f$ S\f$. Hence, the alpha shape becomes
    the convex hull of \f$ S\f$ as \f$ \alpha \rightarrow \infty\f$.

    \cgal offers 2D and 3D alpha shapes. The GUDHI library offers a
    dD Alpha complex.

    \section Alpha_shapes_3Definitions Definitions

    We distinguish two versions of alpha shapes. Basic alpha shapes
    are based on the Delaunay triangulation. Weighted alpha shapes
    are based on its generalization, the regular triangulation
    (cf. Section \ref Triangulation3secclassRegulartriangulation "Regular Triangulations"),
    replacing the Euclidean distance by the power to weighted points.

    Let us consider the basic case with a Delaunay triangulation.
    We first define the alpha complex of the set of points \f$ S\f$.
    The alpha complex is a subcomplex
    of the Delaunay triangulation.
    For a given value of \f$ \alpha\f$, the alpha complex includes
    all the simplices in the Delaunay triangulation which have
    an empty circumscribing sphere with squared radius equal or smaller than \f$ \alpha\f$.
    Here "empty" means that the open sphere does not include any points of \f$ S\f$.
    The alpha shape is then simply the domain covered by the simplices
    of the alpha complex (see \cgalCite{em-tdas-94}).

    In general, an alpha complex is a disconnected and non-pure complex,
    meaning in particular that the alpha complex may have
    singular faces. For \f$ 0 \leq k \leq d-1\f$,
    a \f$ k\f$-simplex of the alpha complex is said to be
    singular if it is not a facet of a \f$ (k+1)\f$-simplex of the complex.
    \cgal provides two versions of alpha shapes. In the general mode,
    the alpha shapes correspond strictly to the above definition.
    The regularized mode provides a regularized version of the alpha shapes.
    It corresponds to the domain covered by a regularized version
    of the alpha complex where singular faces are removed
    (See \cgalFigureRef{figgenregex} for an example).

    \cgalFigureBegin{figgenregex,gen-reg-ex.png}
    Comparison of general and regularized alpha-shape. Left: Some points are taken on the surface of a torus, three points being taken relatively far from the surface of the torus; Middle: The general alpha-shape (for a large enough alpha value) contains the singular triangle facet of the three isolated points; Right: The regularized version (for the same value of alpha) does not contain any singular facet.
    \cgalFigureEnd

    The alpha shapes of a set of points
    \f$ S\f$ form a discrete family, even though they
    are defined for all real numbers \f$ \alpha\f$.
    The entire family of alpha shapes can be represented
    through the underlying triangulation of \f$ S\f$. In this representation
    each \f$ k\f$-simplex of the underlying triangulation is associated with an
    interval that specifies for which values of \f$ \alpha\f$ the \f$ k\f$-simplex
    belongs to the alpha complex. Relying on this fact, the family of
    alpha shapes can be computed efficiently and relatively
    easily. Furthermore, we can select the optimal value
    of \f$ \alpha\f$ to get an alpha shape including all data points
    and having less than a given number of connected components.
    Also, the alpha-values allows to define a filtration on the
    faces of the triangulation of a set of points.
    In this filtration, the faces of the triangulation are output
    in increasing order of the alpha value
    for which they appear
    in the alpha complex. In case of equal alpha values,
    lower dimensional faces are output first.

    The definition is analog in the case of weighted alpha shapes.
    The input set is now a set of weighted points (which can be regarded
    as spheres) and the underlying triangulation
    is the regular triangulation of this set.
    Two spheres, or two weighted points, with centers \f$ C_1, C_2\f$
    and radii \f$ r_1, r_2 \f$ are said to be orthogonal iff
    \f$ C_1C_2 ^2 = r_1^2 + r_2^2\f$ and suborthogonal
    iff \f$ C_1C_2 ^2 < r_1^2 + r_2^2\f$.
    For a given value of \f$ \alpha\f$,
    the weighted alpha complex is formed with the simplices of the
    regular triangulation such that there is a sphere
    orthogonal to the weighted points associated
    with the vertices of the simplex and suborthogonal to all the other
    input weighted points. Once again the alpha shape is then defined as
    the domain covered by the alpha complex and comes in general and
    regularized versions.

    \section Alpha_Shape_3Functionality Functionality

    \subsection AlphaShape_3DFamilyOfAlphaShapes Family of Alpha Shapes

    The class Alpha_shape_3<Dt,ExactAlphaComparisonTag> represents the whole
    family of alpha shapes for a given set of points.
    The class includes the underlying triangulation Dt
    of the set, and associates to each \f$ k\f$-face of this triangulation
    an interval specifying
    for which values of \f$ \alpha\f$ the face belongs to the
    alpha complex.
    The second template parameter, ExactAlphaComparisonTag, is a tag that,
    when set to CGAL::Tag_true, triggers exact comparisons between alpha values.

    The class provides functions to set and
    get the current \f$ \alpha\f$-value, as well as an iterator that enumerates
    the \f$ \alpha\f$ values where the alpha shape changes.

    Additionally, the class has a filtration member function that, given
    an output iterator with Object
    as value type, outputs the faces of the triangulation
    according to the
    order of apparition in the alpha complex when alpha increases.

    Finally, it provides a function to determine
    the smallest value \f$ \alpha\f$
    such that the alpha shape satisfies the following two properties:

    1. All data points are either on the boundary or in the interior of the regularized version of the alpha shape (no singular faces).
    2. The number of components is equal or less than a given number.

    The current implementation is static, that is after its construction
    points cannot be inserted or removed.

    \subsection AlphaShape_3DAlphaShapeForAFixedAlpha Alpha Shape for a Fixed Alpha

    Given a value of alpha, the class Fixed_alpha_shape_3<Dt> represents one
    alpha shape for a given set of points.
    The class includes the underlying triangulation Dt
    of the set, and associates to each \f$ k\f$-face of this triangulation
    a classification type. This class is dynamic, that is after its construction
    points can be inserted or removed.

    \subsection AlphaShape_3DClassificationAndIterators Classification and Iterators

    Both classes provide member functions to classify for a (given) value
    of \f$ \alpha\f$ the different faces of the triangulation as
    EXTERIOR, SINGULAR, REGULAR or
    INTERIOR with respect
    to the alpha shape. A \f$ k\f$-face on the boundary of the alpha complex
    is said to be: REGULAR if it is a subface of the alpha-complex which
    is a subface of a \f$ (k+1)\f$-face of the alpha complex, and SINGULAR otherwise.
    A \f$ k\f$-face of the alpha complex which is not on the boundary of the alpha complex
    is said to be INTERIOR. See \cgalFigureRef{figclassif} for a 2D illustration.

    \cgalFigureBegin{figclassif,classif.png} Classification of simplices, a 2D example. Left: The 2D
    Delaunay triangulation of a set of points; Right:
    Classification of simplices for a given alpha (the squared radius of
    the red circle). INTERIOR, REGULAR and SINGULAR simplices are
    depicted in black, green and blue respectively. EXTERIOR simplices
    are not depicted. The vertex s and the edge tu are SINGULAR
    since all higher dimension simplices they are incident to are
    EXTERIOR. The facet pqr is EXTERIOR because the squared radius
    of its circumscribed circle is larger than alpha.
    \cgalFigureEnd

    The classes provide also output iterators to get for a given alpha value
    the vertices, edges, facets and cells of the different types
    (EXTERIOR, SINGULAR, REGULAR or
    INTERIOR).

    \subsection AlphaShape3DIO Input/Output
    It is possible to export a 3D alpha shape to a std::ostream
    using the operator<<, see the documentation of the class Alpha_shape_3 for more information.

    \section AlphaShape3D_ConceptAndModels Concepts and Models

    We currently do not specify concepts for the underlying triangulation
    type. Models that work for a family of alpha-shapes are the instantiations
    of the classes Delaunay_triangulation_3 and
    Periodic_3_Delaunay_triangulation_3 (see
    example \ref AlphaShape_3DExampleForPeriodicAlphaShapes).
    A model that works for a fixed alpha-shape are the instantiations
    of the class Delaunay_triangulation_3.
    Models that work for a weighted alpha-shape are the instantiations
    of the classes Regular_triangulation_3 and
    Periodic_3_regular_triangulation_3.
    The triangulation needs a geometric traits class
    and a triangulation data structure as template parameters.

    \subsection AlphaShape3D_ConceptAndModelsAlphaShapes Alpha Shapes

    For the class Alpha_shape_3<Dt,ExactAlphaComparisonTag>, the requirements of
    the traits class are described in the concepts AlphaShapeTraits_3
    in the non-weighted case and WeightedAlphaShapeTraits_3 in the weighted case.
    All \cgal kernels are models of both concepts.

    The triangulation data structure of the triangulation
    has to be a model of the concept TriangulationDataStructure_3
    whose vertex and cell classes are model of the concepts
    AlphaShapeVertex_3 and AlphaShapeCell_3.
    The classes Alpha_shape_vertex_base_3<Gt> and Alpha_shape_cell_base_3<Gt>
    are models of these concepts and can be used for all type of alpha shapes,
    provided that the template parameters Vb and Fb are appropriately chosen,
    as we shall see in the following section.

    \subsection AlphaShape3D_ConceptAndModelsFixedAlphaShapes Fixed Alpha Shapes

    For the class Fixed_alpha_shape_3<Dt>, the requirements of
    the traits class are described in the concepts FixedAlphaShapeTraits_3
    in the non-weighted case and FixedWeightedAlphaShapeTraits_3 in the weighted case.
    All \cgal kernels are models of both concepts.
    The triangulation data structure of the triangulation
    has to be a model of the concept TriangulationDataStructure_3
    whose vertex and cell classes are model of the concepts
    FixedAlphaShapeVertex_3 and FixedAlphaShapeCell_3.
    The package provides models Fixed_alpha_shape_vertex_base_3<Gt>
    and Fixed_alpha_shape_cell_base_3<Gt>, respectively.

    \subsection AlphaShape3D_ConceptAndModelsTDS Triangulation data structure

    Additional requirements are put when using weighted or
    periodic triangulations as underlying triangulation:

  • When using a weighted triangulation (`Regular_triangulation_3` or `Periodic_3_regular_triangulation_3`), the vertex and cell classes must respectively be models to both `AlphaShapeVertex_3` and `RegularTriangulationVertexBase_3`, and to both `AlphaShapeCell_3` and `RegularTriangulationCellBase_3` (see example: \ref AlphaShape_3DExampleforWeightedAlphaShapes).
  • When using a periodic triangulation (`Periodic_3_Delaunay_triangulation_3` or `Periodic_3_regular_triangulation_3`), the vertex and cell classes must respectively be models to both `AlphaShapeVertex_3` and `Periodic_3TriangulationDSVertexBase_3`, and to both `AlphaShapeCell_3` and `Periodic_3TriangulationDSCellBase_3` (see example: \ref AlphaShape_3DExampleForPeriodicAlphaShapes).

    \section Alpha_shapes_3AlphaShape3OrFixedAlphaShape3 Alpha_shape_3 vs. Fixed_alpha_shape_3

    The class Alpha_shape_3<Dt,ExactAlphaComparisonTag> represents the whole family
    of alpha shapes for a given set of points while the class Fixed_alpha_shape_3<Dt>
    represents only one alpha shape (for a fixed alpha). When using the same kernel,
    Fixed_alpha_shape_3<Dt> is a lighter version. It is thus naturally much more efficient
    when the alpha-shape is needed for a single given value of alpha.
    In addition, note that the class Alpha_shape_3<Dt,ExactAlphaComparisonTag>
    requires constructions (squared radius of simplices) while the
    class Fixed_alpha_shape_3<Dt> uses only predicates.
    This implies that a certified construction of one (several)
    alpha-shape, using the Alpha_shape_3<Dt,ExactAlphaComparisonTag> requires a kernel
    with exact predicates and exact constructions (or setting ExactAlphaComparisonTag to Tag_true)
    while using a kernel with exact predicates is sufficient for the class Fixed_alpha_shape_3<Dt>.
    This makes the class Fixed_alpha_shape_3<Dt> even more efficient in this setting.
    In addition, note that the Fixed version is the only one of the
    two that supports incremental insertion and removal of points.

    We give the time spent while computing the alpha shape of a protein (considered
    as a set of weighted points) featuring 4251 atoms (using gcc 4.3 under Linux with -O3
    and -DNDEBUG flags, on a 2.27GHz Intel(R) Xeon(R) E5520 CPU):
    Using Exact_predicates_inexact_constructions_kernel, building
    the regular triangulation requires 0.09s, then the class Fixed_alpha_shape_3<Dt>
    required 0.05s while the class Alpha_shape_3<Dt,ExactAlphaComparisonTag> requires 0.35s
    if ExactAlphaComparisonTag is Tag_false (and 0.70s with Tag_true).
    Using Exact_predicates_exact_constructions_kernel, building
    the regular triangulation requires 0.19s and then the class Alpha_shape_3<Dt,ExactAlphaComparisonTag>
    requires 0.90s.

    \section Alpha_shapes_3Examples Examples

    \subsection AlphaShape_3DExampleForBasicAlphaShapes Example for Basic Alpha-Shapes

    This example builds a basic alpha shape using a Delaunay triangulation
    as underlying triangulation.

    \cgalExample{Alpha_shapes_3/ex_alpha_shapes_3.cpp}

    \subsection AlphaShape_3DBuildingBasicAlphaShapesForManyPoints Building Basic Alpha Shapes for Many Points

    When many points are input in the alpha shape, say more than 10 000,
    it may pay off to use a Delaunay triangulation with the Fast_location
    policy as underlying triangulation in order to speed up point location
    queries (cf. Section \ref Triangulation3seclocpol "The Location Policy Parameter").

    \cgalExample{Alpha_shapes_3/ex_alpha_shapes_with_fast_location_3.cpp}

    \subsection AlphaShape_3DExampleforWeightedAlphaShapes Example for Weighted Alpha-Shapes

    The following examples build a weighted alpha shape requiring a
    regular triangulation as underlying triangulation.
    The alpha shape is built in GENERAL mode.

    \cgalExample{Alpha_shapes_3/ex_weighted_alpha_shapes_3.cpp}

    \subsection AlphaShape_3DExampleForFixedWeightedAlphaShapes Example for Fixed Weighted Alpha-Shapes

    Same example as previous but using a fixed value of alpha.

    \cgalExample{Alpha_shapes_3/ex_fixed_weighted_alpha_shapes_3.cpp}

    \subsection AlphaShape_3DBuildingAnAlphaShapesWithExactComparisonsOfAlphaValues Building an Alpha Shapes with Exact Comparisons of Alpha Values

    On some platforms, the alpha shapes of the set of points of this example
    cannot be computed when using a traits with inexact constructions. To be able to compute
    them with a traits with inexact constructions, the tag
    ExactAlphaComparisonTag is set to Tag_true.
    \cgalExample{Alpha_shapes_3/ex_alpha_shapes_exact_alpha.cpp}

    \subsection AlphaShape_3DExampleForPeriodicAlphaShapes Example for Periodic Alpha Shapes

    The following example shows how to use a periodic Delaunay
    triangulation (Chapter \ref Chapter_3D_Periodic_Triangulations "3D Periodic Triangulations") as underlying
    triangulation for the alpha shape computation. Usage of a weighted Delaunay periodic
    triangulation is presented in the example: \ref Alpha_shapes_3/ex_weighted_periodic_alpha_shapes_3.cpp "ex_weighted_periodic_alpha_shapes_3.cpp".

    In order to define the original domain and to benefit from the
    built-in heuristic optimizations of the periodic triangulation computation,
    it is recommended to first construct the triangulation and
    then construct the alpha shape from it. The alpha
    shape constructor that takes a point range can be used as well but in
    this case the original domain cannot be specified and the default unit
    cube will be chosen and no optimizations will be used.

    It is also recommended to switch the triangulation to 1-sheeted
    covering if possible. Note that a periodic triangulation in 27-sheeted
    covering space is degenerate. In this case, an exact constructions
    kernel needs to be used to compute the alpha shapes. Otherwise, the
    results will suffer from round-off problems.

    \cgalExample{Alpha_shapes_3/ex_periodic_alpha_shapes_3.cpp}

    /
    } /
    namespace CGAL */


    Alpha Shapes 3 Doc Alpha Shapes 3 PackageDescription (`Alpha_shapes_3/doc/Alpha_shapes_3/PackageDescription.txt`)

    /// \defgroup PkgAlphaShapes3Ref Reference Manual
    /// \defgroup PkgAlphaShapes3Concepts Concepts
    /// \ingroup PkgAlphaShapes3Ref
    /*!
    \addtogroup PkgAlphaShapes3Ref
    \cgalPkgDescriptionBegin{3D Alpha Shapes,PkgAlphaShapes3}
    \cgalPkgPicture{alpha_shapes_3_small.png}
    \cgalPkgSummaryBegin
    \cgalPkgAuthors{Tran Kai Frank Da, Sébastien Loriot, and Mariette Yvinec}
    \cgalPkgDesc{This package offers a data structure encoding either one alpha-complex or the whole family of alpha-complexes related to a given 3D Delaunay or regular triangulation. In the latter case, the data structure allows to retrieve the alpha-complex for any alpha value, the whole spectrum of critical alpha values and a filtration on the triangulation faces (this filtration is based on the first alpha value for which each face is included on the alpha-complex). }
    \cgalPkgManuals{Chapter_3D_Alpha_Shapes,PkgAlphaShapes3Ref}
    \cgalPkgSummaryEnd
    \cgalPkgShortInfoBegin
    \cgalPkgSince{2.3}
    \cgalPkgDependsOn{\ref PkgTriangulation3}
    \cgalPkgBib{cgal:dy-as3}
    \cgalPkgLicense{\ref licensesGPL "GPL"}
    \cgalPkgDemo{3D Alpha Shapes,alpha_shape_3.zip}
    \cgalPkgShortInfoEnd
    \cgalPkgDescriptionEnd

    Alpha shapes definition is based on an underlying
    triangulation that may be a Delaunay triangulation
    in case of basic alpha shapes or a regular triangulation
    (cf. Section \ref Triangulation3secclassRegulartriangulation "3D Regular Triangulation")
    in case of weighted alpha shapes.

    Let us consider the basic case with a Delaunay triangulation.
    We first define the alpha complex of the set of points \f$ S\f$.
    The alpha complex is a subcomplex
    of the Delaunay triangulation.
    For a given value of \f$ \alpha\f$, the alpha complex includes
    all the simplices in the Delaunay triangulation which have
    an empty circumscribing sphere with squared radius equal or smaller than \f$ \alpha\f$.
    Here "empty" means that the open sphere
    do not include any points of \f$ S\f$.
    The alpha shape is then simply the domain covered by the simplices
    of the alpha complex (see \cgalCite{em-tdas-94}).

    In general, an alpha complex is a non-connected and non-pure complex.
    This means in particular that the alpha complex may have
    singular faces. For \f$ 0 \leq k \leq d-1\f$,
    a \f$ k\f$-simplex of the alpha complex is said to be
    singular if it is not a facet of a \f$ (k+1)\f$-simplex of the complex

    The alpha shapes of a set of points
    \f$ S\f$ form a discrete family, even though they
    are defined for all real numbers \f$ \alpha\f$.
    The entire family of alpha shapes can be represented
    through the underlying triangulation of \f$ S\f$. In this representation,
    each \f$ k\f$-simplex of the underlying triangulation is associated with an
    interval that specifies for which values of \f$ \alpha\f$ the \f$ k\f$-simplex
    belongs to the alpha complex. Relying on this fact, the family of
    alpha shapes can be computed efficiently and relatively
    easily. Furthermore, we can select the optimal value
    of \f$ \alpha\f$ to get an alpha shape including all data points
    and having less than a given number of connected components.

    The definition is analog in the case of weighted alpha shapes.
    The input set is now a set of weighted points (which can be regarded
    as spheres) and the underlying triangulation
    is the regular triangulation of this set.
    Two spheres, or two weighted points, with centers \f$ C_1, C_2\f$
    and radii \f$ r_1, r_2 \f$ are said to be orthogonal iff
    \f$ C_1C_2 ^2 = r_1^2 + r_2^2\f$ and suborthogonal
    iff \f$ C_1C_2 ^2 < r_1^2 + r_2^2\f$.
    For a given value of \f$ \alpha\f$
    the weighted alpha complex is formed with the simplices of the
    regular triangulation triangulation
    such that there is a sphere orthogonal to the weighted points associated
    with the vertices of the simplex and suborthogonal to all the other
    input weighted points. Once again the alpha shape is then defined as
    the domain covered by a the alpha complex.

    CGAL provides two versions to compute alpha shapes.
    The first one gives access to an explicit classification of all the simplices for a fixed alpha value.
    The second one gives access to the entire family of alpha shapes of a set of points.
    This latter version comes with two modes. In the general mode,
    the alpha shapes correspond strictly to the definition previously made.
    The regularized mode provides a regularized version of the alpha shapes
    corresponding to the domain covered by a regularized version
    of the alpha complex where singular faces are removed.

    \cgalClassifedRefPages

    \cgalCRPSection{Concepts}

    • AlphaShapeTraits_3
    • WeightedAlphaShapeTraits_3
    • AlphaShapeCell_3
    • AlphaShapeVertex_3
    • FixedAlphaShapeTraits_3
    • FixedWeightedAlphaShapeTraits_3
    • FixedAlphaShapeCell_3
    • FixedAlphaShapeVertex_3

    \cgalCRPSection{Classes}

    • CGAL::Alpha_status<NT>

    • CGAL::Alpha_shape_3<Dt,ExactAlphaComparisonTag>

    • CGAL::Alpha_shape_vertex_base_3

    • CGAL::Alpha_shape_cell_base_3

    • CGAL::Fixed_alpha_shape_3<Dt>

    • CGAL::Fixed_alpha_shape_vertex_base_3

    • CGAL::Fixed_alpha_shape_cell_base_3

    */


    Alpha Shapes 3 Doc Alpha Shapes 3 Examples (`Alpha_shapes_3/doc/Alpha_shapes_3/examples.txt`)

    /*!
    \example Alpha_shapes_3/ex_alpha_shapes_3.cpp
    \example Alpha_shapes_3/ex_alpha_shapes_exact_alpha.cpp
    \example Alpha_shapes_3/ex_alpha_shapes_with_fast_location_3.cpp
    \example Alpha_shapes_3/ex_fixed_weighted_alpha_shapes_3.cpp
    \example Alpha_shapes_3/ex_periodic_alpha_shapes_3.cpp
    \example Alpha_shapes_3/ex_weighted_alpha_shapes_3.cpp
    \example Alpha_shapes_3/ex_weighted_periodic_alpha_shapes_3.cpp
    \example Alpha_shapes_2/ex_alpha_projection_traits.cpp
    */


    Alpha Wrap 2 Doc Alpha Wrap 2 PackageDescription (`Alpha_wrap_2/doc/Alpha_wrap_2/PackageDescription.txt`)

    /// \defgroup PkgAlphaWrap2Ref Reference Manual

    /// \defgroup PkgAlphaWrap2Concepts Concepts
    /// \ingroup PkgAlphaWrap2Ref

    /// \defgroup AW2_free_functions_grp Free Functions
    /// Functions to create a wrap from point clouds, segment soups, and polygons with holes.
    /// \ingroup PkgAlphaWrap2Ref

    /*!
    \addtogroup PkgAlphaWrap2Ref
    \cgalPkgDescriptionBegin{2D Alpha Wrapping,PkgAlphaWrap2}
    \cgalPkgPicture{alpha_wrap_2.png}
    \cgalPkgSummaryBegin
    \cgalPkgAuthors{Pierre Alliez, David Cohen-Steiner, Michael Hemmer, Cédric Portaneri, and Mael Rouxel-Labbé}
    \cgalPkgDesc{This component takes a polygon soup, a 2D segment soup, and/or a 2D point set as input,
    and generates a valid (watertight, intersection-free and 1-manifold) multi-polygon that
    strictly encloses the input. The algorithm proceeds by shrink-wrapping
    and refining a 2D Delaunay triangulation starting from a loose bounding box of the input.
    Two user-defined parameters, alpha and offset, offer control over the maximum size
    of cavities where the shrink-wrapping process can enter, and the tightness
    of the final polygon(s) to the input, respectively. Once combined, these parameters
    provide a means to trade fidelity to the input for complexity of the output.}
    \cgalPkgManuals{Chapter_2D_Alpha_wrapping,PkgAlphaWrap2Ref}
    \cgalPkgSummaryEnd
    \cgalPkgShortInfoBegin
    \cgalPkgSince{6.2}
    \cgalPkgDependsOn{\ref PkgTriangulation2 and \ref PkgPolygonRepair}
    \cgalPkgBib{cgal:achpr-aw2}
    \cgalPkgLicense{\ref licensesGPL "GPL"}
    \cgalPkgDemo{2D Alpha wrap demo,alpha_wrap_2.zip}
    \cgalPkgShortInfoEnd
    \cgalPkgDescriptionEnd

    \cgalClassifedRefPages

    \cgalCRPSection{Concepts}

    • AlphaWrapTraits_2

    \cgalCRPSection{Functions}

    • \link AW2_free_functions_grp CGAL::alpha_wrap_2() \endlink
      */

    Alpha Wrap 2 Doc Alpha Wrap 2 Alpha Wrap 2 (`Alpha_wrap_2/doc/Alpha_wrap_2/alpha_wrap_2.txt`)

    namespace CGAL {

    /*!

    \mainpage User Manual
    \anchor Chapter_2D_Alpha_wrapping
    \cgalAutoToc

    \authors Pierre Alliez, David Cohen-Steiner, Michael Hemmer, Cédric Portaneri, Mael Rouxel-Labbé

    \section aw2_introduction Introduction

    Various tasks in geometric modeling and processing require 2D objects represented as valid polygons,
    where "valid" refers to polygons that are closed, intersection-free (simple), orientable, and 1-manifold.
    Such representations offer well-defined notions of interior/exterior and geodesic neighborhoods.

    2D data are usually acquired through measurements, possibly followed by reconstruction,
    designed by humans, or generated through imperfect automated processes.
    As a result, they can exhibit a wide variety of defects including gaps, missing data,
    self-intersections, degeneracies such as zero-area structures, and non-manifold features.

    Given the large repertoire of possible defects, many methods and data structures have been proposed
    to repair specific defects (see for example the package \ref PkgPolygonRepair), usually with the goal
    of guaranteeing specific properties in the repaired 2D model.
    Reliably repairing all types of defects is an ill-posed problem as many valid solutions exist
    for a given 2D model with defects.
    In addition, the input model can be overly complex with unnecessary geometric details,
    spurious topological structures, nonessential inner components, or excessively fine discretizations.
    For applications such as collision avoidance, path planning, or simulation,
    getting an approximation (i.e., a silhouette) of the input can be more relevant than repairing it.
    Approximation herein refers to an approach capable of filtering out inner structures,
    fine details and cavities, as well as wrapping the input within a user-defined offset margin.

    Given an input 2D geometry, we address the problem of computing a conservative approximation,
    where conservative means that the output is guaranteed to strictly enclose the input.
    We seek unconditional robustness in the sense that the output polygon should be valid (oriented,
    1-manifold, and without self-intersections), even for raw input with many defects
    and degeneracies.
    The default input is a soup of 2D segments, but the generic interface leaves the door open
    to other types of finite 2D primitives such as point sets.

    \cgalFigureAnchor{aw2_inputs_fig}

    \cgalFigureCaptionBegin{aw2_inputs_fig}
    (Left) Shrink-wrapping output from a segment soup with many intersections and gaps.
    (Center & Right) Possible input degeneracies: non-manifold vertices and zero-area structures.
    The algorithm handles these cases by wrapping an offset of the input.
    \cgalFigureCaptionEnd

    \section aw2_definition Approach

    Many approaches have been devised to enclose a 2D model within a polygon, featuring different balances
    between the runtime and quality (i.e., tightness) of the approximation.
    Within the simplest cases, an axis-aligned or oriented bounding box clearly satisfies some desired properties;
    however, the approximation error is uncontrollable and often very large.
    Computing the convex hull of the input also matches some of the desired properties
    and improves the quality of the result, albeit at the price of increasing the runtime.
    However, the approximation remains crude, especially in the case of several components.

    The convex hull is, in fact, a special case of alpha shapes (\ref PkgAlphaShapes2).
    Mathematically, the alpha shape is a subcomplex of the Delaunay triangulation, with simplicies
    being part of the complex depending on the size of their minimal (empty) Delaunay ball.
    Intuitively, constructing 2D alpha shapes can be thought of as carving 2D space with an empty ball
    of user-defined radius alpha.
    Alpha shapes yield provable, good piecewise-linear approximations of a shape \cgalCite{bb-srmua-97t},
    but are defined on point sets, whereas we wish to deal with more general input data, such as segment soups.
    Even after sampling the segment soup, alpha shapes do not guarantee to be conservative for any alpha.
    Finally, inner structures are also carved within the interior, instead of being filtered out.

    Inspired by alpha shapes, we replace the above notion of carving by shrink-wrapping:
    we iteratively construct a subcomplex of a 2D Delaunay triangulation by starting from
    a simple 2D Delaunay triangulation enclosing the input, and then iteratively removing eligible triangles
    that lie on the boundary of the complex.
    In addition, the underlying triangulation---and thus the complex incidentally---is refined
    as shrinking proceeds.
    Thus, instead of carving from the convex hull of the input data as in alpha shapes, we construct
    an entirely new polygon through a Delaunay refinement-like algorithm. The refinement algorithm inserts Steiner points
    on the boundary of an offset surface, defined as a level set of the unsigned distance field to the input.

    This process both prevents the creation of inner structures within the output and avoids superfluous computations.
    In addition, detaching our wrap construction from the geometry and discretization of the input has several advantages:
    (1) the underlying data is not restricted to a specific format (polygon soups, segment soups, point sets, etc.)
    as all that is required is answering three basic geometric queries: (a) the distance between a point
    and the input, (b) the projection of a query point onto the input, (c) an intersection test
    between a triangle and the input, and (2) The user has more freedom to trade tightness
    to the input for final polygon complexity, as constructing a conservative approximation on a large offset
    of the input requires fewer polygon edges.

    \subsection aw2_algorithm Algorithm

    Initialization. The algorithm is initialized by inserting the four corner vertices
    of a loose bounding box into a 2D Delaunay triangulation.
    In the 2D Delaunay triangulation of \cgal, all edges are adjacent to two triangle faces.
    Each edge of the boundary of the Delaunay triangulation, which coincides with one edge
    of the convex hull of the triangulation vertices, is adjacent to a so-called infinite triangle face,
    an abstract face connected to the so-called infinite vertex to ensure the aforementioned double-edge adjacency.
    Initially, all infinite faces are tagged as outside, and all finite triangle faces are tagged as inside.

    Shrink-wrapping. The shrink-wrapping algorithm proceeds by traversing the faces
    of the Delaunay triangulation from outside to inside, flood-filling from one face to its adjacent face,
    and tagging the adjacent face as outside whenever possible (the term "possible" is specified later).
    Flood filling is implemented via a priority queue of Delaunay triangle edges representing
    the traversal between the two adjacent faces of the edge, from outside to inside.
    These edges are referred to as gates in the following.

    Given an outside face and its adjacent inside face, the common edge (i.e., a gate) is said
    to be alpha-traversable if its circumradius is larger than the user-defined parameter alpha,
    where circumradius refers to the radius of the relating segment's Delaunay ball.
    Intuitively, cavities smaller than alpha are not accessible as their gates are not alpha-traversable.

    Initialized by the alpha-traversable gates on the convex hull, the priority queue contains only
    alpha-traversable gates and is sorted by decreasing order of the circumradius of the gate.
    Traversal can be seen as a continuous process that advances along dual Voronoi edges of the gates,
    with a pencil of empty balls circumscribing the gate.

    \cgalFigureAnchor{aw2_pencil_fig}

    \cgalFigureCaptionBegin{aw2_pencil_fig}
    (Left) Pencil of empty circles (blue) circumscribing a Delaunay edge (green) in a 2D Delaunay triangulation (black).
    From the top triangle circumcenter c1 to the bottom triangle circumcenter c2, the dual Voronoi edge denoted by e (doted red) is the trace of centers of the largest circles that are empty of Delaunay vertex.
    (Right) The graph corresponding to the left example. The x-axis corresponds to the position of empty circle centers located on the Voronoi edge e, from c1 to c2. The y-axis is the radius value of the corresponding empty circles. In this case, the minimum radius of this pencil of empty circle is located at the midpoint of the green Delaunay edge.
    In our algorithm, a gate (green Delaunay edge) is said to be not alpha-traversable when the minimum radius of the pencil of empty circle is smaller than alpha.
    \cgalFigureCaptionEnd

    When traversing from an outside face \f$ f_o \f$ to an inside face \f$ f_i \f$ through an alpha-traversable edge \f$ e \f$,
    two criteria are tested to prevent the wrapping process from colliding with the input:

    (1) We check for an intersection between the dual Voronoi edge of \f$ e \f$, i.e., the segment between
    the circumcenters of the two incident faces, and the offset surface, defined as the level set
    of unsigned distance field to the input.
    If one or several intersections exists, the first intersection point, along the dual Voronoi edge
    oriented from outside to inside is inserted into the triangulation as a Steiner point.

    (2) If the dual Voronoi edge does not intersect the offset surface but the neighboring face \f$ f_i \f$
    intersects the input, we compute the projection of the circumcenter of \f$ f_i \f$
    onto the offset surface, and insert it into the triangulation as a Steiner point (which destroys \f$ f_i \f$).

    After each of the above Steiner point insertions, all new incident faces are tagged as inside,
    and the newly alpha-traversable gates are pushed into the priority queue.

    If none of the above two criteria are met, the neighboring face \f$ f_i \f$ is traversed and tagged as outside.
    Alpha-Traversable edges of \f$ f_i \f$ that are separating inside from outside faces are pushed as new gates into the priority queue.

    Once the queue empties---a process that is guaranteed as edges (and their circumradii) become smaller
    due to the insertion of new Steiner points---the construction phase terminates.
    The output (multi)polygon is extracted from the Delaunay triangulation as the set of edges
    separating inside from outside faces.

    The figure below depicts the steps of the algorithm.

    \cgalFigureAnchor{aw2_steps_fig}

    \cgalFigureCaptionBegin{aw2_steps_fig}
    Steps of the shrink-wrapping algorithm in 2D.
    The algorithm is initialized by inserting the corners of the loose bounding box of the input (red)
    into a Delaunay triangulation, and all finite triangles are tagged inside (grey).
    The current gate (green edge) popped out from the queue is alpha-traversable. The triangle adjacent
    to the gate is tagged outside when it does not intersect the input, and new alpha-traversable gates
    are pushed to the queue. When the adjacent triangle intersects the input, a new Steiner point (large green disc)
    is computed and inserted into the triangulation, all neighboring triangles are tagged inside,
    new alpha-traversable gates are pushed to the queue, and traversal is resumed.
    Grey edges depict the Delaunay triangulation. Blue edges depict the Voronoi diagram.
    Pink circles depict the empty circle of radius alpha. The output edges (dark blue) separate inside from outside triangles.
    \cgalFigureCaptionEnd

    \subsection aw2_guarantees Guarantees

    The algorithm is proven to terminate and to produce a set of 1-manifold, simple polygons
    that strictly enclose the input data.
    The key element to the proof is that we wrap from outside to inside and never allow a face
    that intersects the input to be flagged outside.
    Furthermore, both criteria that lead to refinement of the triangulation insert Steiner points
    that are guaranteed to break the faces in need of refinement and reduce the neighbor edges' circumradii.

    Because the main refinement criterion is the insertion of an intersection between a dual Voronoi edge
    and an offset of the input, or the projection of a Voronoi vertex onto the offset of the input,
    the algorithm has similarities to popular meshing algorithms based on Delaunay filtering
    and refinement (see \ref PkgMesh3).

    \section aw2_interface Interface

    Our algorithm takes as input a set of segments in 2D, provided either as a segment soup or
    as a set of polygons, and two user-defined scalar parameters: the alpha and the offset values.
    It proceeds by shrink-wrapping and refining a 2D Delaunay triangulation starting from a loose bounding box of the input.
    The parameter alpha refers to the size of cavities or holes that cannot be traversed during wrapping,
    and hence to the final level of detail, as alpha acts like a sizing field in a common Delaunay
    refinement algorithm (\ref PkgMesh3).
    The parameter offset refers to the distance between the vertices of the refined triangulation
    and the input, so that a large offset translates into a loose enclosing of the input.
    This second parameter offers a means to control the trade-off between tightness and complexity.

    The main entry point of the component is the global function CGAL::alpha_wrap_2() that generates the alpha wrap;
    this function takes as input a point set, a polyline soup, or a polygon soup.
    There is no prerequisite on the input connectivity so that it can take inputs
    with islands, self-intersections, or overlaps, as well as combinatorial or geometrical degeneracies.

    The underlying traits class must be a model of the AlphaWrapTraits_2 concept. It should use
    a floating point number type as inexactness is inherent to the algorithm since there is no closed
    form description of new vertices on the offset surface.

    The output is a multi polygon, i.e., a set of polygons, whose type is chosen by the user,
    under the constraint that it must be a model of the MultipolygonWithHoles_2 concept.

    A three-dimensional version of this package is also available: \ref PkgAlphaWrap3.

    \section aw2_parameters Choosing Parameters

    The two parameters of the algorithm impact both the level of detail and complexity of the output wrap.

    \subsection aw2_alpha Alpha

    The main parameter, alpha, controls whether a Delaunay edge is traversable during shrink-wrapping.
    Alpha's main purpose is to control the size
    of the empty balls used during wrapping, and thus to determine which features will appear in the output:
    indeed, an edge is alpha-traversable if its circumradius is larger than alpha; hence, the algorithm
    can only shrink-wrap through straits or holes with diameters larger than alpha.
    A second, less direct consequence is that as long as an edge has a circumradius larger than alpha,
    the incident inside face will be visited and possibly refined.
    Therefore, when the algorithm terminates, all edges have a circumradius smaller than alpha.
    This parameter thus also behaves like a sizing criterion on the edges of the output.

    \cgalFigureAnchor{aw2_alpha_param_fig}

    \cgalFigureCaptionBegin{aw2_alpha_param_fig}
    Impact of the alpha parameter on the output.
    (Left) The input segment soup, generated from an SVG file. The input
    has many self-intersections, non-manifold vertices, superfluous geometric details
    and spurious topological structures.
    (Middle & Right) This component approximates the input conservatively and produces valid polygons
    with different complexity and fidelity to the input, depending on the alpha parameter.
    The smaller the alpha, the deeper the shrink-wrapping process will enter cavities.
    The alpha parameter is decreasing from left to right, to respectively 1/20, 1/100, and 1/500 of the longest diagonal of the input bounding box.
    A large alpha will produce an output less complex but less faithful to the input.
    \cgalFigureCaptionEnd

    \subsection aw2_offset Offset

    The second parameter, the offset distance, controls the distance from the input and thus the definition
    of the offset isosurface onto which the vertices of the output polygon are located.
    This parameter controls the tightness of the result, which has, in turn, a few consequences.
    Firstly, locating vertices away from the input enables the algorithm to generate
    a less complex result, especially in convex areas. A trivial example of this behavior would be a very dense
    circle-shaped polygon, for which an as-tight-as-possible envelope would also need to be very dense.
    Secondly, the farther the isosurface is from the input, the more new points are inserted
    through the first criterion (i.e., through intersection with dual Voronoi edge, see Section \ref aw2_algorithm);
    thus, the quality of the output improves in terms of angles of the triangle elements.
    Finally, and depending on the value of the alpha parameter, a large offset can also offer defeaturing capabilities.
    However, using a small offset parameter will tend to better preserve sharp features as projection
    Steiner points tend to project onto convex sharp features.

    \cgalFigureAnchor{aw2_steiner_fig}

    \cgalFigureCaptionBegin{aw2_steiner_fig}
    Steiner points.
    The projection Steiner points (green) are computed by projecting the triangle circumcenter onto the offset.
    The intersection Steiner points (blue) are computed as the first intersection point between the Voronoi edge and the offset.
    (Left) When the offset parameter is small, the algorithm produces more projection Steiner points,
    which tends to improve the preservation of convex sharp features.
    (Right) When the offset parameter is large, the algorithm produces more intersection Steiner points.
    \cgalFigureCaptionEnd

    By default, we recommend to set the offset parameter to a small fraction of alpha, such that alpha
    becomes the main parameter that controls the final level of detail.

    The image below illustrates the impact of both parameters.

    \cgalFigureAnchor{aw2_param_grid_fig}

    \cgalFigureCaptionBegin{aw2_param_grid_fig}
    Different alpha and offset values on the bike model.
    The x-axis represents the offset value equal to 1/5000, 1/500, 1/50, and 1/5 of the longest diagonal of the input bounding box, from left to right.
    The y-axis represents the alpha value equal to 1/500, 1/50, and 1/5 of the longest diagonal of the input bounding box, from bottom to top.
    Depending on the alpha value, an offset too small or too large will produce outputs with higher complexity.
    For each alpha, the models with lower complexity can be used as a scale-space representations for collision detection, from near to far distances.
    \cgalFigureCaptionEnd

    \subsection aw2_two_side A Note on "Two-Sided" Wraps

    The offset parameter is crucial to our approach because it guarantees that the output is a
    set of 1-manifold, simple polygons.
    Indeed, and even when the input is a zero-area structure such as a single segment,
    the output wrap is a thin domain enclosing the said segment, see \cgalFigureRef{aw2_inputs_fig}.

    Users should keep in mind that the wrapping algorithm performs using an unsigned distance field,
    and has no means of determining whether it is acting on both sides of a same input segment.
    It will thus produce two-sided wraps in the case of holes in the input and
    values of alpha smaller than the size of the holes.

    \cgalFigureAnchor{aw2_double_sided_fig}

    \cgalFigureCaptionBegin{aw2_double_sided_fig}
    Wrapping a Bunny in 2D, with decreasing values for alpha.
    When alpha is small enough with respect the diameter of the holes, the algorithm generates a two-sided wrap.
    \cgalFigureCaptionEnd

    \section aw2_examples Examples

    \subsection aw2_examples_polylines Wrapping a Set of Polylines

    The following example illustrates how to construct the wrap of a soup of 2D segments.
    Alpha is set to 1/20 of the bounding box's longest diagonal edge length,
    and offset set to 1/30 of alpha (i.e., 1/600 of the bounding box diagonal edge length).

    \cgalExample{Alpha_wrap_2/polyline_wrap_2.cpp}

    \subsection aw2_examples_polygons Wrapping a Multipolygon

    For polygons, we use multipolygons to represent input sets of polygons (possibly with holes).
    The following example uses the \link IOStreamWKT WKT file format\endlink to read such input
    and wrap it. Note the possible usage of the \ref PkgPolygonRepair package if a pre-emptive
    repair of the polygons is desired.

    \cgalExample{Alpha_wrap_2/polygon_wrap_2.cpp}

    \subsection aw2_examples_points Wrapping a Point Cloud

    Finally, the following example demonstrates how to wrap a 2D point set constructed from the projection
    of an input 3D point cloud.

    \cgalExample{Alpha_wrap_2/point_set_wrap_2.cpp}

    */

    }


    Alpha Wrap 2 Doc Alpha Wrap 2 Examples (`Alpha_wrap_2/doc/Alpha_wrap_2/examples.txt`)

    /*!
    \example Alpha_wrap_2/polygon_wrap_2.cpp
    \example Alpha_wrap_2/polyline_wrap_2.cpp
    \example Alpha_wrap_2/triangle_soup_wrap_2.cpp
    \example Alpha_wrap_2/point_set_wrap_2.cpp
    */


    Alpha Wrap 3 Doc Alpha Wrap 3 PackageDescription (`Alpha_wrap_3/doc/Alpha_wrap_3/PackageDescription.txt`)

    /// \defgroup PkgAlphaWrap3Ref Reference Manual

    /// \defgroup AW3_free_functions_grp Free Functions
    /// Functions to create a wrap from point clouds, triangle soups, and triangle meshes.
    /// \ingroup PkgAlphaWrap3Ref

    /*!
    \addtogroup PkgAlphaWrap3Ref
    \cgalPkgDescriptionBegin{3D Alpha Wrapping,PkgAlphaWrap3}
    \cgalPkgPicture{alpha_wrap_3.jpg}
    \cgalPkgSummaryBegin
    \cgalPkgAuthors{Pierre Alliez, David Cohen-Steiner, Michael Hemmer, Cédric Portaneri, and Mael Rouxel-Labbé}
    \cgalPkgDesc{This component takes a 3D triangle mesh, a triangle soup, or a point set as input, and generates
    a valid triangulated surface mesh that strictly contains the input (watertight, intersection-free
    and 2-manifold). The algorithm proceeds by shrink-wrapping
    and refining a 3D Delaunay triangulation starting from a loose bounding box of the input.
    Two user-defined parameters, alpha and offset, offer control over the maximum size
    of cavities where the shrink-wrapping process can enter, and the tightness
    of the final surface mesh to the input, respectively. Once combined, these parameters
    provide a means to trade fidelity to the input for complexity of the output.}
    \cgalPkgManuals{Chapter_3D_Alpha_wrapping,PkgAlphaWrap3Ref}
    \cgalPkgSummaryEnd
    \cgalPkgShortInfoBegin
    \cgalPkgSince{5.5}
    \cgalPkgDependsOn{\ref PkgTriangulation3 and \ref PkgPolygonMeshProcessing}
    \cgalPkgBib{cgal:achpr-aw3}
    \cgalPkgLicense{\ref licensesGPL "GPL"}
    \cgalPkgShortInfoEnd
    \cgalPkgDescriptionEnd

    \cgalClassifedRefPages

    \cgalCRPSection{Functions}

    • \link AW3_free_functions_grp CGAL::alpha_wrap_3() \endlink
      */

    Alpha Wrap 3 Doc Alpha Wrap 3 Alpha Wrap 3 (`Alpha_wrap_3/doc/Alpha_wrap_3/alpha_wrap_3.txt`)

    namespace CGAL {

    /*!

    \mainpage User Manual
    \anchor Chapter_3D_Alpha_wrapping
    \cgalAutoToc

    \authors Pierre Alliez, David Cohen-Steiner, Michael Hemmer, Cédric Portaneri, Mael Rouxel-Labbé

    Note: a two-dimensional version of this package is also available: \ref PkgAlphaWrap2.

    \section aw3_introduction Introduction

    Various tasks in geometric modeling and processing require 3D objects represented as valid surface meshes,
    where "valid" refers to meshes that are watertight, intersection-free, orientable, and 2-manifold.
    Such representations offer well-defined notions of interior/exterior and geodesic neighborhoods.

    3D data are usually acquired through measurements followed by reconstruction, designed by humans,
    or generated through imperfect automated processes.
    As a result, they can exhibit a wide variety of defects including gaps, missing data,
    self-intersections, degeneracies such as zero-volume structures, and non-manifold features.

    Given the large repertoire of possible defects, many methods and data structures have been proposed
    to repair specific defects, usually with the goal of guaranteeing specific properties in the repaired 3D model.
    Reliably repairing all types of defects is notoriously difficult and is often an ill-posed problem
    as many valid solutions exist for a given 3D model with defects.
    In addition, the input model can be overly complex with unnecessary geometric details,
    spurious topological structures, nonessential inner components, or excessively fine discretizations.
    For applications such as collision avoidance, path planning, or simulation,
    getting an approximation of the input can be more relevant than repairing it.
    Approximation herein refers to an approach capable of filtering out inner structures,
    fine details and cavities, as well as wrapping the input within a user-defined offset margin.

    Given an input 3D geometry, we address the problem of computing a conservative approximation,
    where conservative means that the output is guaranteed to strictly enclose the input.
    We seek unconditional robustness in the sense that the output mesh should be valid (oriented,
    2-manifold, and without self-intersections), even for raw input with many defects
    and degeneracies.
    The default input is a soup of 3D triangles, but the generic interface leaves the door open
    to other types of finite 3D primitives such as triangle soups and point sets.

    \cgalFigureAnchor{aw3_input_1_fig}

    \cgalFigureCaptionBegin{aw3_input_1_fig}
    Shrink-wrapping output from a triangle soup, with many intersections and gaps.
    From left to right, input model, output wrap, and superposition.
    \cgalFigureCaptionEnd

    \cgalFigureAnchor{aw3_input_2_fig}

    \cgalFigureCaptionBegin{aw3_input_2_fig}
    Dealing with non-manifold features and degeneracies.
    From left to right, a non-manifold vertex, self-intersecting faces and two adjacent triangles
    representing a zero-volume structure.
    The algorithm handles these cases by wrapping an offset of the input.
    \cgalFigureCaptionEnd

    \section aw3_definition Approach

    Many approaches have been devised to enclose a 3D model within a volume, featuring different balances
    between the runtime and quality (i.e., tightness) of the approximation.
    Within the simplest cases, an axis-aligned or oriented bounding box clearly satisfies some desired properties;
    however, the approximation error is uncontrollable and often very large.
    Computing the convex hull of the input also matches some of the desired properties
    and improves the quality of the result, albeit at the price of increasing the runtime.
    However, the approximation remains crude, especially in the case of several components.

    The convex hull is, in fact, a special case of alpha shapes (\ref Chapter_3D_Alpha_Shapes).
    Mathematically, the alpha shape is a subcomplex of the Delaunay triangulation, with simplicies
    being part of the complex depending on the size of their minimal (empty) Delaunay ball.
    Intuitively, constructing 3D alpha shapes can be thought of as carving 3D space with an empty ball
    of user-defined radius alpha.
    Alpha shapes yield provable, good piecewise-linear approximations of a shape \cgalCite{bb-srmua-97t},
    but are defined on point sets, whereas we wish to deal with more general input data, such as triangle soups.
    Even after sampling the triangle soup, alpha shapes do not guarantee to be conservative for any alpha.
    Finally, inner structures are also carved within the volumes, instead of being filtered out.

    Inspired by alpha shapes, we replace the above notion of carving by shrink-wrapping:
    we iteratively construct a subcomplex of a 3D Delaunay triangulation by starting from
    a simple 3D Delaunay triangulation enclosing the input, and then iteratively removing eligible tetrahedra
    that lie on the boundary of the complex.
    In addition, the underlying triangulation---and thus the complex incidentally---is refined
    as shrinking proceeds.
    Thus, instead of carving from the convex hull of the input data as in alpha shapes, we construct
    an entirely new mesh through a Delaunay refinement-like algorithm. The refinement algorithm inserts Steiner points
    on the boundary of an offset volume, defined as a level set of the unsigned distance field to the input.

    This process both prevents the creation of inner structures within the output and avoids superfluous computations.
    In addition, detaching our mesh construction from the geometry and discretization of the input has several advantages:
    (1) the underlying data is not restricted to a specific format (triangle soups, polygon soups, point clouds, etc.)
    as all that is required is answering three basic geometric queries: (a) the distance between a point
    and the input, (b) the projection of a query point onto the input, (c) an intersection test
    between a tetrahedron and the input, and (2) The user has more freedom to trade tightness
    to the input for final mesh complexity, as constructing a conservative approximation on a large offset
    of the input requires fewer mesh elements.

    \subsection aw3_algorithm Algorithm

    Initialization. The algorithm is initialized by inserting the eight corner vertices
    of a loose bounding box into a 3D Delaunay triangulation.
    In the 3D Delaunay triangulation of \cgal, all triangle facets are adjacent to two tetrahedron cells.
    Each facet of the boundary of the Delaunay triangulation, which coincides with one facet
    of the convex hull of the triangulation vertices, is adjacent to a so-called infinite tetrahedron cell,
    an abstract cell connected to the so-called infinite vertex to ensure the aforementioned double-facet adjacency.
    Initially, all infinite cells are tagged as outside, and all finite tetrahedron cells are tagged as inside.

    Shrink-wrapping. The shrink-wrapping algorithm proceeds by traversing the cells
    of the Delaunay triangulation from outside to inside, flood-filling from one cell to its adjacent cell,
    and tagging the adjacent cell as outside whenever possible (the term possible is specified later).
    Flood filling is implemented via a priority queue of Delaunay triangle facets representing
    the traversal between the two adjacent cells of the facet, from outside to inside.
    These triangle facets are referred to as gates in the following.

    Given an outside cell and its adjacent inside cell, the common facet (i.e., a gate) is said
    to be alpha-traversable if its circumradius is larger than the user-defined parameter alpha,
    where circumradius refers to the radius of the relating triangle's Delaunay ball.
    Intuitively, cavities smaller than alpha are not accessible as their gates are not alpha-traversable.

    Initialized by the alpha-traversable gates on the convex hull, the priority queue contains only
    alpha-traversable gates and is sorted by decreasing order
    of the circumradius of the gate.
    Traversal can be seen as a continuous process that advances along dual Voronoi edges of the gates,
    with a pencil of empty balls circumscribing the gate.

    \cgalFigureAnchor{aw3_pencil_fig}

    \cgalFigureCaptionBegin{aw3_pencil_fig}
    (Left) Pencil of empty circles (blue) circumscribing a Delaunay edge (green) in a 2D Delaunay triangulation (black).
    From the top triangle circumcenter c1 to the bottom triangle circumcenter c2, the dual Voronoi edge denoted by e (doted red) is the trace of centers of the largest circles that are empty of Delaunay vertex.
    (Right) The graph corresponding to the left example. The x-axis corresponds to the position of empty circle centers located on the Voronoi edge e, from c1 to c2. The y-axis is the radius value of the corresponding empty circles. In this case, the minimum radius of this pencil of empty circle is located at the midpoint of the green Delaunay edge.
    In our algorithm, a gate (green Delaunay edge) is said to be not alpha-traversable when the minimum radius of the pencil of empty circle is smaller than alpha.
    \cgalFigureCaptionEnd

    When traversing from an outside cell \f$ c_o \f$ to an inside cell \f$ c_i \f$ through an alpha-traversable facet \f$ f \f$,
    two criteria are tested to prevent the wrapping process from colliding with the input:

    (1) We check for an intersection between the dual Voronoi edge of \f$ f \f$, i.e. the segment between
    the circumcenters of the two incident cells, and the offset surface, defined as the level set
    of unsigned isosurface to the input.
    If one or several intersections exists, the first intersection point, along the dual Voronoi edge
    oriented from outside to inside is inserted into the triangulation as a Steiner point.

    (2) If the dual Voronoi edge does not intersect the offset surface but the neighboring cell \f$ c_i \f$
    intersects the input, we compute the projection of the circumcenter of \f$ c_i \f$
    onto the offset surface, and insert it into the triangulation as a Steiner point (which destroys \f$ c_i \f$).

    After each of the above Steiner point insertions, all new incident cells are tagged as inside,
    and the newly alpha-traversable gates are pushed into the priority queue.

    If none of the above two criteria are met, the neighboring cell \f$ c_i \f$ is traversed and tagged as outside.
    Alpha-Traversable facets of \f$ c_i \f$ that are separating inside from outside cells are pushed as new gates into the priority queue.

    Once the queue empties---a process that is guaranteed as facets (and their circumradii) become smaller
    due to the insertion of new Steiner points---the construction phase terminates.
    The output triangle surface mesh is extracted from the Delaunay triangulation as the set of facets
    separating inside from outside cells.

    The figure below depicts the steps of the algorithm in 2D.

    \cgalFigureAnchor{aw3_steps_fig}

    \cgalFigureCaptionBegin{aw3_steps_fig}
    Steps of the shrink-wrapping algorithm in 2D.
    The algorithm is initialized by inserting the corners of the loose bounding box of the input (red)
    into a Delaunay triangulation, and all finite triangles are tagged inside (grey).
    The current gate (green edge) popped out from the queue is alpha-traversable. The triangle adjacent
    to the gate is tagged outside when it does not intersect the input, and new alpha-traversable gates
    are pushed to the queue. When the adjacent triangle intersects the input, a new Steiner point (large green disc)
    is computed and inserted into the triangulation, all neighboring triangles are tagged inside,
    new alpha-traversable gates are pushed to the queue, and traversal is resumed.
    Grey edges depict the Delaunay triangulation. Blue edges depict the Voronoi diagram.
    Pink circles depict the empty circle of radius alpha. The output edges (dark blue) separate inside from outside triangles.
    \cgalFigureCaptionEnd

    \subsection aw3_guarantees Guarantees

    The algorithm is proven to terminate and to produce a 2-manifold triangulated surface mesh
    that strictly encloses the input data.
    The key element to the proof is that we wrap from outside to inside and never allow a cell
    that intersects the input to be flagged outside.
    Furthermore, both criteria that lead to refinement of the triangulation insert Steiner points
    that are guaranteed to break the cells in need of refinement and reduce the neighbor facets circumradii.

    Because the main refinement criterion is the insertion of an intersection between a dual Voronoi edge
    and an offset of the input, or the projection of a Voronoi vertex onto the offset of the input,
    the algorithm has similarities to popular meshing algorithms based on Delaunay filtering
    and refinement (see \ref Chapter_3D_Mesh_Generation).

    \section aw3_interface Interface

    Our algorithm takes as input a set of triangles in 3D, provided either as a triangle soup or
    as a triangle surface mesh, and two user-defined scalar parameters: the alpha and the offset values.
    It proceeds by shrink-wrapping and refining a 3D Delaunay triangulation starting from a loose bounding box of the input.
    The parameter alpha refers to the size of cavities or holes that cannot be traversed during wrapping,
    and hence to the final level of detail, as alpha acts like a sizing field in a common Delaunay
    refinement algorithm (\ref Chapter_3D_Mesh_Generation).
    The parameter offset refers to the distance between the vertices of the refined triangulation
    and the input, so that a large offset translates into a loose enclosing of the input.
    This second parameter offers a means to control the trade-off between tightness and complexity.

    The main entry point of the component is the global function CGAL::alpha_wrap_3() that generates the alpha wrap;
    this function takes as input a polygon soup or a polygon mesh.
    There is no prerequisite on the input connectivity so that it can take an arbitrary triangle soup,
    with islands, self-intersections, or overlaps, as well as combinatorial or geometrical degeneracies.

    The underlying traits class must be a model of the Kernel concept. It should use
    a floating point number type as inexactness is inherent to the algorithm since there is no closed
    form description of new vertices on the offset surface.

    The output is a triangle surface mesh whose type is chosen by the user, under the constraint
    that it must be a model of the MutableFaceGraph concept.

    \section aw3_parameters Choosing Parameters

    The two parameters of the algorithm impact both the level of detail and complexity of the output mesh.

    \subsection aw3_alpha Alpha

    The main parameter, alpha, controls whether a Delaunay facet is traversable during shrink-wrapping.
    Alpha's main purpose is to control the size
    of the empty balls used during wrapping, and thus to determine which features will appear in the output:
    indeed, a facet is alpha-traversable if its circumradius is larger than alpha; hence, the algorithm
    can only shrink-wrap through straits or holes with diameters larger than alpha.
    A second, less direct consequence is that as long as a facet has a circumradius larger than alpha,
    the incident inside cell will be visited and possibly refined.
    Therefore, when the algorithm terminates, all facets have a circumradius smaller than alpha.
    This parameter thus also behaves like a sizing criterion on the triangle facets of the output.

    \cgalFigureAnchor{aw3_alpha_param_fig}

    \cgalFigureCaptionBegin{aw3_alpha_param_fig}
    Impact of the alpha parameter on the output.
    (Left) The input triangle mesh, generated by surface reconstruction from a raw point cloud,
    has many non-manifold edges and vertices, superfluous geometric details and spurious topological structures.
    (Right) This component approximates the input conservatively and produces valid meshes with different
    complexity and fidelity to the input, depending on the alpha parameter.
    The smaller the alpha, the deeper the shrink-wrapping process will enter cavities.
    The alpha parameter is decreasing from left to right, to respectively 1/50, 1/100 and 1/300 of the longest diagonal of the input bounding box.
    A large alpha will produce an output less complex but less faithful to the input.
    \cgalFigureCaptionEnd

    \subsection aw3_offset Offset

    The second parameter, the offset distance, controls the distance from the input and thus the definition
    of the offset isosurface onto which the vertices of the output mesh are located.
    This parameter controls the tightness of the result, which has, in turn, a few consequences.
    Firstly, locating vertices away from the input enables the algorithm to generate
    a less complex mesh, especially in convex areas. A trivial example of this behavior would be a very dense mesh
    of a sphere, for which an as-tight-as-possible envelope would also be very dense.
    Secondly, the farther the isosurface is from the input, the more new points are inserted
    through the first criterion (i.e., through intersection with dual Voronoi edge, see Section \ref aw3_algorithm);
    thus, the quality of the output improves in terms of angles of the triangle elements.
    Finally, and depending on the value of the alpha parameter, a large offset can also offer defeaturing capabilities.
    However, using a small offset parameter will tend to better preserve sharp features as projection
    Steiner points tend to project onto convex sharp features.

    \cgalFigureAnchor{aw3_offset_param_fig}

    \cgalFigureCaptionBegin{aw3_offset_param_fig}
    Impact of the offset parameter on the output.
    (Left) Input mesh generated by meshing a NURBS CAD model in parameter space.
    (Right) The smaller the offset, the closest sample points are to the input.
    The offset parameter is decreasing from left to right, to respectively 1/50, 1/200 and 1/1000 of the longest diagonal of the input bounding box.
    The alpha parameter is equal to 1/50 of the longest diagonal of the input bounding box for all level of details.
    A larger offset will produce an output less complex with better triangle quality.
    However, the sharp features (red edges) are well-preserved when the offset parameter is small.
    \cgalFigureCaptionEnd

    \cgalFigureAnchor{aw3_steiner_fig}

    \cgalFigureCaptionBegin{aw3_steiner_fig}
    Steiner points.
    The projection Steiner points (green) are computed by projecting the triangle circumcenter onto the offset.
    The intersection Steiner points (blue) are computed as the first intersection point between the Voronoi edge and the offset.
    (Left) When the offset parameter is small, the algorithm produces more projection Steiner points,
    which tends to improve the preservation of convex sharp features.
    (Right) When the offset parameter is large, the algorithm produces more intersection Steiner points,
    which tends to generate triangles with better quality in terms of angles, in 3D.
    \cgalFigureCaptionEnd

    By default, we recommend to set the offset parameter to a small fraction of alpha, such that alpha
    becomes the main parameter that controls the final level of detail.

    The image below illustrates the impact of both parameters.

    \cgalFigureAnchor{aw3_param_grid_fig}

    \cgalFigureCaptionBegin{aw3_param_grid_fig}
    Different alpha and offset values on the bike model (533,000 triangles).
    The x-axis represents the offset value equal to 1/5000, 1/2000, 1/500, 1/200, 1/50, 1/20 and 1/5 of the longest diagonal of the input bounding box, from left to right.
    The y-axis represents the alpha value equal to 1/300, 1/100, 1/50, 1/20 and 1/5 of the longest diagonal of the input bounding box, from bottom to top.
    The numbers below each level of detail represents their number of triangles.
    Depending on the alpha value, an offset too small or too large will produce output mesh with higher complexity.
    For each alpha, the models with lower complexity can be used as a scale-space representations for collision detection, from near to far distances.
    \cgalFigureCaptionEnd

    \subsection aw3_two_side A Note on "Two-Sided" Wraps

    The offset parameter is crucial to our approach because it guarantees that the output is a closed,
    2-manifold surface mesh.
    Indeed, and even when the input is a zero-volume structure such as a single 3D triangle,
    the output wrap is a thin volume enclosing the said triangle \cgalFigureRef{aw3_input_2_fig}.

    Users should keep in mind that the wrapping algorithm has no means of determining whether it is acting on the inside or the outside
    of the unsigned distance field, and will thus produce two-sided wraps in the case of holes in the input
    and values of alpha smaller than the size of the holes.

    \cgalFigureAnchor{aw3_double_sided_fig}

    \cgalFigureCaptionBegin{aw3_double_sided_fig}
    Two-sided wrap.
    (Left) Wrapping a Bunny in 2D, with decreasing values for alpha.
    (Right) Wrapping a defect-laden Bunny in 3D. The rightmost column depicts a clipped visualization
    of the inside. When alpha is small enough with respect the diameter of the holes, the algorithm generates a two-sided wrap.
    \cgalFigureCaptionEnd

    \section aw3_performance Performance

    The charts below plots the computation times of the wrapping algorithm on the Thingi10k dataset, as well as the complexity of the output triangle mesh.

    \cgalFigureAnchor{aw3_bench_fig}

    \cgalFigureCaptionBegin{aw3_bench_fig}
    Execution times and output complexity for different values of alpha on the Thingi10k data set.
    Alpha increases from 1/20 to 1/200 of the length of bounding box diagonal.
    The x-axis represents the complexity of the output wrap mesh in number of triangle facets.
    The y-axis represents the total computation time, in seconds.
    The color and diameter of the dots represent the number of faces in the input triangle soup,
    ranging from 10 (green) to 3154000 (blue).
    \cgalFigureCaptionEnd

    \section aw3_examples Examples

    Here is an example with an input triangle mesh, with alpha set to 1/20 of the bounding box's longest diagonal edge length,
    and offset set to 1/30 of alpha (i.e., 1/600 of the bounding box diagonal edge length).

    \cgalExample{Alpha_wrap_3/triangle_mesh_wrap.cpp}

    Some triangle soups might not be representable as a mesh due to non-manifoldness or incompatible orientations.
    Such triangle soup is nevertheless a valid input for the wrapping algorithm, as illustrated
    in the following example.

    \cgalExample{Alpha_wrap_3/triangle_soup_wrap.cpp}

    Here is an example with a point cloud.

    \cgalExample{Alpha_wrap_3/point_set_wrap.cpp}

    */

    }


    Alpha Wrap 3 Doc Alpha Wrap 3 Examples (`Alpha_wrap_3/doc/Alpha_wrap_3/examples.txt`)

    /*!
    \example Alpha_wrap_3/triangle_mesh_wrap.cpp
    \example Alpha_wrap_3/triangle_soup_wrap.cpp
    \example Alpha_wrap_3/point_set_wrap.cpp
    */


    Apollonius Graph 2 Doc Apollonius Graph 2 Apollonius Graph 2 (`Apollonius_graph_2/doc/Apollonius_graph_2/Apollonius_graph_2.txt`)

    namespace CGAL {
    /*!

    \mainpage User Manual
    \anchor Chapter_2D_Apollonius_Graphs
    \anchor chapterapollonius2
    \cgalAutoToc
    \authors Menelaos Karavelas and Mariette Yvinec

    This chapter describes the two-dimensional Apollonius graph
    of \cgal. We start with a few definitions in
    Section \ref secapollonius2definitions.
    The software design of the 2D Apollonius graph package is described
    in Section \ref secapollonius2design.
    In Section \ref secapollonius2traits we discuss the geometric
    traits of the 2D Apollonius graph package and in Section
    \ref secapollonius2hierarchy the Apollonius graph hierarchy, a data
    structure suitable for fast nearest neighbor queries, is briefly
    described.

    \section secapollonius2definitions Definitions

    \cgalFigureBegin{figapollonius,apollonius_diagram.png,apollonius_graph.png}
    The Apollonius diagram (left) and its dual the Apollonius graph (right).
    \cgalFigureEnd

    The 2D Apollonius graph class of \cgal is designed to compute the
    dual of the Apollonius diagram or, as it is also known, the
    Additively weighted Voronoi diagram. The algorithm that has been
    implemented is dynamic, which means that we can perform insertions and
    deletions online. The corresponding \cgal class is called
    Apollonius_graph_2<ApolloniusGraphTraits_2,ApolloniusGraphDataStructure_2>
    and will be discussed in more detail in the sequel. The interested
    reader may want to refer to the paper by Karavelas and Yvinec
    \cgalCite{cgal:ky-dawvd-02} for the general idea as well as the details of the
    algorithm implemented.

    Before describing the details of the implementation we make a brief
    introduction to the theory of Apollonius diagrams.
    The Apollonius diagram is defined over a set of sites
    \f$ P_i=(c_i,w_i)\f$, \f$ i=1,\ldots,n\f$, where \f$ c_i\f$ is the point and \f$ w_i\f$
    the weight of \f$ P_i\f$. It is a subdivision of the plane into connected
    regions, called cells, associated with the sites (see
    \cgalFigureRef{figapollonius} (left)). The cell of a
    site \f$ P_i\f$ is the locus of points on the plane that are
    closer to \f$ P_i\f$ than any other site \f$ P_j\f$, \f$ j\neq i\f$.
    The distance \f$ \delta(x, P_i)\f$ of a point \f$ x\f$ in the plane to a
    site \f$ P_i\f$ is defined as:
    \f[ \delta(x,P_i)=|x-c_i|-w_i, \f]
    where \f$ |\cdot|\f$ denotes the Euclidean norm.
    It can easily be seen that it is a generalization of the Voronoi
    diagram for points, which can actually be obtained if all the weights
    \f$ w_i\f$ are equal. Unlike the case of points, however, it is
    possible that a site \f$ P_i\f$ might have an empty cell. This
    can also happen in the case of the power diagram, whose dual is the
    regular triangulation (see Section
    \ref Section_2D_Triangulations_Regular ). If this is
    the case we call the site hidden (these are the black
    circles in \cgalFigureRef{figapollonius} ). A site which is not
    hidden will be referred to as visible.

    If all weights \f$ w_i\f$ are non-negative, the Apollonius
    diagram can be viewed as the Voronoi diagram of the set of circles
    \f$ {P_1,\ldots, P_n}\f$, where \f$ c_i\f$ is the center of the circle \f$ P_i\f$
    and \f$ w_i\f$ its radius. If the weights are allowed to be negative,
    we need to go to 3D in order to explain what the Apollonius diagram
    means geometrically. We identify the 2D Euclidean plane with the
    \f$ xy\f$-plane in 3D. Then the Voronoi diagram of a set of points can be
    seen as the vertical projection on the \f$ xy\f$-plane of the lower
    envelope of a set of 3D cones defined as follows: for each point \f$ p\f$
    in the set of 2D points we have a cone \f$ C_p\f$ whose apex is the point
    \f$ p\f$. The axis of
    \f$ C_p\f$ is a line parallel to the \f$ z\f$-axis passing through \f$ p\f$, the
    angle of \f$ C_p\f$ is \f$ 45^\circ\f$ and, finally \f$ C_p\f$ is facing in the
    positive \f$ z\f$-direction (that is, \f$ C_p\f$ is contained in the positive
    \f$ z\f$-halfspace).
    The Apollonius diagram corresponds to shifting the
    apexes of these cones in the \f$ z\f$-direction by a quantity equal to the
    weight. Sites with negative weight will give rise to
    cones whose apex is in the negative \f$ z\f$-halfspace and sites
    with positive weight will give rise to cones whose apex is in the
    positive \f$ z\f$-halfspace. In a manner analogous to the case of points,
    the Apollonius diagram can then be defined as the vertical projection
    on the \f$ xy\f$-plane of the lower envelope of the set of shifted cones.
    Notice that when all apexes are translated along the \f$ z\f$-direction by
    the same amount, the projection of the lower envelope of the set of
    cones does not change. In particular, we can translate all cones by a
    large enough amount so that all apexes are in the positive
    \f$ z\f$-halfspace. Algebraically, this means that the Apollonius diagram
    does not change if we add to all weights the same quantity, which in
    particular, implies that we can assume without loss of generality that
    all weights are positive. Given the observations above and in order to
    simplify our discussion of Apollonius diagrams, we will, from now on,
    assume that all weights are positive, and we will refer to the
    sites as circles.

    The Apollonius diagram is a planar graph, and so is its dual, the
    Apollonius graph. There are many ways to embed it on the plane and one
    such way is shown in \cgalFigureRef{figapollonius} (right).
    The Apollonius graph is uniquely defined once we have
    the Apollonius diagram. If the circles are in general position
    (see precise definition below), then the Apollonius graph is a graph
    with triangular faces away from
    the convex hull of the set of circles (by triangular we mean that
    every face has exactly three edges). Near the convex hull we may
    have some spikes (i.e., vertices of degree 1). To unify our approach
    and handling of the Apollonius graph we add to the set of (finite)
    circles a fictitious circle at infinity, which we call the
    site at infinity. We can then connect all vertices of the outer
    face of the Apollonius graph to the site at infinity which gives us
    a graph with the property that all of its faces are now
    triangular. However, the Apollonius graph is not a triangulation for
    two main reasons: we cannot always embed it on the plane with straight
    line segments that yield a triangulation and, moreover, we may have two
    faces of the graph that have two edges in common, which is not allowed
    in a triangulation. Both of these particularities appear when we
    consider the Apollonius graph of the set of circles in
    \cgalFigureRef{figapollonius}.

    We would like to finish our brief introduction to the theory of
    Apollonius graphs by discussing the concept of general position. We say
    that a set of circles is in general position if no two triplets of
    circles have the same tritangent circle. This statement is rather
    technical and it is best understood in the context of points. The
    equivalent statement for points is that we have no two triplets of
    points that define the same circumcircle, or equivalently that no
    four points are co-circular. The statement about general position made
    above is a direct generalization of the (much simpler to understand)
    statement about points. On the contrary, when we have circles in
    degenerate position, the Apollonius graph has faces with more than
    three edges on their boundary. We can get a triangulated version of
    the graph by simply triangulating the corresponding faces in an
    arbitrary way. In fact the algorithm that has been implemented in
    \cgal has the property that it always returns a valid
    triangulated version of the Apollonius graph. By valid we mean
    that it contains the actual Apollonius graph (i.e., the actual dual of
    the Apollonius diagram) and whenever there are faces with more than
    three faces then they are triangulated. The way that they are
    triangulated depends on the order of insertion and deletion of the
    circles in the diagram.

    One final point has to be made about hidden circles. First of all we
    would like to be more precise about our definition of hidden circles:
    we say that a circle is hidden if its cell has empty interior. This
    definition allows us to guarantee that all visible circles have
    cells that are two-dimensional regions.
    Geometrically the fact that a circle is hidden means that it is
    contained in the closure of the disk of another circle (see again
    \cgalFigureRef{figapollonius} ). Note that a circle contained in the union
    of several disks, but not in the closure of any one of them, is not
    hidden.

    Hidden circles pose an additional
    difficulty to our algorithm and software design. Since we allow
    circles to be inserted and deleted at will, it is possible that a
    circle that was hidden at some point in time, may become visible at
    a later point in time; for example this can happen if we delete the
    circle that hides it. For this purpose we store hidden circles and
    have them reappear when they become visible. We will discuss this
    issue in detail below. For the time being it suffices to say that the
    user has the ability to control this behavior. More specifically it is
    possible to discard the circles that become hidden. This choice is
    totally natural when for example we expect to do only insertions,
    since in this case a circle that becomes hidden will never
    reappear. On the other hand if deletions are expected as well, then we
    lose the ability to have the hidden circles reappear.

    Degenerate Dimensions.

    The dimension of the Apollonius graph is in general 2. The exceptions
    to this rule are as follows:

  • The dimension is \f$ -1\f$ if the Apollonius graph contains no circles.
  • The dimension is \f$ 0\f$ if the Apollonius graph contains exactly one visible circle.
  • The dimension is \f$ 1\f$ is the Apollonius graph contains exactly two visible circles.

    \section secapollonius2design Software Design

    The 2D Apollonius graph class
    Apollonius_graph_2<ApolloniusGraphTraits_2,ApolloniusGraphDataStructure_2>
    follows the design of the triangulation packages of \cgal. It is
    parametrized by two arguments:

  • the **geometric traits** class. It provides the basic geometric objects involved in the algorithm, such as sites, points etc. It also provides the geometric predicates for the computation of the Apollonius graph, as well as some basic constructions that can be used, for example, to visualize the Apollonius graph or the Apollonius diagram. The geometric traits for the Apollonius graph will be discussed in more detail in the next section.
  • the **Apollonius graph data structure**. This is essentially the same as the triangulation data structure (discussed in Chapter \ref Chapter_2D_Triangulation_Data_Structure ), augmented with some additional operations that are specific to Apollonius graphs. The corresponding concept is that of `ApolloniusGraphDataStructure_2`, which in fact is a refinement of the `TriangulationDataStructure_2` concept. The class `Triangulation_data_structure_2` is a model of the concept `ApolloniusGraphDataStructure_2`. A default value for the corresponding template parameter is provided, so the user does not need to specify it.

    Storing Hidden Sites.

    As we have already mentioned a circle is hidden if it is contained
    inside some visible circle. This creates a parent-child relationship
    between visible and hidden circles: the parent of a hidden circle is the
    visible circle that contains it. If more than one visible circles
    contain a hidden circle then the hidden circle can be assigned to any of
    the visible circles arbitrarily.

    To store hidden circles we assign to every visible circle a list. This
    list comprises the hidden circles that are contained in the
    visible circle. The user can access the hidden circles associated with
    a visible circle through an iterator called
    Hidden_sites_iterator. This iterator is defined in the
    ApolloniusGraphVertexBase_2 concept and is implemented by its
    model, the Apollonius_graph_vertex_base_2<Gt,StoreHidden>
    class. It is also possible to iterate through the entire set of hidden
    sites using a homonymous iterator defined by the
    Apollonius_graph_2<Gt,Agds> class.

    Since storing hidden sites may not be of interest in some cases (e.g.,
    for example this is the case if we only perform insertions in the
    Apollonius graph), the user has the possibility of controlling this
    behavior. More precisely, the class
    Apollonius_graph_vertex_base_2<Gt,StoreHidden> has two template
    parameters, the second of which is a Boolean value. This value is by
    default true and it indicates that hidden sites should be
    stored. The user can indicate that hidden sites may be discarded
    by setting this value to false.

    \section secapollonius2traits The Geometric Traits

    The predicates required for the computation of the Apollonius graph
    are rather complicated. It is not the purpose of this document to
    discuss them in detail. The interested reader may refer to the papers
    by Karavelas and Emiris for the details
    \cgalCite{cgal:ke-ppawv-02}, \cgalCite{cgal:ke-rctac-03}. However, we would like to give a brief
    overview of what they
    compute. There are several predicates needed by this algorithm. We
    will discuss the most important/complicated ones. It turns out that
    it is much easier to describe them in terms of the Apollonius diagram,
    rather than the Apollonius graph. Whenever it is applicable we will also
    describe their meaning in terms of the Apollonius graph.

    The first two geometric predicates are called
    Is_hidden_2 and Oriented_side_of_bisector_2. The first one
    involves two circles, say \f$ P_1\f$ and \f$ P_2\f$. It determines if \f$ P_1\f$ is
    hidden with respect to \f$ P_2\f$; more precisely it checks whether the
    circle \f$ P_1\f$ is contained in the closure of the disk defined by the
    circle \f$ P_2\f$. As its name indicates, it determines if a circle is
    hidden or not. The second predicate involves two circles \f$ P_1\f$ and
    \f$ P_2\f$ and a point \f$ q\f$. It answers the question whether \f$ q\f$ is closer
    to \f$ P_1\f$ or \f$ P_2\f$. Its name stems from the fact that answering the
    aforementioned question is equivalent to determining the oriented
    side of the bisector of \f$ P_1\f$ and \f$ P_2\f$ that contains the query point
    \f$ q\f$. This predicate is used by the algorithm for closest neighbor
    queries for points.

    The next geometric predicate is called Vertex_conflict_2 and it
    involves four circles \f$ P_1\f$, \f$ P_2\f$, \f$ P_3\f$, and \f$ P_4\f$ (see
    \cgalFigureRef{figag2vc} ). The first three (red circles in
    \cgalFigureRef{figag2vc} ) define a tritangent circle (yellow
    circle in \cgalFigureRef{figag2vc} ). What we want to determine is
    the sign of the distance of the green circle from the yellow
    circle. The distance between two circles \f$ K_1=(c_1,r_1)\f$ and
    \f$ K_2=(c_2, r_2)\f$ is defined as the distance of their centers minus
    their radii:
    \f[ \delta(K_1, K_2) = |c_1-c_2|-r_1-r_2. \f]
    This predicate determines if a vertex in the Apollonius diagram
    (the center of the yellow circle) is destroyed when a new circle is
    inserted in the diagram (the green circle). In the Apollonius graph
    it tells us if a triangular face of the diagram is to be destroyed or
    not.

    \cgalFigureBegin{figag2vc,apollonius-vertex_conflict-false.png,apollonius-vertex_conflict-true.png}
    The Vertex_conflict_2 predicate. The left-most, bottom-most and top-most circles define the tritangent circle in the middle. We want to determine the sign of the distance of the left-most circle from the one in the middle. The almost horizontal curve is the bisector of the top-most and bottom-most circles. Left: the predicate returns NEGATIVE. Right: the predicate returns POSITIVE.
    \cgalFigureEnd

    What we essentially want to compute when we construct incrementally a
    Voronoi diagram, is whether the object to be inserted destroys an edge
    of the Voronoi diagram or not. In the case of points this is really
    easy and it amounts to the well-known incircle test.
    In the case
    of circles the situation is more complicated. We can have six possible
    outcomes as to what portion of an edge of the Apollonius diagram the
    new circle destroys (see \cgalFigureRef{figag2edgeconflict} ). The first
    two can be answered directly by the Vertex_conflict_2 predicate
    evaluated for the two endpoints of the Apollonius diagram edge. This
    is due to the fact that the value of the Vertex_conflict_2
    predicate is different for the two endpoints. If the two values are
    the same then we need an additional test which determines if the interior
    of the Apollonius diagram edge is destroyed by the new circle. This is
    what the Finite_edge_interior_conflict_2 and
    Infinite_edge_interior_conflict_2 predicates do. In essence, it
    is the same predicate (same idea) applied to two different types of
    edges in the Apollonius diagram: a finite or an infinite edge. An edge
    is infinite if its dual edge in the Apollonius graph connects the
    site at infinity with the vertex corresponding to a (finite) circle;
    otherwise it is a finite edge.

    \cgalFigureAnchor{figag2edgeconflict}

    | \image html ./apollonius-left_vertex.png
    \image latex ./apollonius-left_vertex.png | \image html ./apollonius-right_vertex.png

    \image latex ./apollonius-right_vertex.png |
    | --- | --- |
    | \image html ./apollonius-no_conflict.png
    \image latex ./apollonius-no_conflict.png | \image html ./apollonius-entire_edge.png
    \image latex ./apollonius-entire_edge.png |
    | \image html ./apollonius-interior.png
    \image latex ./apollonius-interior.png | \image html ./apollonius-both_vertices.png
    \image latex ./apollonius-both_vertices.png |

    \cgalFigureCaptionBegin{figag2edgeconflict}
    The 6 possible outcomes of the
    Finite_edge_interior_conflict_2 predicate. Top left: only a
    neighborhood around the left-most endpoint of the edge will be
    destroyed. Top right: only a neighborhood around the right-most
    endpoint of the edge will be destroyed. Middle left: no portion of the
    edge is destroyed. Middle right: the entire edge will be
    destroyed. Bottom left: a neighborhood in the interior of the edge
    will be destroyed; the regions near the endpoints remain
    unaffected. Bottom right: The neighborhood around the two endpoints
    will be destroyed, but an interval in the interior of the edge will
    remain in the new diagram.
    \cgalFigureCaptionEnd

    The last predicate that we want to discuss is called
    Is_degenerate_edge_2. It tells us whether an edge in the
    Apollonius diagram is degenerate, that is if its two endpoints
    coincide. In the Apollonius graph such an edge corresponds to one of
    the additional edges that we use to triangulate the non-triangular
    faces.

    The aforementioned predicates are part of the
    ApolloniusGraphTraits_2 concept of \cgal. \cgal also provides
    a model for this concept, the
    Apollonius_graph_traits_2<K,Method_tag> class. The first
    template parameter of this class must be a model of the Kernel
    concept. The second template parameter is a tag that indicates what
    operations are allowed in the computations that take place within the
    traits class.
    The two possible values of the Method_tag parameter are
    Integral_domain_without_division_tag and Field_with_sqrt_tag. When
    Integral_domain_without_division_tag is used, only ring operations are used during the
    evaluation of the predicates, whereas if Field_with_sqrt_tag is
    chosen, all four field operations, as well as square roots, are used
    during the predicate evaluation.

    The Apollonius_graph_traits_2<K,Method_tag> class provides exact
    predicates if the number type in the kernel K is an exact number
    type. This is to be associated with the type of operations allowed for
    the predicate evaluation. For example MP_Float as number
    type, with Integral_domain_without_division_tag as tag will give exact predicates,
    whereas MP_Float with Field_with_sqrt_tag will give
    inexact predicates.

    Although exact number types provide exact predicates and constructions,
    their use often results in unacceptably large runtimes.
    The class Apollonius_graph_filtered_traits_2<CK,CM,EK,EM,FK,FM>
    aims to paliate this shortcoming. Similar to a filtered kernel, it takes a
    constructions kernel CK, a filtering kernel FK and an
    exact kernel EK, as well as the corresponding tags
    (CM, FM and EM, respectively).
    Predicates are evaluated by first using the filtering kernel, and
    if this fails the evaluation is performed using the exact kernel,
    thus yielding exact predicates at a generally much cheaper cost
    than directly using an exact number type. The constructions
    are done using the kernel CK, which means that
    they are not necessarily exact. All template parameters except
    CK have default values, which are explained in the reference
    manual.

    \section secapollonius2hierarchy The Apollonius Graph Hierarchy

    The Apollonius_graph_hierarchy_2<ApolloniusGraphTraits_2,ApolloniusGraphDataStructure_2> class is nothing but the equivalent of the Triangulation_hierarchy_2
    class, applied to the Apollonius graph. It consists of a series of
    Apollonius graphs constructed in a manner analogous to the Delaunay
    hierarchy by Devillers \cgalCite{d-iirdt-98}. The class
    Apollonius_graph_hierarchy_2<ApolloniusGraphTraits_2,ApolloniusGraphDataStructure_2>
    has exactly the same interface and functionality as the
    Apollonius_graph_2<ApolloniusGraphTraits_2,ApolloniusGraphDataStructure_2>
    class. Using the Apollonius graph hierarchy involves an additional
    cost in space and time for maintaining the hierarchy. Our experiments
    have shown that it usually pays off to use the hierarchy for inputs
    consisting of more than 1,000 circles. This threshold holds for both
    the construction of the Apollonius diagram itself, as well as for
    nearest neighbor queries.

    \section secapollonius2examples Examples

    \subsection Apollonius_graph_2FirstExample First Example

    \cgalExample{Apollonius_graph_2/ag2_exact_traits.cpp}

    \subsection Apollonius_graph_2SecondExample Second Example

    \cgalExample{Apollonius_graph_2/ag2_exact_traits_sqrt.cpp}

    \subsection Apollonius_graph_2ThirdExample Third Example

    \cgalExample{Apollonius_graph_2/ag2_filtered_traits_no_hidden.cpp}

    \subsection Apollonius_graph_2FourthExample Fourth Example

    \cgalExample{Apollonius_graph_2/ag2_hierarchy.cpp}

    /
    } /
    namespace CGAL */


    Apollonius Graph 2 Doc Apollonius Graph 2 PackageDescription (`Apollonius_graph_2/doc/Apollonius_graph_2/PackageDescription.txt`)

    /// \defgroup PkgApolloniusGraph2Ref Reference Manual
    /// \defgroup PkgApolloniusGraph2Concepts Concepts
    /// \ingroup PkgApolloniusGraph2Ref
    /*!
    \addtogroup PkgApolloniusGraph2Ref
    \cgalPkgDescriptionBegin{2D Apollonius Graphs (Delaunay Graphs of Disks),PkgApolloniusGraph2}
    \cgalPkgPicture{CircleVoronoi.png}
    \cgalPkgSummaryBegin
    \cgalPkgAuthors{Menelaos Karavelas and Mariette Yvinec}
    \cgalPkgDesc{Algorithms for computing the Apollonius graph in two dimensions. The Apollonius graph is the dual of the Apollonius diagram, also known as the additively weighted Voronoi diagram. The latter can be thought of as the Voronoi diagram of a set of disks under the Euclidean metric, and it is a generalization of the standard Voronoi diagram for points. The algorithms provided are dynamic.}
    \cgalPkgManuals{Chapter_2D_Apollonius_Graphs,PkgApolloniusGraph2Ref}
    \cgalPkgSummaryEnd
    \cgalPkgShortInfoBegin
    \cgalPkgSince{3.0}
    \cgalPkgDependsOn{\ref PkgTDS2}
    \cgalPkgBib{cgal:ky-ag2}
    \cgalPkgLicense{\ref licensesGPL "GPL"}
    \cgalPkgDemo{2D Apollonius Graph,apollonius_graph_2.zip}
    \cgalPkgShortInfoEnd
    \cgalPkgDescriptionEnd

    An Apollonius graph is the dual of the Apollonius diagram, also known
    as the additively weighted Voronoi diagram. It is essentially the
    Voronoi diagram of a set of disks, where the distance of a
    point of the plane from a disk is defined as the Euclidean
    distance of the point and the center of the circle, minus the radius
    of the disk.

    \cgal provides the class CGAL::Apollonius_graph_2<Gt,Agds> for
    computing the 2D Apollonius graph. The two template parameters must be
    models of the ApolloniusGraphTraits_2 and
    ApolloniusGraphDataStructure_2 concepts. The first concept is
    related to the geometric objects and predicates associated with
    Apollonius graphs, whereas the second concept refers to the data
    structure used to represent the Apollonius graph. The classes
    Apollonius_graph_traits_2<K,Method_tag> and
    Triangulation_data_structure_2<Vb,Fb> are models of the
    aforementioned concepts.

    \cgalClassifedRefPages

    \cgalCRPSection{Concepts}

    • ApolloniusSite_2
    • ApolloniusGraphTraits_2
    • ApolloniusGraphDataStructure_2
    • ApolloniusGraphVertexBase_2
    • ApolloniusGraphHierarchyVertexBase_2

    \cgalCRPSection{Classes}

    • CGAL::Apollonius_graph_2<Gt,Agds>
    • CGAL::Apollonius_site_2<K>
    • CGAL::Apollonius_graph_traits_2<K,Method_tag>
    • CGAL::Apollonius_graph_filtered_traits_2<CK,CM,EK,EM,FK,FM>
    • CGAL::Apollonius_graph_vertex_base_2<Gt,StoreHidden>
    • CGAL::Apollonius_graph_hierarchy_2<Gt,Agds>
    • CGAL::Apollonius_graph_hierarchy_vertex_base_2<Agvb>

    */


    Apollonius Graph 2 Doc Apollonius Graph 2 Examples (`Apollonius_graph_2/doc/Apollonius_graph_2/examples.txt`)

    /*!
    \example Apollonius_graph_2/ag2_exact_traits.cpp
    \example Apollonius_graph_2/ag2_exact_traits_sqrt.cpp
    \example Apollonius_graph_2/ag2_filtered_traits_no_hidden.cpp
    \example Apollonius_graph_2/ag2_hierarchy.cpp
    */


    Arrangement On Surface 2 Doc Arrangement On Surface 2 Arrangement On Surface 2 (`Arrangement_on_surface_2/doc/Arrangement_on_surface_2/Arrangement_on_surface_2.txt`)

    namespace CGAL {
    /*!

    \mainpage User Manual
    \anchor Chapter_2D_Arrangements
    \anchor chapterArrangement_on_surface_2
    \cgalAutoToc

    \authors Ron Wein, Eric Berberich, Efi Fogel, Dan Halperin,
    Michael Hemmer, Oren Salzman, and Baruch Zukerman

    \section aos_sec-intro Introduction

    Geometric arrangements, or arrangements for short, are subdivisions of
    some space induced by geometric objects.
    \cgalFigureRef{aos_fig-simple_arr} shows an arrangement of two curves
    \f$c_1\f$ and \f$c_2\f$ in the plane. It has three faces—two
    bounded faces \f$f_1\f$ and \f$f_2\f$ (filled with diagonal-stripe
    patterns) and an unbounded face. The arrangement has seven
    vertices—four represent the endpoints of \f$c_1\f$ and \f$c_2\f$
    (drawn as small discs), and three represent the intersection points of
    the two curves (drawn as small rings). The arrangement also has eight
    edges, each of which is a maximal portion of one curve not
    intersecting the other.

    \cgalFigureBegin{aos_fig-simple_arr,simple_arr.png}
    \cgalFigureEnd

    Arrangements are not restricted to curves in the plane. There are
    useful arrangements in three and higher dimensions (these are not so
    easy to visualize) and they can be induced by geometric objects of any
    type, such as spheres, simplices, polytopes, or Bézier
    surfaces. This package provides a data structure that represents a
    two-dimensional arrangement of curves embedded in an orientable
    parametric surface in three dimensional space, such as a plane, a
    cylinder, a sphere, a torus, or a surface homeomorphic to them. This
    package also provides operations that construct and manipulate such
    arrangements. Arrangements are ubiquitous in the
    computational-geometry literature and have many applications; see,
    e.g., \cgalCite{as-aa-00}, \cgalCite{cgal:bfhks-apsca-10},
    \cgalCite{cgal:bfhmw-apsgf-10}, and \cgalCite{cgal:h-a-04}.

    \subsection aos_ssec-intro-sep Separation of Topology and Geometry

    The use of the generic programming paradigm enables a convenient
    separation of the topology and the geometry of data
    structures.\cgalFootnote{In this context, we sometimes say
    combinatorics instead of topology, and say algebra or
    numerics instead of geometry. We always mean the same
    thing---the separation of the abstract, graph-like structure (the
    topology) from the actual embedding in the plane (the geometry).}
    This is a key aspect in the design of geometric software, and is put
    into practice, for example, in the design of \cgal polyhedra, \cgal
    triangulations, and our \cgal arrangements. This separation allows the
    convenient abstraction of algorithms and data structures in
    combinatorial and topological terms, regardless of the specific
    geometry of the objects at hand. This abstraction is realized through
    class and function templates that represent specific data structures
    and algorithmic frameworks, respectively. Consider the class template

    \code{.cpp}
    template <typename GeometryTraits, typename Dcel>
    class Arrangement_2 { ... };
    \endcode

    An instance of this template represents an arrangement embedded in the
    plane. When the template is instantiated, the GeometryTraits
    parameter must be substituted by a type that defines a set of
    geometric-object types, such as point and curve, and a set of
    operations on objects of these types (see Section \ref
    aos_sec-geom_traits); the Dcel parameter must be substituted by a
    type that represents a doubly-connected edge list (\dcel) data
    structure. It defines types of topological objects, such as vertices,
    edges, and faces, and the operations required to maintain the
    incidence relations among objects of these types (see Section \ref
    aos_ssec-basic-dcel).

    The class template Arrangement_2 derives from the following class
    template:

    \code{.cpp}
    template <typename GeometryTraits, typename TopologyTraits>
    class Arrangement_on_surface_2 { ... };
    \endcode

    An instance of this template represents a two-dimensional arrangement
    embedded in a surface in three dimensional space. When the template is
    instantiated, the GeometryTraits parameter must be substituted as
    described above; the TopologyTraits parameter must be substituted
    by a type that deals with the topology of the surface (see Section
    \ref aos_sec-topol_traits). In particular, it maintains a
    representation of the arrangement graph embedded in the surface using
    a doubly-connected edge list (\dcel) data-structure suitable for
    the particular topology.

    Several member functions and nested types defined in the
    Arrangement_2 derived class-template inherit their definitions from
    the base class-template Arrangement_on_surface_2; their semantics is
    equivalent in both class templates. The names of these member
    functions and nested types typically appear in the manual without any
    scope, as each of these class templates can serve as their scope. (As
    a matter of fact, the package provides additional class templates that
    represent two-dimensional arrangements, such as the
    Arrangement_with_history_2 class template, which derives from the
    class template Arrangement_2; these additional class templates also
    contain inherited definitions of the aforementioned member functions
    and nested types.)

    An immediate advantage of the separation of the topology and the
    geometry of data structures is that users with limited expertise in
    computational geometry can employ the data structure with their own
    special type of objects. They must, however, supply the relevant
    traits class, which mainly involves algebraic computations. A traits
    class also encapsulates the number types used to represent coordinates
    of geometric objects and to carry out algebraic operations on them. It
    encapsulates the type of coordinate system used (e.g., %Cartesian and
    homogeneous), and the geometric or algebraic computation methods
    themselves. The precise minimal sets of requirements the actual traits
    classes must conform to are organized as a hierarchy of concepts; see
    Section \ref aos_sec-geom_traits.

    \subsection aos_ssec-intro-well_behaved Well-Behaved Curves

    What constitutes valid curves that can be handled by the \ref
    PkgArrangementOnSurface2 package is discussed in detail in Section
    \ref aos_sec-geom_traits, where the models of the traits classes are
    described. However, when we cite combinatorial complexity bounds or
    bounds on the resources (i.e., running time and storage space)
    required by algorithms, we often postulate stricter assumptions on the
    input curves. The prevalent term in use is that the curves are
    well behaved, which may have different interpretations in
    different settings. If we are concerned with combinatorial complexity
    bounds for curves embedded in a two-dimensional surface, then the
    standard assumptions are that (i) each curve is non-self-intersecting
    (a so-called Jordan arc) and (ii) every pair of curves intersects in
    at most some constant number of points. For algorithmic purposes we
    need to require more since we assume that any operation on a small
    constant number of curves takes unit time. In this sense arcs of
    algebraic curves of degree bounded by a constant (namely the zero set
    of bivariate polynomials of constant maximum total degree) are well
    behaved. Naturally, what are typically considered well-behaved
    surfaces in \f$\mathbb{R}^3\f$ is even more complicated to state.

    Remarks

    1. From the complexity-bound perspective, most of the arrangements that we can deal with can be regarded as defined by well-behaved curves. Even though the package allows for self-intersecting curves, for most types each curve can be decomposed into a constant number of well-behaved curves, thus having no effect on the asymptotic bounds that we state.
    2. One type of curves that we deal with is special in this sense: *polylines*, namely concatenations of an unlimited number of line segments; see Section \ref arr_sssectr_polylines. A polyline is not well behaved, as it cannot be decomposed into a constant number of constant-descriptive complexity subcurves. Informative bounds for arrangements of polylines are expressed by other parameters in addition to the number of polylines, for example, the total number of segments in all the polylines together. The same holds for the more general type *polycurve*, which are piecewise curves that are not necessarily linear; see Section \ref arr_sssectr_polycurves.

    \subsection aos_ssec-intro-outline Outline

    In Section \ref aos_sec-basic we provide the minimum material you need
    to know in order to use \cgal 2D arrangements in the plane. In Section
    \ref aos_sec-curved_surfaces we provide additional material you need
    to know in order use \cgal 2D arrangements embedded in curved
    surfaces. Most of the succeeding material is oblivious to the type of
    the embedding surface. In Section \ref arr_secqueries we show how
    queries on an arrangement can be issued. In Section \ref
    arr_secgl_funcs we review some useful free (global) functions that
    operate on arrangements, the most important ones being the free
    insertion-functions. In Section \ref aos_sec-unbounded we explain how
    to construct and manipulate arrangements of unbounded curves. Section
    \ref aos_sec-geom_traits contains detailed descriptions of the
    geometric traits concept hierarchy and the various geometric traits
    classes included in the \ref PkgArrangementOnSurface2 package. The
    different traits classes enables the construction and manipulation of
    arrangements of different families of curves. Naturally, here, the
    embedding surface plays a significant role. In Section \ref
    arr_ssecnotif we review the notification mechanism that allows
    external classes to keep track of the changes that an arrangement
    instance goes through. Section \ref arr_ssecex_dcel explains how to
    extend the \dcel records, to store extra data with them, and to
    efficiently update this data. In Section \ref arr_ssecoverlay we
    introduce the fundamental operation of overlaying two arrangements.
    Section \ref arr_ssecarr_with_hist describes a class-template that
    extends the arrangement by storing additional history records with its
    curves. In Section \ref aos_sec-io we review the arrangement
    input/output functions. In Section \ref aos_sec-bgl we describes how
    to apply the graph algorithms implemented in the Boost Graph Library
    to arrangement types. Finally, in Section \ref aos_sec-tips we provide
    some tips that can be applied to expedite computation.

    \section aos_sec-basic Basic Arrangements

    We start with a formal definition of two-dimensional arrangements, and
    proceed with an introduction to the data structure used to represent
    the incidence relations among features of two-dimensional
    arrangements, namely, the doubly-connected edge list, or
    \dcel for short. In Section \ref aos_ssec-basic-arr_class we
    describe a central component in the \ref PkgArrangementOnSurface2
    package, namely, the Arrangement_2 class-template, which can be used
    to represent arrangements in the plane.

    \subsection aos_ssec-basic-dcel Representation of Arrangements: The Dcel

    Given a set \f$\mathcal{C}\f$ of curves embedded in a two-dimensional
    surface, the arrangement \f$\mathcal{A}(\mathcal{C})\f$ is
    the subdivision of the surface into zero-dimensional, one-dimensional
    and two-dimensional cells,\cgalFootnote{We use the term cell
    to describe the various dimensional entities in the induced
    subdivision. Sometimes, the term face is used for this
    purpose in the literature. However, we use the term face to
    describe a two-dimensional cell.} called vertices,
    edges and faces, respectively, induced by the curves
    in \f$\mathcal{C}\f$.

    In our implementation we use a definition that slightly deviates from
    the standard definition above for practical reasons. The curves in
    \f$\mathcal{C}\f$ can intersect each other (a single curve may also be
    self-intersecting or may comprise several disconnected branches) and
    are not necessarily \f$x\f$-monotone.\cgalFootnote{A continuous planar
    curve \f$c\f$ is \f$x\f$-monotone if every vertical line
    intersects it at most once. For example, a non-vertical line segment
    is always \f$x\f$-monotone and so is the graph of any continuous
    function \f$y = f(x)\f$. For convenience, we treat vertical line
    segments as weakly \f$x\f$-monotone, as there exists a single
    vertical line that overlaps them. A circle of radius \f$r\f$ centered
    at \f$(x_0, y_0)\f$ is not \f$x\f$-monotone, as the vertical line \f$x
    = x_0\f$ intersects it at \f$(x_0, y_0 - r)\f$ and at \f$(x_0, y_0 +
    r)\f$.} We construct a collection \f$\mathcal{C}''\f$ of
    \f$x\f$-monotone subcurves that are pairwise disjoint in their
    interiors in two steps as follows. First, we decompose each curve in
    \f$\mathcal{C}\f$ into maximal \f$x\f$-monotone subcurves and possibly
    isolated points, obtaining the collection \f$\mathcal{C}'\f$. Note
    that an \f$x\f$-monotone curve cannot be self-intersecting. Then, we
    decompose each curve in \f$\mathcal{C}'\f$ into maximal connected
    subcurves not intersecting any other curve (or point) in
    \f$\mathcal{C}'\f$ in its interior. The collection \f$\mathcal{C}''\f$
    contains isolated points, if the collection \f$\mathcal{C}'\f$
    contains such points. The arrangement induced by the collection
    \f$\mathcal{C}''\f$ can be conveniently embedded as a planar graph,
    the vertices of which are associated with curve endpoints or with
    isolated points, and the edges of which are associated with
    subcurves. It is easy to see that the faces of
    \f$\mathcal{A}(\mathcal{C})\f$ are the same as the faces of
    \f$\mathcal{A}(\mathcal{C}'')\f$. There are possibly more vertices in
    \f$\mathcal{A}(\mathcal{C}'')\f$ than in
    \f$\mathcal{A}(\mathcal{C})\f$---the vertices where curves were cut
    into \f$x\f$-monotone (non-intersecting) pieces; accordingly there may
    also be more edges in \f$\mathcal{A}(\mathcal{C}'')\f$. This graph can
    be represented using a doubly-connected edge list
    data-structure (\dcel), which consists of containers of vertices,
    edges and faces and maintains the incidence relations among these
    cells. It is one of a family of combinatorial data structures called
    halfedge data structures (Hds),
    which are edge-centered data structures capable of maintaining
    incidence relations among cells of, for example, planar subdivisions,
    polyhedra, or other orientable, two-dimensional surfaces embedded in a
    space of arbitrary dimension. Geometric interpretation is added by
    classes built on top of the halfedge data structure.

    \cgalAdvancedBegin

    The \f$x\f$-monotone curves of an arrangement are embedded in a
    rectangular two-dimensional area called the parameter space. The
    parameter space is defined as \f$X \times Y\f$, where \f$X\f$ and
    \f$Y\f$ are open, half-open, or closed intervals with endpoints in the
    compactified real line \f$\mathbb{R} \cup {-\infty,+\infty}\f$. Let
    \f$x_{\rm min}\f$, \f$x_{\rm max}\f$, \f$y_{\rm min}\f$, and
    \f$y_{\rm max}\f$ denote the endpoints of \f$X\f$ and \f$Y\f$,
    respectively. We typically refer to these values as the left, right,
    bottom, and top sides of the boundary of the parameter space. If the
    parameter space is, for example, the entire compactified plane, as in
    the case of arrangements in the plane,
    \f$x_{\rm min} = y_{\rm min} = -\infty\f$ and
    \f$x_{\rm max} = y_{\rm max} = +\infty\f$; see Section \ref
    aos_sec-curved_surfaces for more details.

    \cgalAdvancedEnd

    The \dcel data-structure represents each edge using a pair of
    directed halfedges, one going from the
    \f$xy\f$-lexicographically smaller (left) endpoint of the curve
    towards the \f$xy\f$-lexicographically larger (right) endpoint, and
    the other, known as its twin halfedge, going in the opposite
    direction. As each halfedge is directed, it has a source
    vertex and a target vertex. Halfedges are used to separate
    faces, and to connect vertices, with the exception of isolated
    vertices (representing isolated points), which are disconnected.
    If a vertex \f$v\f$ is the target of a halfedge \f$e\f$, we say that
    \f$v\f$ and \f$e\f$ are incident to each other. The halfedges
    incident to a vertex \f$v\f$ form a circular list sorted in a
    clockwise order around this vertex. (An isolated vertex has no
    incident halfedges.)

    An edge of an arrangement is a maximal portion of a curve
    between two vertices of the arrangement. Each edge is represented in
    the \dcel by a pair of twin halfedges. Each halfedge \f$e\f$
    stores a pointer to its incident face, which is the face lying
    to its left. Moreover, every halfedge is followed by another halfedge
    sharing the same incident face, such that the target vertex of the
    halfedge is the same as the source vertex of the next halfedge. The
    halfedges around faces form circular chains, such that all halfedges
    of a chain are incident to the same face and wind along its boundary.
    We call such a chain a connected component of the boundary, or
    CCB for short.

    The unique CCB of halfedges winding in a counterclockwise orientation
    along a face boundary is referred to as the outer CCB of the
    face. For the time being let us consider only (i) arrangements of
    bounded curves, such that exactly one unbounded face exists in every
    arrangement, and (ii) arrangements embedded in the plane, such that
    every face has at most one outer CCB. The unbounded face does not have
    an outer boundary. Any other connected component of the boundary of
    the face is called a hole, or inner CCB, and can be
    represented as a circular chain of halfedges winding in a clockwise
    orientation around it. Note that a hole does not necessarily
    correspond to a face at all, as it may have no area, or alternatively
    it may contain several faces. Every face can have several inner CCBs
    in its interior, or may not contain inner CCBs at all. In addition,
    every face may contain isolated vertices in its interior. We
    distinguish between isolated vertices and holes even though,
    theoretically, the former are degenerate holes. See
    \cgalFigureRef{aos_fig-arr_segs} for an illustration of the various
    \dcel features. For more details on the \dcel data structure see
    \cgalCite{bkos-cgaa-00} Chapter 2.

    \cgalFigureBegin{aos_fig-arr_segs,arr_segs.png}
    An arrangement of interior-disjoint line segments with some of the
    \dcel records that represent it. The unbounded face \f$f_0\f$ has
    a single connected component that forms a hole inside it, and this
    hole comprises of several faces. The halfedge \f$e\f$ is directed
    from its source vertex \f$v_1\f$ to its target vertex \f$v_2\f$.
    This edge, together with its twin \f$e'\f$, correspond to a
    line segment that connects the points associated with \f$v_1\f$ and
    \f$v_2\f$ and separates the face \f$f_1\f$ from \f$f_2\f$. The
    predecessor \f$e_{\rm prev}\f$ and successor \f$e_{\rm next}\f$ of
    \f$e\f$ are part of the chain that form the outer boundary of the
    face \f$f_2\f$. The face \f$f_1\f$ has a more complicated structure
    as it contains two holes in its interior: One hole consists of two
    adjacent faces \f$f_3\f$ and \f$f_4\f$, while the other hole
    comprises of two edges. \f$f_1\f$ also contains two isolated vertices
    \f$u_1\f$ and \f$u_2\f$ in its interior.
    \cgalFigureEnd

    \subsection aos_ssec-basic-arr_class The Arrangement Class Template

    One of the main components of the \ref PkgArrangementOnSurface2
    package is the Arrangement_2 class template. An
    instance of this template is used to represent an arrangement embedded
    in the plane. The class template provides the interface needed to
    construct such arrangements, traverse them, and maintain them.

    The design of the \ref PkgArrangementOnSurface2 package is guided by
    two aspects of modularity as follows:

  • the separation of the representation of the arrangements and the various geometric algorithms that operate on them, and
  • the separation of the topological and geometric aspects of the two-dimensional subdivision.

    The latter separation is exhibited by the two template parameters of
    the Arrangement_2 class template; their description follows.

  • The `Traits` template-parameter should be substituted by a model of the `AosBasicTraits_2` concept and optionally additional geometry traits concepts. A model of the `AosBasicTraits_2` concept defines the types of \f$x\f$-monotone curves and two-dimensional points, namely `AosBasicTraits_2::X_monotone_curve_2` and `AosBasicTraits_2::Point_2`, respectively, and supports basic geometric predicates on them. The instantiated traits class determines the family of planar curves that induce the arrangement.

    In this section we always use Arr_non_caching_segment_traits_2 as
    our traits-class model in order to construct arrangements of line
    segments. In succeeding sections we also use Arr_segment_traits_2
    as our traits-class model. These two traits trade computation time
    and storage space. The latter stores the underlying line of every
    segment of the arrangement to expedite certain operations on the
    arrangement segments. In Section \ref aos_sec-unbounded we use
    Arr_linear_traits_2 to construct arrangements of linear curves
    (i.e., lines, rays, and line segments). The \ref
    PkgArrangementOnSurface2 package contains several other traits
    classes that can handle other types of curves, such as polylines
    (continuous piecewise-linear curves), conic arcs, and arcs of
    rational functions. We exemplify the usage of these traits classes
    in Section \ref aos_sec-geom_traits.

  • The `Dcel` template-parameter should be substituted by a class that models the `AosDcel` concept, which is used to represent the topological layout of the arrangement. This parameter is substituted by `Arr_default_dcel` by default, and we use this default value in this and in the following three sections. However, in many applications it is necessary to extend the \dcel features. This is done by substituting the `Dcel` parameter with a different type (typically, a different instance of the `Arr_dcel<>` class template); see Section \ref arr_ssecex_dcel for further explanations and examples.

    The function template print_arrangement_size() listed below, and
    defined in the header file Arr_print.h, prints out quantitative
    measures of a given arrangement. While in what follows it is used only
    by examples, it demonstrates well the use of the member functions
    \link Arrangement_on_surface_2::number_of_vertices()
    number_of_vertices()\endlink, \link
    Arrangement_on_surface_2::number_of_edges()
    number_of_edges()\endlink, and \link
    Arrangement_on_surface_2::number_of_faces()
    number_of_faces()\endlink, which return the number of vertices,
    edges, and faces of an arrangement, respectively.

    \anchor lst_paz
    \code{.cpp}
    template
    void print_arrangement_size(const Arrangement& arr) {
    std::cout << "The arrangement size:\n"
    << " |V| = " << arr.number_of_vertices()
    << ", |E| = " << arr.number_of_edges()
    << ", |F| = " << arr.number_of_faces() << std::endl;
    }
    \endcode

    You can also obtain the number of halfedges of an arrangement using
    the member function \link Arrangement_on_surface_2::number_of_halfedges()
    number_of_halfedges()\endlink. Recall that the number of halfedges is
    always twice the number of edges.

    \image html triangle.png
    \image latex triangle.png

    The simple program listed below constructs an arrangement of three
    connected line segments forming a triangle. It uses the
    Cartesian kernel with an integral-number type to instantiate
    the Arr_non_caching_segment_traits_2<Kernel> class template. The
    resulting arrangement consists of two faces, a bounded triangular face
    and the unbounded face. Constructing and maintaining arrangements
    using limited-precision numbers, such as int, works properly only
    under severe restrictions, which in many cases render the program not
    very useful. In this example, however, the points are far apart, and
    constructions of new geometric objects do not occur. Thus, it is safe
    to use int after all. The program constructs an arrangement induced
    by three line segments that are pairwise disjoint in their interior,
    prints out the number of faces, and ends. It uses the
    \link insert(Arrangement_2&, InputIterator, InputIterator) insert()\endlink
    free-function, which inserts the segments into the
    arrangement; see Section \ref arr_secgl_funcs. It uses the member
    function \link Arrangement_on_surface_2::number_of_faces
    number_of_faces()\endlink to obtain the number of faces (two in this
    case). We give more elaborate examples in the rest of this
    chapter. The programs in those examples rely on computing with numbers
    of arbitrary precision, which guarantees robust execution and correct
    results.

    \code{.cpp}
    #include <CGAL/Cartesian.h>
    #include <CGAL/Arr_non_caching_segment_traits_2.h>
    #include <CGAL/Arrangement_2.h>

    using Number_type = int;
    using Kernel = CGAL::Cartesian;
    using Traits = CGAL::Arr_non_caching_segment_traits_2;
    using Point = Traits_2::Point_2;
    using Segment = Traits_2::X_monotone_curve_2;
    using Arrangement = CGAL::Arrangement_2;

    int main() {
    Arrangement arr;
    Point p1(1, 1), p2(1, 2), p3(2, 1);
    Segment cv[] = {Segment(p1, p2), Segment(p2, p3), Segment(p3, p1)};
    CGAL::insert(arr, &cv[0], &cv[sizeof(cv)/sizeof(Segment)]);
    return 0;
    }
    \endcode

    \subsection arr_ssectraverse Traversing the Arrangement

    The simplest and most fundamental arrangement operations are the
    various traversal methods, which allow users to systematically go over
    the relevant features of the arrangement at hand.

    As mentioned above, the arrangement is represented as a \dcel,
    which stores three containers of vertices, halfedges and faces; thus,
    the Arrangement_2 class template supplies iterator types for these
    containers, respectively. For example, if arr is an Arrangement_2
    object, the calls \link Arrangement_on_surface_2::vertices_begin()
    arr.vertices_begin()\endlink and \link
    Arrangement_on_surface_2::vertices_end arr.vertices_end()\endlink
    return iterators of the nested \link
    Arrangement_on_surface_2::Vertex_iterator Vertex_iterator\endlink
    type that define the valid range of vertices of the arrangement
    arr. The value type of this iterator is \link
    Arrangement_on_surface_2::Vertex Vertex\endlink. Moreover, the
    vertex-iterator type is convertible to \link
    Arrangement_on_surface_2::Vertex_handle Vertex_handle\endlink, which
    serves as a pointer to a vertex. As we show next, all functions
    related to arrangement features accept handle types as input
    parameters and return handle types as their output.
    See Chapter \ref Chapter_Handles_Ranges_and_Circulators
    "Handles and Circulators" for more information on \cgal handles.

    In addition to the iterators for arrangement vertices, halfedges, and
    faces, the arrangement class also provides an iterator for edges,
    namely \link Arrangement_on_surface_2::Edge_iterator
    Edge_iterator\endlink. The value type of this iterator is \link
    Arrangement_on_surface_2::Halfedge Halfedge\endlink, which is the
    same as the value type of \link
    Arrangement_on_surface_2::Halfedge_iterator
    Halfedge_iterator\endlink. The calls \link
    Arrangement_on_surface_2::edges_begin() arr.edges_begin()\endlink
    and \link Arrangement_on_surface_2::edges_end()
    arr.edges_end()\endlink return iterators that define the valid range
    of arrangement edges. This range consists of half the number of
    halfedges of the arrangement, as every twin halfedges has one
    representative in this range.

    All iterator, circulator\cgalFootnote{A circulator is used to
    traverse a circular list, such as the list of halfedges incident to a
    vertex.} and handle types also have non-mutable (const)
    counterparts. These non-mutable iterator types are useful for
    traversing an arrangement with the promise to keep it unchanged. For
    example, the arrangement has a non-constant member function called
    Arrangement_on_surface_2::vertices_begin() that returns a \link
    Arrangement_on_surface_2::Vertex_iterator Vertex_iterator\endlink
    object and another const member function that returns a \link
    Arrangement_on_surface_2::Vertex_const_iterator
    Vertex_const_iterator\endlink object. In fact, all methods listed in
    this section that return an iterator, a circulator, or a handle have
    non-mutable counterparts. It should be noted that, for example, \link
    Arrangement_on_surface_2::Vertex_handle Vertex_handle\endlink can be
    readily converted into a \link
    Arrangement_on_surface_2::Vertex_const_handle
    Vertex_const_handle\endlink, but not the other way around.

    Conversions of non-mutable handles to the corresponding mutable
    handles are nevertheless possible. They can be performed using the
    overloaded member function \link
    Arrangement_on_surface_2::non_const_handle()
    non_const_handle()\endlink. There are three variants that accept a
    non-mutable handle to a vertex, a halfedge, or a face, respectively.
    The call \link Arrangement_on_surface_2::non_const_handle()
    non_const_handle()\endlink can be issued only if the arrangement
    object arr is mutable; see, e.g., Section \ref arr_ssecpl.

    \subsubsection arr_sssectr_vertex Traversal Methods for an Arrangement Vertex

    A vertex \f$v\f$ of an arrangement induced by bounded curves is always
    associated with a geometric entity, namely with an \link
    Arrangement_on_surface_2::Point_2 Point_2\endlink object, which can
    be obtained by \link Arrangement_on_surface_2::Vertex::point()
    v->point()\endlink, where v identifies a handle to \f$v\f$.

    The call \link Arrangement_on_surface_2::Vertex::is_isolated()
    v->is_isolated()\endlink determines whether the vertex \f$v\f$ is
    isolated or not. Recall that the halfedges incident to a non-isolated
    vertex, namely, the halfedges that share a common target vertex, form
    a circular list around this vertex. The call \link
    Arrangement_on_surface_2::Vertex::incident_halfedges()
    v->incident_halfedges()\endlink returns a circulator of the nested
    type \link Arrangement_on_surface_2::Halfedge_around_vertex_circulator
    Halfedge_around_vertex_circulator\endlink that enables the traversal
    of this circular list around a given vertex \f$v\f$ in a clockwise
    order. The value type of this circulator is \link
    Arrangement_on_surface_2::Halfedge Halfedge\endlink. By convention,
    the target of the halfedge is \f$v\f$. The call \link
    Arrangement_on_surface_2::Vertex::degree() v->degree()\endlink
    evaluates to the number of the halfedges incident to \f$v\f$.

    The function below prints all the halfedges incident to a given
    arrangement vertex (assuming that objects of the \link
    Arrangement_on_surface_2::Point_2 Point_2\endlink type can be
    inserted into the standard output using the << operator). The
    arrangement type is the same as in the simple example above.

    \code
    template
    void print_incident_halfedges(typename Arrangement::Vertex_const_handle v) {
    if (v->is_isolated()) {
    std::cout << "The vertex (" << v->point() << ") is isolated\n";
    return;
    }
    typename Arrangement::Halfedge_around_vertex_const_circulator first, curr;
    first = curr = v->incident_halfedges();
    std::cout << "The neighbors of the vertex (" << v->point() << ") are:";
    do std::cout << " (" << curr->source()->point() << ")";
    while (++curr != first);
    std::cout << std::endl;
    }
    \endcode

    If \f$v\f$ is an isolated vertex, the call \link
    Arrangement_on_surface_2::Vertex::face() v->face()\endlink can be used to
    obtain the face that contains \f$v\f$.

    \subsubsection arr_sssectr_halfedge Traversal Methods for an Arrangement Halfedge

    A halfedge \f$e\f$ of an arrangement induced by bounded curves is
    associated with an \link Arrangement_on_surface_2::X_monotone_curve_2
    X_monotone_curve_2\endlink object, which can be obtained by
    \link Arrangement_on_surface_2::Halfedge::curve()
    e->curve()\endlink, where e identifies a handle to \f$e\f$.

    The calls \link Arrangement_on_surface_2::Halfedge::source()
    e->source()\endlink and \link
    Arrangement_on_surface_2::Halfedge::target() e->target()\endlink
    return handles to the halfedge's source-vertex and target-vertex,
    respectively. You can obtain a handle to the twin halfedge using \link
    Arrangement_on_surface_2::Halfedge::twin() e->twin()\endlink. Note
    that from the definition of halfedges in the Dcel structure, the
    following invariants always hold:

  • \link Arrangement_on_surface_2::Halfedge::curve() `e->curve()`\endlink is equivalent to \link Arrangement_on_surface_2::Halfedge::curve() `e->twin()->curve()`\endlink,
  • \link Arrangement_on_surface_2::Halfedge::source() `e->source()`\endlink is equivalent to \link Arrangement_on_surface_2::Halfedge::target() `e->twin()->target()`\endlink, and
  • \link Arrangement_on_surface_2::Halfedge::target() `e->target()`\endlink is equivalent to \link Arrangement_on_surface_2::Halfedge::source() `e->twin()->source()`\endlink.

    Every halfedge has an incident face that lies to its left, which can
    be obtained by \link Arrangement_on_surface_2::Halfedge::face()
    e->face()\endlink. Recall that a halfedge is always one link in a
    connected chain (CCB) of halfedges that share the same incident
    face. The \link Arrangement_on_surface_2::Halfedge::prev()
    e->prev()\endlink and \link
    Arrangement_on_surface_2::Halfedge::next() e->next()\endlink calls
    return handles to the previous and next halfedges in the CCB,
    respectively.

    As the CCB is a circular list of halfedges, it is only natural to
    traverse it using a circulator. Indeed \link
    Arrangement_on_surface_2::Halfedge::ccb() e->ccb()\endlink returns
    an \link Arrangement_on_surface_2::Ccb_halfedge_circulator
    Ccb_halfedge_circulator\endlink object for traversing all halfedges
    along the connected component of \f$e\f$. The value type of this
    circulator is \link Arrangement_on_surface_2::Halfedge
    Halfedge\endlink.

    The function template print_ccb() listed below prints all
    \f$x\f$-monotone curves along a given CCB (assuming that objects of
    the \link Arrangement_on_surface_2::Point_2 Point_2\endlink and the
    \link Arrangement_on_surface_2::X_monotone_curve_2
    X_monotone_curve_2\endlink types can be inserted into the standard
    output using the << operator).

    \code
    template
    void print_ccb(typename Arrangement::Ccb_halfedge_const_circulator circ) {
    Ccb_halfedge_const_circulator curr = circ;
    std::cout << "(" << curr->source()->point() << ")";
    do {
    typename Arrangement::Halfedge_const_handle he = curr->handle();
    std::cout << " [" << e->curve() << "] "
    << "(" << e->target()->point() << ")";
    } while (++curr != circ);
    std::cout << std::endl;
    }
    \endcode

    \subsubsection arr_sssectr_face Traversal Methods for an Arrangement Face

    An Arrangement_2 object arr that identifies an arrangement of
    bounded curves always has a single unbounded face. The call \link
    Arrangement_on_surface_2::unbounded_face()
    arr.unbounded_face()\endlink returns a handle to this face. Note
    that an empty arrangement contains nothing but the unbounded
    face.

    Given a handle to a face \f$f\f$, you can use the call \link
    Arrangement_on_surface_2::Face::is_unbounded()
    f->is_unbounded()\endlink to determine whether the face \f$f\f$ is
    unbounded. Bounded faces have an outer CCB, and the \link
    Arrangement_on_surface_2::Face::outer_ccb() outer_ccb()\endlink
    method returns a circulator for the halfedges along this CCB. Note
    that the halfedges along this CCB wind in a counterclockwise order
    around the outer boundary of the face.

    A face can also contain disconnected components in its interior,
    namely, holes and isolated vertices. You can access these components
    as follows:

  • You can obtain a pair of iterators of type \link Arrangement_on_surface_2::Face::Hole_iterator `Hole_iterator`\endlink that define the range of holes inside a face \f$f\f$ by calling \link Arrangement_on_surface_2::Face::holes_begin() `f->holes_begin()`\endlink and \link Arrangement_on_surface_2::Face::holes_end() `f->holes_end()`\endlink. The value type of this iterator type is \link Arrangement_on_surface_2::Ccb_halfedge_circulator `Ccb_halfedge_circulator`\endlink, defining the CCB that winds in a clockwise order around a hole. The call \link Arrangement_on_surface_2::Face::number_of_holes() `f->number_of_holes()`\endlink return the number of holes in \f$f\f$.
  • The calls \link Arrangement_on_surface_2::Face::isolated_vertices_begin() `f->isolated_vertices_begin()`\endlink and \link Arrangement_on_surface_2::Face::isolated_vertices_end() `f->isolated_vertices_end()`\endlink return iterators of type \link Arrangement_on_surface_2::Isolated_vertex_iterator `Isolated_vertex_iterator`\endlink that define the range of isolated vertices inside the face \f$f\f$. The value type of this iterator is \link Arrangement_on_surface_2::Vertex `Vertex`\endlink.

    The function print_face() listed below prints the outer and inner
    boundaries of a given face. It uses the function template
    print_ccb() listed above.

    \code
    template
    void print_face(typename Arrangement::Face_const_handle f) {
    // Print the outer boundary.
    if (f->is_unbounded()) std::cout << "Unbounded face.\n";
    else {
    std::cout << "Outer boundary: ";
    print_ccb(f->outer_ccb());
    }

    // Print the boundary of each of the holes.
    std::size_t index = 1;
    for (auto hi = f->holes_begin(); hi != f->holes_end(); ++hi) {
    std::cout << " Hole #" << index++ << ": ";
    print_ccb(*hi);
    }

    // Print the isolated vertices.
    index = 1;
    for (auto iv = f->isolated_vertices_begin();
    iv != f->isolated_vertices_end(); ++iv)
    {
    std::cout << " Isolated vertex #" << index++ << ": "
    << "(" << iv->point() << ")\n";
    }
    }
    \endcode

    The function print_arrangement() listed below prints the features of
    a given arrangement. The file arr_print.h, which can be found under
    the examples folder, includes the definitions of this function, as
    well as the definitions of all other functions listed in this
    section. This concludes the preview of the various traversal methods.

    \code
    void print_arrangement (const Arrangement_2& arr) {
    // Print the arrangement vertices.
    std::cout << arr.number_of_vertices() << " vertices:\n";
    for (auto vit = arr.vertices_begin(); vit != arr.vertices_end(); ++vit) {
    std::cout << "(" << vit->point() << ")";
    if (vit->is_isolated()) std::cout << " - Isolated.\n";
    else std::cout << " - degree " << vit->degree() << std::endl;
    }

    // Print the arrangement edges.
    std::cout << arr.number_of_edges() << " edges:\n";
    for (auto eit = arr.edges_begin(); eit != arr.edges_end(); ++eit)
    std::cout << "[" << eit->curve() << "]\n";

    // Print the arrangement faces.
    std::cout << arr.number_of_faces() << " faces:\n";
    for (auto fit = arr.faces_begin(); fit != arr.faces_end(); ++fit)
    print_face(fit);
    }
    \endcode

    \subsection arr_ssecmodify Modifying the Arrangement

    In this section we review the various member functions of the
    Arrangement_2 class that allow users to modify the topological
    structure of the arrangement through the introduction of new edges or
    vertices, or the modification or removal of existing edges and
    vertices.

    The arrangement member-functions that insert new \f$x\f$-monotone
    curves into the arrangement, thus enabling the construction of a
    two-dimensional surface subdivision, are rather specialized, as they
    assume that the interior of the inserted curve is disjoint from all
    existing arrangement vertices and edges, and in addition require
    apriori knowledge of the location of the inserted curve. Indeed, for
    most purposes it is more convenient to construct an arrangement using
    the free (global) insertion functions, which relax these
    restrictions. However, as these free functions are implemented in
    terms of the specialized insertion functions, we start by describing
    the fundamental functionality of the arrangement class, and describe
    the operation of the free functions in Section \ref arr_secgl_funcs.

    \subsection arr_sssecmf_insert_cv Inserting Pairwise Disjoint x-Monotone Curves

    The most trivial functions that allow users to modify the arrangement
    are the specialized functions for the insertion of an \f$x\f$-monotone
    curve the interior of which is disjoint from the interior of all other
    curves in the existing arrangement and does not contain any point of
    the arrangement. In addition, these functions require that the
    location of the curve in the arrangement be known.

    The rather harsh restrictions on the inserted curves enable an
    efficient implementation. While inserting an \f$x\f$-monotone curve,
    the interior of which is disjoint from all curves in the existing
    arrangement, is quite straightforward, as we show next, (efficiently)
    inserting a curve that intersects with the curves already in the
    arrangement is much more complicated and requires the application of
    nontrivial geometric algorithms. The decoupling of the topological
    arrangement representation from the various algorithms that operate on
    it dictates that the general insertion operations be implemented as
    free functions that operate on the arrangement and the inserted
    curve(s); see Section \ref arr_secgl_funcs for more details and
    examples.

    \cgalFigureBegin{aos_fig-insert,insert.png}
    Illustrations of the various specialized insertion procedures. The
    inserted \f$x\f$-monotone curve is drawn as a dashed line, surrounded
    by two solid arrows that represent the pair of twin halfedges added to
    the \dcel. Existing vertices are shown as red discs, while new
    vertices are shown as blue discs. Existing halfedges that are
    affected by the insertion operations are drawn as dashed arrows. (a)
    Inserting a curve as a new hole inside the face \f$f\f$. (b)
    Inserting a curve from an existing vertex \f$u\f$ that corresponds to
    one of its endpoints. (c) Inserting an \f$x\f$-monotone curve, the
    endpoints of which correspond to existing vertices \f$u_1\f$ and
    \f$u_2\f$. In this case, the new pair of halfedges closes a new face
    \f$f'\f$. The hole \f$h_1\f$, which belonged to \f$f\f$ before
    the insertion, becomes a hole in this new face.
    \cgalFigureEnd

    When an \f$x\f$-monotone curve is inserted into an existing
    arrangement, such that the interior of this curve is disjoint from the
    interiors of all curves in the arrangement, only the following three
    scenarios are possible, depending on the status of the endpoints of
    the inserted curve:

    1. Neither curve endpoints correspond to any existing arrangement vertex. In this case we have to create two new vertices that correspond to the curve endpoints, respectively, and connect them using a pair of twin halfedges. This halfedge pair forms a new hole inside the face that contains the curve in its interior.
    2. Exactly one endpoint corresponds to an existing arrangement vertex. (We distinguish between a vertex that corresponds to the left endpoint of the inserted curve and a vertex that corresponds to its right endpoint.) In this case we have to create a new vertex that corresponds to the other endpoint of the curve and to connect the two vertices by a pair of twin halfedges that form an "antenna" emanating from the boundary of an existing connected component. (Note that if the existing vertex is isolated, we need to form a new hole inside the face that contains this vertex, essentially falling back to the handling of the previous case, naturally, skipping the creation of the existing vertex.)
    3. Both endpoints correspond to existing arrangement vertices. In this case we connect these vertices using a pair of twin halfedges. (If one or both vertices are isolated, we fall back to the handling of the first or second case, respectively, naturally, skipping the creation of the existing vertices.) The two following subcases may occur:
    4. Two disconnected components are merged into a single connected component (as is the case with the segment \f$s_1\f$ in the figure below).
    5. A new face, which is split from an existing arrangement face, is created (as is the case with the segment \f$s_2\f$ in the figure below). In this case we also have to examine the holes and isolated vertices in the existing face and move the relevant ones inside the new face.

    \image html connect_comp.png
    \image latex connect_comp.png

    The Arrangement_2 class offers insertion functions that perform the
    special insertion procedures listed above, namely, \link
    Arrangement_on_surface_2::insert_in_face_interior()
    insert_in_face_interior()\endlink, \link
    Arrangement_on_surface_2::insert_from_left_vertex()
    insert_from_left_vertex()\endlink, \link
    Arrangement_on_surface_2::insert_from_right_vertex()
    insert_from_right_vertex()\endlink and \link
    Arrangement_on_surface_2::insert_at_vertices()
    insert_at_vertices()\endlink. The first function accepts an
    \f$x\f$-monotone curve \f$c\f$ and an arrangement face \f$f\f$ that
    contains this curve in its interior. The other functions accept an
    \f$x\f$-monotone curve \f$c\f$ and handles to the existing vertices
    that correspond to the curve endpoint(s). Each of the four functions
    returns a handle to one of the twin halfedges that have been created;
    more precisely:

  • \link Arrangement_on_surface_2::insert_in_face_interior() `insert_in_face_interior(c, f)`\endlink returns a handle to the halfedge directed from the left endpoint of \f$c\f$ towards the vertex corresponding to its right endpoint.
  • \link Arrangement_on_surface_2::insert_from_left_vertex() `insert_from_left_vertex(c, v)`\endlink and \link Arrangement_on_surface_2::insert_from_right_vertex() `insert_from_right_vertex(c, v)`\endlink each returns a handle to the halfedge, the source of which is the vertex \f$v\f$, and the target of which is the new vertex that has just been created.
  • \link Arrangement_on_surface_2::insert_at_vertices() `insert_at_vertices(c, v1, v2)`\endlink returns a handle to the halfedge directed from \f$v_1\f$ to \f$v_2\f$.

    \cgalFigureBegin{aos_fig-edge_insertion,edge_insertion.png}
    The arrangement of the line segments \f$s_1, \ldots, s_5\f$
    constructed in \ref Arrangement_on_surface_2/edge_insertion.cpp.
    The arrows mark the direction of the halfedges returned from the
    various insertion functions.
    \cgalFigureEnd

    The program below demonstrates the usage of the four specialized
    insertion functions. It creates an arrangement of five line segments
    \f$s_1, \ldots, s_5\f$, as depicted in
    \cgalFigureRef{aos_fig-edge_insertion}. \cgalFootnote{Notice that in
    all figures in the rest of this chapter the coordinate axes are drawn
    only for illustrative purposes and are not part of the
    arrangement.} The first line segment \f$s_1\f$ is inserted in the
    interior of the unbounded face, while the four succeeding line
    segments \f$s_2, \ldots, s_5\f$ are inserted using the vertices
    created by the insertion of preceding segments. The arrows in the
    figure mark the direction of the halfedges \f$e_1, \ldots, e_5\f$
    returned from the insertion functions. The resulting arrangement
    consists of three faces, where the two bounded faces form together a
    hole in the unbounded face.

    Two header files are included in the code in order to make this and
    the following examples more compact. The file
    arr_inexact_construction_segments.h is listed
    immediately after the program. The file arr_print.h is
    introduced in Section \ref arr_ssectraverse.

    \cgalExample{Arrangement_on_surface_2/edge_insertion.cpp}

    The statements below define the types for arrangements of line
    segments common to all examples that do not construct new geometric
    objects. They are kept in the header file
    arr_inexact_construction_segments.h. In these examples the Traits
    parameter of the Arrangement_2 class template is
    substituted by an instance of the
    Arr_non_caching_segment_traits_2<Kernel> class template. The
    Arr_non_caching_segment_traits_2 class template is instantiated with
    the predefined kernel that evaluates predicates in an exact manner,
    but constructs geometric objects in an inexact manner, as none of
    these examples construct new geometric objects. In the remaining
    examples the traits class-template is instantiated with a kernel that
    evaluates predicates and constructs geometric objects, both in an
    exact manner.

    \code{.cpp}
    #include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
    #include <CGAL/Arr_non_caching_segment_traits_2.h>
    #include <CGAL/Arrangement_2.h>

    using Kernel = CGAL::Exact_predicates_inexact_constructions_kernel;
    using Number_type = Kernel::FT;

    using Traits = CGAL::Arr_non_caching_segment_traits_2;
    using Point = Traits::Point_2;
    using Segment = Traits::X_monotone_curve_2;

    using Arrangement = CGAL::Arrangement_2;
    using Vertex_handle = Arrangement::Vertex_handle;
    using Halfedge_handle = Arrangement::Halfedge_handle;
    using Face_handle = Arrangement::Face_handle;
    \endcode

    \subsection arr_sssecmf_iso_verts Manipulating Isolated Vertices

    Isolated points are simpler geometric entities than curves, and indeed
    the member functions that manipulate them are easier to understand.

    The call \link Arrangement_on_surface_2::insert_in_face_interior()
    arr.insert_in_face_interior(p, f)\endlink inserts an isolated point
    \f$p\f$, located in the interior of a given face \f$f\f$, into the
    arrangement and returns a handle to the arrangement vertex associated
    with \f$p\f$ it has created. Naturally, this function has a
    precondition that \f$p\f$ is really an isolated point; namely it does
    not coincide with any existing arrangement vertex and does not lie on
    any edge. As mentioned in Section \ref arr_ssectraverse, it is
    possible to obtain the face containing an isolated vertex calling the
    member function Arrangement_on_surface_2::Vertex::face(). The member
    function \link Arrangement_on_surface_2::remove_isolated_vertex()
    Arrangement_on_surface_2::remove_isolated_vertex(Vertex_handle v)\endlink
    accepts a handle to an isolated vertex and removes it from the
    arrangement.

    \cgalFigureBegin{aos_fig-isolated_vertices,isolated_vertices.png}
    An arrangement of line segments containing three isolated vertices,
    as constructed in \ref Arrangement_on_surface_2/isolated_vertices.cpp.
    The vertices \f$u_2\f$ and \f$u_3\f$ are eventually removed from the
    arrangement.
    \cgalFigureEnd

    The following program demonstrates the usage of the arrangement
    member-functions for manipulating isolated vertices. It first inserts
    three isolated vertices, \f$u_1\f$, \f$u_2\f$, and \f$u_3\f$, located
    inside the unbounded face of the arrangement. Then, it inserts four
    line segments \f$s_1, \ldots, s_4\f$, that form a square hole inside
    the unbounded face (see \cgalFigureRef{aos_fig-edge_insertion} for an
    illustration). Finally, it traverses the vertices and removes those
    isolated vertices that are still contained in the unbounded face
    (\f$u_2\f$ and \f$u_3\f$ in this case):

    \cgalExample{Arrangement_on_surface_2/isolated_vertices.cpp}

    \subsection arr_sssecmf_halfedges Manipulating Halfedges

    While reading the previous subsection you learned how to insert new
    points that induce isolated vertices into the arrangement. You may
    wonder now how you can insert a new point that lies on an
    \f$x\f$-monotone curve that is associated with existing arrangement
    edge.

    The introduction of a vertex, the geometric mapping of which is a
    point \f$p\f$ that lies on an \f$x\f$-monotone curve, requires the
    splitting of the curve in its interior at \f$p\f$. The two resulting
    subcurves induce two new edges, respectively. In general, the
    Arrangement_2 class template relies on the geometry traits to
    perform such a split. As a matter of fact, it relies on the geometry
    traits to perform all geometric operations. To insert a point \f$p\f$
    that lies on an \f$x\f$-monotone curve associated with an existing
    edge \f$e\f$ into the arrangement \f$\mathcal{A}\f$, you must first
    construct the two curves \f$c_1\f$ and \f$c_2\f$, which are the two
    subcurves that result from splitting the \f$x\f$-monotone curve
    associated with the edge \f$e\f$ at \f$p\f$. Then, you have to issue
    the call \link Arrangement_on_surface_2::split_edge()
    arr.split_edge(he, c1, c2)\endlink, where arr identifies the
    arrangement \f$\mathcal{A}\f$ and he is a handle to one of the two
    halfedges that represent the edge \f$e\f$. The function splits the two
    halfedges that represent \f$e\f$ into two pairs of halfedges,
    respectively. Two new halfedges are incident to the new vertex \f$v\f$
    associated with \f$p\f$. The function returns a handle to the new
    halfedge, the source of which is the source vertex of the halfedge
    handled by he, and the target of which is the new vertex \f$v\f$.

    The reverse operation is also possible. Consider a vertex \f$v\f$ of
    degree \f$2\f$ that has two incident edges \f$e_1\f$ and \f$e_2\f$
    associated with two curves \f$c_1\f$ and \f$c_2\f$, respectively, such
    that the union of \f$c_1\f$ and \f$c_2\f$ results in a single
    continuous \f$x\f$-monotone curve \f$c\f$ of the type supported by the
    traits class in use. To merge the edges \f$e_1\f$ and \f$e_2\f$ into a
    single edge associated with the curve \f$c\f$, essentially removing
    the vertex \f$v\f$ from the arrangement identified by arr, you need
    to issue the call \link Arrangement_2.merge_edge() arr.merge_edge(he1, he2, c)\endlink, where he1 and he2 are handles to halfedges
    representing \f$e_1\f$ and \f$e_2\f$, respectively.

    Finally, the call \link Arrangement_2.remove_edge()
    remove_edge(he)\endlink removes the edge \f$e\f$ from the
    arrangement, where he is a handle to one of the two halfedges that
    represents \f$e\f$. Note that this operation is the reverse of an
    insertion operation, so it may cause a connected component to split
    into two, or two faces to merge into one, or a hole to disappear. By
    default, if the removal of \f$e\f$ causes one of its end vertices to
    become isolated, this vertex is removed as well. However, you can
    control this behavior and choose to keep the isolated vertices by
    supplying additional Boolean flags to \link
    Arrangement_on_surface_2::remove_edge remove_edge()\endlink
    indicating whether the source or the target vertices are to be removed
    should they become isolated.

    \cgalFigureBegin{aos_fig-edge_manipulation,edge_manipulation.png}
    The three steps of the example program \ref
    Arrangement_on_surface_2/edge_manipulation.cpp. In Step (a) it
    constructs an arrangement of four line segments. In Step (b) the edges
    \f$e_1\f$ and \f$e_2\f$ are split, and the split points are connected
    with a new segment \f$s\f$ that is inserted into the arrangement. This
    operation is undone in Step (c), where \f$e\f$ is removed from the
    arrangement, rendering its end vertices \f$u_1\f$ and \f$u_2\f$
    redundant. We therefore remove these vertices by merging their
    incident edges and go back to the arrangement depicted in (a).
    \cgalFigureEnd

    The following example program shows how the edge-manipulation
    functions can be used. The program works in three steps, as
    demonstrated in \cgalFigureRef{aos_fig-isolated_vertices}. Note that
    the program uses the fact that \link
    Arrangement_on_surface_2::split_edge() split_edge()\endlink returns
    one of the new halfedges (after the split) that has the same direction
    as the original halfedge (the first parameter of the function) and is
    directed towards the split point. Thus, it is easy to identify the
    vertices \f$u_1\f$ and \f$u_2\f$ associated with the split points.

    \cgalExample{Arrangement_on_surface_2/edge_manipulation.cpp}

    The member functions \link Arrangement_on_surface_2::modify_vertex()
    modify_vertex()\endlink and \link
    Arrangement_on_surface_2::modify_edge() modify_edge()\endlink modify
    the geometric mappings of existing features of the arrangement. The
    call \link Arrangement_on_surface_2::modify_vertex
    arr.modify_vertex(v, p)\endlink accepts a handle to a vertex \f$v\f$
    and a reference to a point \f$p\f$, and sets \f$p\f$ to be the point
    associated with the vertex \f$v\f$. The call \link
    Arrangement_on_surface_2::modify_edge() arr.modify_edge(he, c)\endlink accepts a handle to one of the two halfedges that
    represent an edge \f$e\f$ and a reference to a curve \f$c\f$, and sets
    \f$c\f$ to be the \f$x\f$-monotone curve associated with
    \f$e\f$. (Note that both halfedges are modified; that is, both
    expressions e->curve() and e->twin()->curve() evaluate to
    \f$c\f$ after the modification.) These functions have preconditions
    that \f$p\f$ is geometrically equivalent to v->point() and \f$c\f$
    is equivalent to e->curve(), respectively.\cgalFootnote{Roughly
    speaking, two curves are equivalent iff they have the same graph. In
    Section \ref aos_sssec-geom_traits-concepts_basic we give a formal
    definition of curves and curve equivalence.} If these preconditions
    are not met, the corresponding operation may invalidate the structure
    of the arrangement. At first glance it may seem as if these two
    functions are of little use. However, you should keep in mind that
    there may be extraneous data (probably non-geometric) associated with
    the point objects or with the curve objects, as defined by the traits
    class. With these two functions you can modify this data; see more
    details in Section \ref arr_sssec_tr_data_decorators. In addition, you can use
    these functions to replace a geometric object (a point or a curve)
    with an equivalent object that has a more compact representation. For
    example, if we use some simple rational-number type to represent the
    point coordinates, we can replace the point \f$(\frac{20}{40},
    \frac{99}{33})\f$ associated with some vertex \f$v\f$ with an
    equivalent point with normalized coordinates, namely \f$(\frac{1}{2},
    3)\f$.

    \subsection arr_sssecadv_insert Advanced Insertion Functions

    \cgalAdvancedBegin

    | \image html pred_around_vertex.png
    \image latex pred_around_vertex.png | Assume that the specialized insertion function \link
    Arrangement_on_surface_2::insert_from_left_vertex()
    insert_from_left_vertex(c, v)\endlink is given a curve \f$c\f$, the
    left endpoint of which is already associated with a non-isolated
    vertex \f$v\f$. Namely, \f$v\f$ has already several incident
    halfedges. It is necessary in this case to locate the exact place for
    the new halfedge mapped to the inserted new curve \f$c\f$ in the
    circular list of halfedges incident to \f$v\f$. More precisely, in
    order to complete the insertion, it is necessary to locate the
    halfedge \f$e_{\mathrm{pred}}\f$ directed toward \f$v\f$, such that
    \f$c\f$ is located between the curves associated with
    \f$e_{\mathrm{pred}}\f$ and the next halfedge in the clockwise order
    in the circular list of halfedges around \f$v\f$; see
    \cgalFigureRef{aos_fig-insert}. This search may take \cgalBigO{d} time,
    where \f$d\f$ is the degree of the vertex \f$v\f$. \cgalFootnote{We
    can store the handles to the halfedges incident to \f$v\f$ in an efficient
    search structure to obtain \cgalBigO{\log d} access time. However, as
    \f$d\f$ is usually very small, this may lead to a waste of storage
    space without a meaningful improvement in running time in practice.}
    However, if the halfedge \f$e_{\mathrm{pred}}\f$ is known in advance,
    the insertion can be carried out in constant time, and without

    performing any geometric comparisons. |
    | --- | --- |

    The Arrangement_2 class provides advanced versions of the
    specialized insertion functions for a curve \f$c\f$, namely, \link
    Arrangement_on_surface_2::insert_from_left_vertex()
    insert_from_left_vertex(c, he_pred)\endlink and \link
    Arrangement_on_surface_2::insert_from_right_vertex()
    insert_from_right_vertex(c, he_pred)\endlink. These functions
    accept a halfedge \f$e_{\mathrm{pred}}\f$ as specified above, instead
    of a handle to a vertex \f$v\f$. They are more efficient, as they take
    constant time and do not perform any geometric operations. Thus, you
    should use them when the halfedge \f$e_{\mathrm{pred}}\f$ is known. In
    cases where the vertex \f$v\f$ is isolated or the predecessor halfedge
    for the newly inserted curve is not known, the simpler versions of
    these insertion functions should be used. Similarly, the member
    function \link Arrangement_on_surface_2::insert_at_vertices()
    insert_at_vertices()\endlink is overloaded with two additional
    versions as follows. One accepts two handles to the two predecessor
    halfedges around the two vertices \f$v_1\f$ and \f$v_2\f$,
    respectively, that correspond to the curve endpoints. The other one
    accepts a handle to one vertex and a handle to the predecessor
    halfedge around the other vertex.

    \cgalFigureBegin{aos_fig-special_edge_insertion,special_edge_insertion.png}
    An arrangement of line segments, as constructed in
    \ref Arrangement_on_surface_2/special_edge_insertion.cpp. Note that
    \f$p_0\f$ is initially inserted as an isolated point and later on
    connected to the other four vertices.
    \cgalFigureEnd

    The following program shows how to construct the arrangement
    depicted in \cgalFigureRef{aos_fig-special_edge_insertion} using the specialized
    insertion functions that accept predecessor halfedges:

    \cgalExample{Arrangement_on_surface_2/special_edge_insertion.cpp}

    It is possible to perform even more refined operations on an
    Arrangement_2 object given specific topological information.
    As most of these operations are very fragile and perform no precondition
    testing on their input in order to gain efficiency, they are not included
    in the public interface of the arrangement class. Instead, the
    Arr_accessor<Arrangement> class allows access to these internal
    arrangement operations; see more details in the Reference Manual.
    \cgalAdvancedEnd

    \section arr_secqueries Issuing Queries on an Arrangement

    One of the most useful query types defined on arrangements is the
    point-location query: Given a point, find the arrangement
    cell that contains it. Typically, the result of a point-location query
    is one of the arrangement faces, but in degenerate situations the
    query point can lie on an edge, or it may coincide with a vertex.

    Point-location queries are common in many applications, and also
    play an important role in the incremental construction of arrangements
    (and more specifically in the free insertion-functions described in
    Section \ref arr_secgl_funcs). Therefore, it is crucial to have the
    ability to answer such queries effectively.

    \subsection arr_ssecpl Point-Location Queries

    Recall that the arrangement representation is decoupled from the
    geometric algorithms that operate on it. Thus, the Arrangement_2
    class template does not support point-location queries directly.
    Instead, the \ref PkgArrangementOnSurface2 package provides a set of
    class templates that are capable of answering such queries; all are
    models of the concept AosPointLocation_2. Each model employs
    a different algorithm or strategy for answering queries. A
    model of this concept must define the \link
    AosPointLocation_2::locate() locate()\endlink member
    function, which accepts an input query-point and returns a polymorphic
    object representing the arrangement cell that contains this point.
    The returned object is of type
    Arr_point_location_result<Arrangement_2>::%Type, which is a
    discriminated union container of the bounded types \link
    Arrangement_on_surface_2::Vertex_const_handle
    Vertex_const_handle\endlink, \link
    Arrangement_on_surface_2::Halfedge_const_handle
    Halfedge_const_handle\endlink, or \link
    Arrangement_on_surface_2::Face_const_handle
    Face_const_handle\endlink. Depending on whether the query point is
    located inside a face, lies on an edge, or coincides with a vertex,
    the appropriate handle can be obtained with value retrieval
    by std::get as demonstrated in the example below.

    Note that the handles returned by the \link
    AosPointLocation_2::locate() locate()\endlink functions are
    non-mutable (const). If necessary, such handles may be cast to
    mutable handles using the
    Arrangement_on_surface_2::non_const_handle() methods.

    An object pl of any point-location class must be attached to an
    Arrangement_2 object arr before it is used to answer
    point-location queries on arr. This attachment can be performed
    when pl is constructed or at a later time using the
    pl.init(arr) call.

    The function template locate_point() listed below accepts a
    point-location object, the type of which is a model of the
    AosPointLocation_2 concept, and a query point. The function
    template issues a point-location query for the given point, and prints
    out the result. It is defined in the header file
    point_location_utils.h.

    \anchor lst_pl
    \code
    template
    void locate_point(const PointLocation& pl,
    const typename PointLocation::Arrangement_2::Point_2& q) {
    using Point_location = PointLocation;
    using Arrangement_2 = typename Point_location::Arrangement_2;
    typename CGAL::Arr_point_location_result::Type obj =
    pl.locate(q);

    // Print the result.
    print_point_location(q, obj);
    }
    \endcode

    The function template locate_point() calls an instance of the
    function template print_point_location(), which inserts the
    result of the query into the standard output-stream. It is listed
    below, and defined in the header file point_location_utils.h.
    Observe how the function std::get() is used to cast the
    resulting object into a handle to an arrangement feature. The
    point-location object pl is assumed to be already attached
    to an arrangement.

    \code
    template
    void print_point_location
    (const typename PointLocation::Arrangement_::Point_2& q
    typename CGAL::Arr_point_location_result::Type obj) {
    using Arrangement_2 = Arrangement_;

    using Vertex_const_handle = typename Arrangement_2::Vertex_const_handle;
    using Halfedge_const_handle = typename Arrangement_2::Halfedge_const_handle;
    using Face_const_handle = typename Arrangement_2::Face_const_handle;

    const Vertex_const_handle* v;
    const Halfedge_const_handle* e;
    const Face_const_handle* f;

    std::cout << "The point (" << q << ") is located ";
    if (f = std::get_if(&obj)) // located inside a face
    std::cout << "inside "
    << (((*f)->is_unbounded()) ? "the unbounded" : "a bounded")
    << " face.\n";
    else if (e = std::get_if(&obj)) // located on an edge
    std::cout << "on an edge: " << (*e)->curve() << std::endl;
    else if (v = std::get_if(&obj)) // located on a vertex
    std::cout << "on " << (((*v)->is_isolated()) ? "an isolated" : "a")
    << " vertex: " << (*v)->point() << std::endl;
    else CGAL_error_msg("Invalid object.");
    }
    \endcode

    \subsection aos_sssec-pl_strategy Choosing a Point-Location Strategy

    Each of the various point-location class templates employs a different
    algorithm or strategy\cgalFootnote{The term strategy
    is borrowed from the design-pattern taxonomy \cgalCite{cgal:ghjv-dpero-95},
    Chapter 5. A strategy provides the means to define a family of
    algorithms, each implemented by a separate class. All classes that implement
    the various algorithms are made interchangeable, letting the algorithm in use
    vary according to the user choice.} for answering queries:

  • `Arr_naive_point_location` employs the *naive* strategy. It locates the query point naively, exhaustively scanning all arrangement cells.
  • `Arr_walk_along_line_point_location` employs the *walk-along-a-line* (or *walk* for short) strategy. It simulates a traversal, in reverse order, along an imaginary vertical ray emanating from the query point. It starts from the unbounded face of the arrangement and moves downward toward the query point until it locates the arrangement cell containing it.
  • `Arr_landmarks_point_location` uses a set of *landmark* points, the location of which in the arrangement is known. It employs the *landmark* strategy. Given a query point, it uses a nearest-neighbor search-structure (a Kd-tree is used by default) to find the nearest landmark, and then traverses the straight-line segment connecting this landmark to the query point.

    There are various ways to select the landmark set in the
    arrangement. The selection is governed by the Generator
    template parameter. The default generator class, namely
    Arr_landmarks_vertices_generator, selects all the vertices of
    the attached arrangement as landmarks. Additional generators that
    select the set in other ways, such as by sampling random
    points or choosing points on a grid, are also available; see the
    Reference Manual for more details.

    The arrangement attached to the landmark strategy must be either (i)
    an instance of the Arrangement_2<GeomTraits,Dcel> class template,
    where the GeomTraits parameter is substituted by a geometry-traits
    class that models the AosLandmarkTraits_2 concept, or (ii) an
    instance of the Arrangement_on_surface_2<GeomTraits,TopolTraits>
    class template, where the GeomTraits is similarly substituted;
    see Section \ref aos_sssec-tr_landmarks_concept for details about
    this concept. Most traits classes included in the \ref
    PkgArrangementOnSurface2 package are models of this refined concept.

  • `Arr_trapezoid_ric_point_location` implements an improved variant of Mulmuley's point-location algorithm \cgalCite{m-fppa-90}; see also \cgalCite{bkos-cgaa-00}, Chapter 6. The (expected) query-time is logarithmic in the size of the arrangement. The arrangement faces are decomposed into simpler cells each of constant complexity, known as *pseudo trapezoids*, and a search structure (a directed acyclic graph) is constructed on top of these cells, facilitating the search of the pseudo trapezoid (hence the arrangement cell) containing a query point in expected logarithmic time. The trapezoidal map and the search structure are built by a randomized incremental construction algorithm (RIC).
  • `Arr_triangulation_point_location` uses a constrained triangulation, provided by the \ref PkgTriangulation2 package, as a search structure. Every time the arrangement is modified the constrained triangulation search-structure is reconstructed from scratch, where the edges of the arrangement are set to be the constrained edges of the triangulation. This strategy is inefficient (especially when the number of modifications applied to the arrangement is high) and provided only for educational purposes.

    The first two strategies do not require any extra data. The class
    templates that implement them store a pointer to an arrangement object
    and operate directly on it. Attaching such point-location objects to
    an existing arrangement has virtually no running-time cost at all, but
    the query time is linear in the size of the arrangement (the
    performance of the walk strategy is much better in practice, but its
    worst-case performance is linear). Using these strategies is therefore
    recommended only when a relatively small number of point-location
    queries are issued by the application, or when the arrangement is
    constantly changing (That is, changes in the arrangement structure are
    more frequent than point-location queries). On the other hand, the
    landmark and the trapezoid RIC strategies require auxiliary data
    structures on top of the arrangement structure, which they need to
    construct once they are attached to an arrangement object and need to
    keep up-to-date as this arrangement changes.

    As mentioned above, the triangulation strategy is provided only for
    educational purposes, and thus we do not elaborate on this strategy.
    The data structure needed by the landmark and the trapezoidal map RIC
    strategies can be constructed in \cgalBigO{N \log N} time, where \f$N\f$
    is the overall number of edges in the arrangement, but the constant
    hidden in the \cgalBigO{~} notation for the trapezoidal map RIC strategy
    is much larger. Thus, construction needed by the landmark algorithm is
    in practice significantly faster than the construction needed by the
    trapezoidal map RIC strategy. In addition, although both resulting
    data structures are asymptotically linear in size, the actual amount
    of memory consumed by the landmark algorithm is typically smaller than
    to the amount used by the trapezoidal map RIC algorithm, due to the
    space-efficient Kd-tree used by the
    landmark algorithm as the nearest-neighbor search-structure. The
    trapezoidal map RIC algorithm has expected logarithmic query time,
    while the query time for the landmark algorithm may be as large as
    linear. In practice however, the query times of both strategies are
    competitive. For a detailed experimental comparison see
    \cgalCite{cgal:hh-eplca-05}.

    Updating the auxiliary data structures of the trapezoidal map RIC
    algorithm is done very efficiently. On the other hand, updating the
    nearest-neighbor search-structure of the landmark algorithm may
    consume significant time when the arrangement changes frequently,
    especially when a Kd-tree is used, as it
    must be rebuilt each time the arrangement changes. It is therefore
    recommended that the Arr_landmarks_point_location class template be
    used when the application frequently issues point-location queries on
    an arrangement that only seldom changes. If the arrangement is more
    dynamic and is frequently going through changes, the
    Arr_trapezoid_ric_point_location class template should be the
    selected point-location strategy.

    \cgalFigureBegin{aos_fig-point_location,point_location.png}
    The arrangement of line segments, as constructed in \ref
    Arrangement_on_surface_2/point_location.cpp, \ref
    Arrangement_on_surface_2/vertical_ray_shooting.cpp, and \ref
    Arrangement_on_surface_2/batched_point_location.cpp. The arrangement
    vertices are drawn as small rings, while the query points \f$q_1,
    \ldots, q_6\f$ are drawn as crosses.
    \cgalFigureEnd

    The program listed below constructs a simple arrangement of five line
    segments that form a pentagonal face, with a single isolated
    vertex in its interior, as depicted in \cgalFigureRef{aos_fig-point_location}.
    Notice that we use the same arrangement structure in the next
    three example programs. The arrangement construction is performed by
    the function construct_segment_arr() defined in the header file
    point_location_utils.h. (Its listing is omitted here.) The
    program employs the naive and the landmark strategies to issue
    several point-location queries on this arrangement.

    \cgalExample{Arrangement_on_surface_2/point_location.cpp}

    Note that the program uses the locate_point() function template
    to locate a point and nicely print the result of each query; see
    \ref lst_pl "code example" in Section \ref arr_ssecpl.

    \subsection arr_ssecray_shoot Vertical Ray Shooting

    Another query frequently issued on arrangements is the vertical
    ray-shooting query: Given a query point, which arrangement cell
    is encounter by a vertical ray shot upward (or downward) from this
    point? In the general case the ray hits an edge, but it is possible
    that it hits a vertex, or that the arrangement does not have any
    vertex or edge lying directly above (or below) the query point.

    All point-location classes listed in the previous section are also
    models of the AosVerticalRayShoot_2 concept. That is, they
    all have member functions called ray_shoot_up(q) and
    ray_shoot_down(q) that accept a query point \f$q\f$. These functions
    output a polymorphic object of type
    Arr_point_location_result<Arrangement_2>::%Type, which is a
    discriminated union container of the bounded types \link
    Arrangement_on_surface_2::Vertex_const_handle
    Vertex_const_handle\endlink, \link
    Arrangement_on_surface_2::Halfedge_const_handle
    Halfedge_const_handle\endlink, or \link
    Arrangement_on_surface_2::Face_const_handle
    Face_const_handle\endlink. The latter type is used for the unbounded
    face of the arrangement, in case there is no edge or vertex lying
    directly above (or below) \f$q\f$.

    The function template vertical_ray_shooting_query() listed
    below accepts a vertical ray-shooting object, the type of which
    models the AosVerticalRayShoot_2 concept. It exports
    the result of the upward vertical ray-shooting operation from a
    given query point to the standard output-stream. The ray-shooting
    object vrs is assumed to be already attached to an arrangement.
    The function template is defined in the header file
    point_location_utils.h.

    \code
    template
    void shoot_vertical_ray(const RayShoot& vrs,
    const typename
    VerticalRayShooting::Arrangement_2::Point_2& q) {
    using Vertical_ray_shooting = VerticalRayShooting;

    // Perform the point-location query.
    typename Vertical_ray_shooting::result_type obj = vrs.ray_shoot_up(q);

    // Print the result.
    using Arrangement_2 = typename Vertical_ray_shooting::Arrangement_2;
    using Vertex_const_handle = typename Arrangement_2::Vertex_const_handle;
    using Halfedge_const_handle = typename Arrangement_2::Halfedge_const_handle;
    using Face_const_handle = typename Arrangement_2::Face_const_handle;

    const Vertex_const_handle* v;
    const Halfedge_const_handle* e;
    const Face_const_handle* f;

    std::cout << "Shooting up from (" << q << ") : ";
    if (v = std::get_if(&obj)) // we hit a vertex
    std::cout << "hit " << (((*v)->is_isolated()) ? "an isolated" : "a")
    << " vertex: " << (*v)->point() << std::endl;
    else if (e = std::get_if(&obj)) // we hit an edge
    std::cout << "hit an edge: " << (*e)->curve() << std::endl;
    else if (f = std::get_if(&obj)) { // we hit nothing
    CGAL_assertion((*f)->is_unbounded());
    std::cout << "hit nothing.\n";
    }
    else CGAL_error();
    }
    \endcode

    The program below uses the function template listed above to
    perform vertical ray-shooting queries on an arrangement. The
    arrangement and the query points are exactly the same as in
    \ref Arrangement_on_surface_2/point_location.cpp; see
    \cgalFigureRef{aos_fig-point_location}.
    \cgalExample{Arrangement_on_surface_2/vertical_ray_shooting.cpp}

    \subsection arr_ssecbatched_pl Batched Point-Location

    Suppose that at a given moment our application has to issue a
    relatively large number \f$m\f$ of point-location queries on a
    specific arrangement object. Naturally, It is possible to define a
    point-location object and use it to issue separate queries on the
    arrangement. However, as explained in Section \ref arr_ssecpl choosing
    a simple point-location strategy (either the naive or the walk
    strategy) means inefficient queries, while the more sophisticated
    strategies need to construct auxiliary structures that incur
    considerable overhead in running time.

    Alternatively, the 2D Arrangement package includes a free
    locate() function that accepts an arrangement and a range of query
    points as its input and sweeps through the arrangement to locate all
    query points in one pass. The function outputs the query results as
    pairs, where each pair consists of a query point and a discriminated
    union container, which represents the cell containing the point; see
    Section \ref arr_ssecpl. The output pairs are sorted in increasing
    \f$xy\f$-lexicographical order of the query point.

    The batched point-location operation is carried out by sweeping the
    arrangement. Thus, it takes \cgalBigO{(m+N)\log{(m+N)}} time, where
    \f$N\f$ is the number of edges in the arrangement. Issuing separate
    queries exploiting a point-location strategy with logarithmic query
    time per query, such as the trapezoidal map RIC strategy (see Section
    \ref aos_sssec-pl_strategy), is asymptotically more efficient. However,
    experiments show that when the number \f$m\f$ of point-location
    queries is of the same order of magnitude as \f$N\f$, the batched
    point-location operation is more efficient in practice. One of the
    reasons for the inferior performance of the alternative
    (asymptotically faster) procedures is the necessity to construct and
    maintain complex additional data structures.

    The program below issues a batched point-location query, which
    is essentially equivalent to the six separate queries performed in
    \ref Arrangement_on_surface_2/point_location.cpp; see Section
    \ref arr_ssecpl.
    \cgalExample{Arrangement_on_surface_2/batched_point_location.cpp}

    \section arr_secgl_funcs Free Functions

    The Arrangement_on_surface_2 class template is used to represent
    subdivisions of two-dimensional surfaces induced by curves that lie on
    such surfaces. Its interface is minimal in the sense that the member
    functions hardly perform any geometric operations. In this section we
    explain how to utilize the free functions that enhance that set of
    operations on arrangements. The implementation of these operations
    typically require non-trivial geometric algorithms, and occasionally
    incurs additional requirements on the geometry traits class; the
    implementation of many of the operations is based on two frameworks,
    namely the surface sweep and the zone construction.
    These operations accepts \f$x\f$-monotone curves; thus, the
    geometry-traits class used by the arrangements passed as input to, or
    obtained as output from, these operations must be a model of the
    AosXMonotoneTraits_2 concept; see Section \ref
    aos_sec-geom_traits for the precise definition of this concept. It
    defines the minimal set of geometric primitives, among other things,
    required to perform the algorithms of the surface-sweep and
    zone-construction frameworks.

    \subsection arr_ssec_zone The Zone Construction Algorithm

    Given an arrangement of curves \f$\mathcal{A} =
    \mathcal{A}(\mathcal{C})\f$ embedded in a two-dimensional surface, the
    zone of an additional curve \f$\gamma \notin \mathcal{C}\f$
    in \f$\mathcal{A}\f$ is the union of the features of
    \f$\mathcal{A}\f$, whose closure is intersected by \f$\gamma\f$. The
    complexity of the zone is defined as the sum of the complexities of
    its constituents. (Notice that some vertices are counted multiple
    times.) The zone of a curve \f$\gamma\f$ is computed by locating the
    left endpoint of \f$\gamma\f$ in the arrangement and then "walking"'
    along the curve towards the right endpoint, keeping track of the
    vertices, edges, and faces crossed on the way. The \ref
    PkgArrangementOnSurface2 package offers a generic implementation of an
    algorithm that computes the zone. It is used to implement a set of
    operations that incrementally construct arrangements induced by sets
    of curves that lie in two-dimensional surfaces. For simplicity,
    however, we continue to consider arrangements embedded in the plane.

    Section \ref aos_ssec-basic-arr_class explains how to construct
    arrangements of \f$x\f$-monotone curves that are pairwise disjoint in
    their interior when the location of the segment endpoints in the
    arrangement is known. Here we relax this constraint, and allow the
    location of the inserted \f$x\f$-monotone curve endpoints to be
    unknown at the time of insertion.

    \subsubsection arr_sssecinsert_non_x Inserting Pairwise Disjoint Curves

    We retain, for the moment, the requirement that the interior of the
    inserted curve is disjoint from all existing arrangement edges and
    vertices.

    The call \link CGAL::insert_non_intersecting_curve<>
    insert_non_intersecting_curve(arr, c, pl)\endlink inserts the
    \f$x\f$-monotone curve \f$c\f$ into the arrangement arr, with the
    precondition that the interior of \f$c\f$ is disjoint from all
    existing edges and vertices of arr. The third argument pl is a
    point-location object attached to the arrangement; it is used to
    locate both endpoints of \f$c\f$ in the arrangement. Each endpoint is
    expected to either coincide with an existing vertex or lie inside a
    face. It is possible to invoke one of the specialized insertion
    functions (see Section \ref aos_ssec-basic-arr_class), based on the
    query results, and insert \f$c\f$ at its proper
    location.\cgalFootnote{The \cgalFootnoteCode{CGAL::insert_non_intersecting_curve<>()}
    function template, as all other functions reviewed in this section, is
    parameterized by an arrangement type and a point-location type (The
    latter must be substituted by a model of the
    AosPointLocation_2 concept).} The insertion operation thus
    hardly requires any geometric operations on top of the ones needed to
    answer the point-location queries. Moreover, it is sufficient that the
    traits class that substitutes the Traits template parameter of the
    Arrangement_2 class template when the latter is
    instantiated models the concept AosBasicTraits_2 concept
    (and the concept AosLandmarkTraits_2 if the landmark
    point-location strategy is used), and does not have to support the
    computation of intersection points between curves. This implies that
    using a kernel that provides exact geometric predicates, but
    potentially inexact geometric constructions due to round-off errors, is
    still sufficient.

    The free-function template CGAL::insert_non_intersecting_curve<>(arr, c, pl) is overloaded. There is a variant that instead of accepting a
    user-defined point-location object, it constructs a local object of
    the walk point-location type, namely, an instance of the
    Arr_walk_along_line_point_location class template, and uses it to
    insert the curve.

    \subsubsection arr_sssecinsert_x_mon Inserting X-monotone Curves

    The time it takes to insert a curve \f$c\f$ using the
    insert_non_intersecting_curve() function template is the sum of the
    time is takes to locate the two endpoints of \f$c\f$ and the time is
    takes to find the exact place for the new two halfedges mapped to
    \f$c\f$ in the circular list of halfedges incident to the two vertices
    mapped to the endpoints of \f$c\f$, respectively. This makes the
    function relatively efficient; however, its preconditions on the input
    curves are still rather restricting. Let us assume that the traits
    class that substitutes the Traits template parameter of the
    Arrangement_2 class template models the refined
    AosXMonotoneTraits_2 concept and supports curve intersection
    computations; see Section \ref aos_sec-geom_traits for the exact
    details. Given an \f$x\f$-monotone curve, it is sufficient to locate
    its left endpoint in the arrangement and to trace its zone
    (see Section \ref arr_ssec_zone) until the right endpoint is
    reached. Each time the new curve \f$c\f$ crosses an existing vertex or
    edge, the curve is split into subcurves (in the latter case, we have
    to split the curve associated with the existing halfedge as well) and
    new edges are associated with the resulting subcurves. Recall that an
    edge is represented by a pair of twin halfedges, so we split it into
    two halfedge pairs.

    The call \link CGAL::insert<>() insert(arr, c, pl)\endlink performs
    this insertion operation. The CGAL::insert<>() function template
    accepts an \f$x\f$-monotone curve \f$c\f$, which may intersect some of
    the curves already in the arrangement arr, and inserts it into the
    arrangement by computing its zone. Users may supply a point-location
    object pl or use the default walk point-location strategy (namely,
    the variant CGAL::insert<>(arr, c) is also available). The
    running-time of this insertion function is proportional to the
    complexity of the zone of the curve \f$c\f$.

    \cgalAdvancedBegin In some cases users may have a prior knowledge of
    the location of the left endpoint of the \f$x\f$-monotone curve
    \f$c\f$ they wish to insert, so they can perform the insertion without
    issuing any point-location queries. This can be done by calling the
    free function template CGAL::insert<>(arr, c, obj), where obj is a
    polymorphic object of type
    Arr_point_location_result<Arrangement_2>::%Type that represents the
    location of \f$c\f$s left endpoint in the arrangement. It is a
    discriminated union container of the bounded types \link
    Arrangement_on_surface_2::Vertex_const_handle
    Vertex_const_handle\endlink, \link
    Arrangement_on_surface_2::Halfedge_const_handle
    Halfedge_const_handle\endlink, or \link
    Arrangement_on_surface_2::Face_const_handle
    Face_const_handle\endlink; see also Section \ref arr_ssecpl.
    \cgalAdvancedEnd

    \subsubsection aos_ssec-insert_gen Inserting General Curves

    So far, all the examples have constructed arrangements of line
    segments, where the Arrangement_2 template was instantiated with an
    instance of the Arr_segment_traits_2 class template. In this case,
    the restriction that CGAL::insert<>() requires an \f$x\f$-monotone
    is irrelevant, as all line segments are \f$x\f$-monotone. (Note that
    we always deal with weakly \f$x\f$-monotone curves, and we
    consider vertical line-segments to be weakly \f$x\f$-monotone).

    Consider an arrangement of circles. A circle is obviously not
    \f$x\f$-monotone, so CGAL::insert<>() cannot be used in this
    case.\cgalFootnote{A key operation performed by \cgalFootnoteCode{CGAL::insert<>()} is
    to locate the left endpoint of the curve in the arrangement. A circle,
    however, does not have any endpoints!} , it is necessary to subdivide
    each circle into two \f$x\f$-monotone circular arcs, namely, its upper
    half and its lower half, and to insert the two individual
    \f$x\f$-monotone arcs.

    The free function template CGAL::insert<>() is overloaded. It is
    possible to another version of this function and pass a curve that is
    not necessarily \f$x\f$-monotone, but this is subject to an important
    condition. Consider the call \link CGAL::insert<>() insert(arr, c, pl)\endlink, where \f$c\f$ is not necessarily \f$x\f$-monotone. In
    this case the type of arr must be an instance of the
    Arrangement_2 class template, where the Traits
    template parameter is substituted by a traits class that models the
    concept AosTraits_2, which refines the
    AosXMonotoneTraits_2 concept. It has to define an additional
    \link AosTraits_2::Curve_2 Curve_2\endlink type, which may
    differ from the \link AosBasicTraits_2::X_monotone_curve_2
    X_monotone_curve_2\endlink type. It also has to support the
    subdivision of curves of this new type into \f$x\f$-monotone curves
    and possibly singular points; see the exact details in Section \ref
    aos_sec-geom_traits. The CGAL::insert<>(arr, c, pl) function
    performs the insertion of the curve \f$c\f$ that does not need to be
    \f$x\f$-monotone, into the arrangement by subdividing it into
    \f$x\f$-monotone subcurves and inserting all individual
    \f$x\f$-monotone subcurves. Users may supply a point-location object
    pl, or use the default walk point-location strategy by calling
    CGAL::insert<>(arr, c).

    \subsubsection arr_sssecinsert_point Inserting Points

    The Arrangement_2 class template has a member function that inserts
    a point as an isolated vertex in a given face. The free function
    template CGAL::insert_point<>(arr, p, pl) inserts a vertex that
    corresponds to the point \f$p\f$ into arr at an arbitrary
    location. It uses the point-location object pl to locate the point
    in the arrangement (by default, the walk point-location strategy is
    used), and acts according to the result as follows:

  • If \f$p\f$ is located inside a face, it is inserted as an isolated vertex inside this face.
  • If \f$p\f$ lies on an edge, the edge is split to create a vertex associated with \f$p\f$.
  • Otherwise,\f$p\f$ coincides with an existing vertex and no further actions are needed.

    In all cases, the function returns a handle to the vertex
    associated with \f$p\f$.

    The type of arr must be and instance of the Arrangement_2 class
    template instantiated with a traits class that models the
    AosXMonotoneTraits_2 concept, as the insertion operation may
    involve the splitting of curves.

    \subsubsection arr_sssecinsert_ex Inserting Intersecting Line Segments (code example)

    \cgalFigureBegin{aos_fig-incremental_insertion,incremental_insertion.png}
    An arrangement of five intersecting line segments, as constructed in
    \ref Arrangement_on_surface_2/incremental_insertion.cpp and
    \ref Arrangement_on_surface_2/aggregated_insertion.cpp. The
    segment endpoints are marked by black disks and the arrangement
    vertices that correspond to intersection points are marked by
    circles. The query point \f$q\f$ is marked with a cross and the face
    that contains it is shaded.
    \cgalFigureEnd

    The program below constructs an arrangement of five intersecting
    line-segments \f$s_1, \ldots, s_5\f$. It is known that \f$s_1\f$ and
    \f$s_2\f$ do not intersect, so
    CGAL::insert_non_intersecting_curve<>() is used to insert them into
    the empty arrangement. The rest of the segments are inserted using
    CGAL::insert<>(). Using a kernel that constructs geometric objects
    in an inexact manner (due to round-off errors) may yield a program that
    computes incorrect results and crashes from time to time. This is
    avoided by using a kernel that provides exact geometric-object
    constructions as well as exact geometric-predicate evaluations. The
    header file arr_exact_construction_segments.h, just like the header
    file arr_inexact_construction_segments.h, contains the definitions
    for arrangements of line segments. Unlike the latter, it uses a
    kernel suitable for arrangements induced by curves that intersect each
    other, namely a kernel that is exact always. Note that we alternately
    use the naive point-location strategy, given explicitly to the
    insertion functions, and the default walk point-location strategy.

    The resulting arrangement is depicted in
    \cgalFigureRef{aos_fig-incremental_insertion}, where the vertices that
    correspond to segment endpoints are drawn as dark discs, and the
    vertices that correspond to intersection points are drawn as
    circles. It consists of 13 vertices, 16 edges, and 5 faces. We also
    perform a point-location query on the resulting arrangement. The query
    point \f$q\f$ is drawn as a plus sign. The face that contains it is
    drawn with a shaded texture. The program calls an instance of the
    function template print_arrangement_size(), which prints
    quantitative measures of the arrangement; see \ref lst_paz
    "code example" for its listing in Section \ref aos_ssec-basic-arr_class.

    \cgalExample{Arrangement_on_surface_2/incremental_insertion.cpp}

    \subsection arr_ssseczone Other Zone Related Functions

    In this section we have described so far free functions that insert
    curves and points into a given arrangement. Now we describe functions
    that do not change the arrangement at all; nevertheless, they are
    closely related to the incremental insertion functions, as they also
    use the zone framework.

    The free function template %CGAL::do_intersect<>(arr, c, pl) checks
    whether the given query curve \f$c\f$ intersects the curves and points
    of an existing arrangement arr. If \f$c\f$ is not \f$x\f$-monotone
    (that is, it is of type \link AosTraits_2::Curve_2
    Curve_2\endlink) the curve is subdivided into \f$x\f$-monotone
    subcurves and isolated points. Each \f$x\f$-monotone curve (or point)
    is checked for intersection in turn using the zone framework. For
    points we simply apply point-location. Given an \f$x\f$-monotone
    curve, first its left endpoint is located; then, its zone is computed
    starting from its left endpoint location. The zone computation
    terminates when an intersection with an arrangement curve or point is
    found or when the right endpoint is reached. A given point-location
    object is used for locating the left endpoint of the curve in the
    existing arrangement. There is a variant that instead of accepting a
    user-defined point-location object, it constructs a local object of
    the walk point-location type, namely, an instance of the
    Arr_walk_along_line_point_location class template, and uses it to
    locate the endpoint. If the given curve is \f$x\f$-monotone then the
    traits type must model the AosXMonotoneTraits_2 concept. If
    the curve is not \f$x\f$-monotone then the traits type must model the
    AosTraits_2 concept.

    The CGAL::zone<>(arr, c, oi, pl) function template computes the zone
    of a given \f$x\f$-monotone curve in a given arrangement. More
    precisely, it outputs all the arrangement cells (namely, vertices,
    edges, and faces) that the input \f$x\f$-monotone curve \f$C\f$
    intersects in the order they are discovered when traversing the curve
    from left to right. The function uses a given point-location object
    to locate the left endpoint of the given curve. There is a variant
    that instead of accepting a user-defined point-location object, it
    constructs a local object of the walk point-location type, namely, an
    instance of the Arr_walk_along_line_point_location class template,
    and uses it to locate the endpoint. The traits type must model the
    AosXMonotoneTraits_2 concept.

    \subsection arr_ssec_sweep The Surface-Sweep Algorithm

    The famous plane-sweep algorithm introduced by Bentley and Ottmann was
    originally formulated for sets of line segments in the plane. The \ref
    PkgSurfaceSweep2 package offers a generic implementation of a
    generalized version of the original plane-sweep algorithm. It (i)
    operates in two-dimensional surfaces (not restricted to the plane),
    (ii) accepts various families of \f$x\f$-monotone curves (not only
    line segments), and (iii) handles overlaps. (Observe that the original
    algorithm did not handle overlaps. Handling overlaps is difficult,
    especially for polyline, as two polylines may overlap in more than one
    connected component.) The generic implementation serves as the
    foundation of a family of concrete operations described in the rest of
    this section, such as aggregately constructing an arrangement induced
    by a set of curves that lie in a two-dimensional surface and outputting
    the overlay of two arrangements.

    Given a set of \f$n\f$ input curves, you can insert the curves in the
    set into an arrangement incrementally one by one. However, the \ref
    PkgArrangementOnSurface2 package also provides a couple of free
    (overloaded) functions that aggregately insert a range of curves into
    an arrangement using the surface-Sweep framework.

  • `CGAL::insert_non_intersecting_curves<>(arr, begin, end)` inserts a range of \f$x\f$-monotone curves given by the range `[begin, end)` into an arrangement `arr`. The \f$x\f$-monotone curves should be pairwise disjoint in their interior and also interior-disjoint from all existing curves and points of `arr`.
  • \link CGAL::insert<>() `insert(arr, begin, end)`\endlink operates on a range of \f$x\f$-monotone curves that may intersect one another.
  • We distinguish between two cases:
    (i) The given arrangement arr is empty (has only an unbounded face),
    so it must be construct from scratch.
    (ii) The given arrangement arr is not empty.

    In the first case, we sweep over the input curves, compute their
    intersection points, and construct the \dcel that represents their
    arrangement. This process is performed in \cgalBigO{(n + k)\log
    n} time, where \f$k\f$ is the total number of intersection
    points. The running time is asymptotically better than the time needed
    for incremental insertion if the arrangement is relatively sparse
    (when \f$k\f$ is \cgalBigO{\frac{n^2}{\log n}}), but it is recommended
    that this aggregate construction process be used even for dense
    arrangements, since the plane-sweep algorithm performs fewer geometric
    operations compared to the incremental insertion algorithms, and hence
    typically runs much faster in practice.

    Another important advantage of the aggregated insertion functions is
    that they do not issue point-location queries. Thus, no point-location
    object needs to be attached to the arrangement. As explained in
    Section \ref arr_ssecpl, there is a trade-off between construction
    time and query time in each of the point-location strategies, which
    affects the running times of the incremental insertion
    process. Naturally, this trade-off is absent in the case of aggregated
    insertion.

    The example below shows how to construct the same arrangement of five
    line segments built incrementally in \ref
    Arrangement_on_surface_2/incremental_insertion.cpp depicted in
    \cgalFigureRef{aos_fig-incremental_insertion} using the aggregate
    insertion function \link CGAL::insert<>() insert()\endlink. Note
    that no point-location object needs to be defined and attached to the
    arrangement.

    \cgalExample{Arrangement_on_surface_2/aggregated_insertion.cpp}

    Next we handle the case where we have to insert a set of \f$n\f$
    curves into an existing arrangement. Let \f$N\f$ denote the number of
    edges in the arrangement. If \f$n\f$ is very small compared to
    \f$N\f$ (in theory, we would say that if \f$n = o(\sqrt{N})\f$), we
    insert the curves one by one. For larger input sets, we use the
    aggregate insertion procedures.

    \cgalFigureBegin{aos_fig-global_insertion,global_insertion.png} An
    arrangement of intersecting line segments, as constructed in \ref
    Arrangement_on_surface_2/global_insertion.cpp. The segments of
    \f$\mathcal{S}_1\f$ are drawn in solid lines and the segments of
    \f$\mathcal{S}_2\f$ are drawn in dark dashed lines. Note that the
    segment \f$s\f$ (light dashed line) overlaps one of the segments in
    \f$\mathcal{S}_1\f$. \cgalFigureEnd

    The program below aggregately construct an arrangement of a set
    \f$\mathcal{S}_1\f$ containing five line segments (drawn as solid
    lines). Then, it inserts a single segment \f$s\f$ (drawn as a dotted
    line) using the incremental insertion function. Finally, it adds a set
    \f$\mathcal{S}_2\f$ with five more line segments (drawn as dashed
    lines) in an aggregate fashion. Notice that the line segments of
    \f$\mathcal{S}_1\f$ are pairwise interior-disjoint, so
    insert_non_intersecting_curves() is safely used. \f$\mathcal{S}_2\f$
    also contains pairwise interior-disjoint segments, but as they
    intersect the existing arrangement, \link
    insert(Arrangement_2&, InputIterator, InputIterator)
    insert()\endlink must be used to insert them. Also note that the
    single segment \f$s\f$ inserted incrementally partially overlaps an
    existing arrangement curve; the overlapped portion is drawn as a
    dash-dotted line.

    \cgalExample{Arrangement_on_surface_2/global_insertion.cpp}

    We summarize the three levels of arrangement types
    based on curve monotonicity and intersection properties in the table
    below. The three levels, starting from the most restrictive, are
    (i) \f$x\f$-monotone curves that are pairwise disjoint in their
    interior,
    (ii) \f$x\f$-monotone curves (which are possibly intersecting one
    another), and
    (iii) general curves. We list the single-curve insertion functions.

    The insertion function template %insert() is overloaded to
    (i) incrementally insert a single \f$x\f$-monotone curve,
    (ii) incrementally insert a single general curve,
    (iii) aggregately insert a set of \f$x\f$-monotone curves, and
    (iv) aggregately insert a set of general curves.
    The CGAL::insert_non_intersecting_curves<>() function template
    aggregately inserts a set of \f$x\f$-monotone pairwise interior-disjoint
    curves into an arrangement.

    \subsection arr_ssecgl_remove Removing Vertices and Edges

    The free functions remove_vertex() and remove_edge() handle the
    removal of vertices and edges from an arrangement, respectively. The
    difference between these functions and the corresponding member
    functions of the Arrangement_2 class template (see Section \ref
    arr_sssecmf_iso_verts and Section \ref arr_sssecmf_halfedges) has to do
    with the ability to merge two curves associated with adjacent edges to
    form a single curve associated with a single edge. An attempt to
    remove a vertex or an edge from an arrangement object arr using the
    free functions above requires that the traits class used to
    instantiate the arrangement type of arr models the concept
    AosXMonotoneTraits_2, which refines the
    AosBasicTraits_2 concept; see Section \ref
    aos_sec-geom_traits.

    The function template CGAL::remove_vertex<>(arr, v) removes the
    vertex \f$v\f$ from the given arrangement arr, where \f$v\f$ is
    either an isolated vertex or is a redundant vertex. Namely,
    it has exactly two incident edges that are associated with two curves
    that can be merged to form a single \f$x\f$-monotone curve. If
    neither of the two cases apply, the function returns an indication
    that it has failed to remove the vertex.

    The function CGAL::remove_edge<>(arr, e) removes the edge \f$e\f$
    from the arrangement by simply calling arr.remove_edge(e); see
    Section \ref arr_ssecmodify. In addition, if either of the end
    vertices of \f$e\f$ becomes isolated or redundant after the removal of
    the edge, it is removed as well.

    \image html global_removal.png
    \image latex global_removal.png

    The following example demonstrates the usage of the free removal
    functions. It creates an arrangement of four line segment \f$s_1,
    \ldots, s_4\f$ forming an H-shape with two horizontal edges induced by
    \f$s_1\f$ and \f$s_2\f$ (drawn as dashed lines). Then it removes the
    two horizontal edges and clears all redundant vertices (drawn as
    lightly shaded discs), such that the final arrangement consists of
    just two edges associated with the vertical line segments \f$s_3\f$
    and \f$s_4\f$.

    \cgalExample{Arrangement_on_surface_2/global_removal.cpp}

    \subsection arr_ssec_decompose Vertical Decomposition

    As you have already seen, an arrangement face may have a fairly
    complicated structure; its outer boundary may be very large, and it
    may contain numerous holes. For many practical applications, it is
    more convenient to analyze the faces by decomposing each into a finite
    number of cells (preferably convex when dealing with arrangements of
    linear curves) of constant complexity. Vertical decomposition is a
    generic way to achieve such a simplification of the arrangement.

    Given an arrangement, we consider each arrangement vertex \f$v\f$, and
    locate the feature lying vertically below the vertex and the feature
    lying vertically above it, or the unbounded face in case there is no
    such feature. (Such a feature is also the result of the vertical
    ray-shooting operation from the vertex \f$v\f$, as described in
    Section \ref arr_ssecray_shoot.) It is now possible to construct two
    vertical segments connecting \f$v\f$ to the feature above it and to
    the feature below it, possibly extending the vertical segments to
    infinity. The collection of the vertical segments and rays computed
    for all arrangement vertices induces a subdivision of the arrangement
    into simple cells. There are two types of bounded two-dimensional
    cells, as follows:

  • Cells whose outer boundaries comprise four edges, of which two originate from the original arrangement and the other two are vertical.
  • Cells whose outer boundaries comprise three edges, of which two originate from the original arrangement and intersect at a common vertex and the remaining one is vertical.

    \cgalFigureBegin{aos_fig-bounded_vd,bounded_vertical_decomposition.png}
    An arrangement of four line segments and its vertical decomposition
    into pseudo trapezoids, as constructed in \ref
    Arrangement_on_surface_2/bounded_vertical_decomposition.cpp. The
    segments of the arrangement are drawn in solid blue lines and the
    segments of the vertical decomposition are drawn in dark dotted lines.
    \cgalFigureEnd

    In the case of an arrangement of line segments, two-dimensional cells
    of the former type are trapezoids (as they have a pair of parallel
    vertical edges), while two-dimensional cells of the latter type are
    triangles, which can be viewed as degenerate trapezoids. The unbounded
    cells can be similarly categorized into two types. Observe that the
    boundary of an unbounded cell contains only one original edge or none
    and it may contain only non-vertical edges. The resulting cells are
    therefore referred to as pseudo trapezoids. The
    \cgalFigureRef{aos_fig-bounded_vd} depicts the vertical decomposition
    of an arrangement induced by four line segments, as constructed in
    \ref Arrangement_on_surface_2/bounded_vertical_decomposition.cpp and
    listed below. The decomposition consists of 14 pseudo trapezoids, out
    of which two are bounded triangles, two are bounded trapezoids, and 10
    are unbounded trapezoids.

    The function template decompose() accepts an arrangement
    \f$\mathcal{A}\f$ and outputs for each vertex \f$v\f$ of
    \f$\mathcal{A}\f$ a pair of features---one that directly lies below
    \f$v\f$ and another that directly lies above \f$v\f$. It is
    implemented as a plane-sweep algorithm, which aggregately computes the
    set of pairs of features. Let \f$v\f$ be a vertex of
    \f$\mathcal{A}\f$. The feature above (respectively below) \f$v\f$ may
    be one of the following:

  • Another vertex \f$u\f$ having the same \f$x\f$-coordinate as \f$v\f$.
  • An arrangement edge associated with an \f$x\f$-monotone curve that contains \f$v\f$ in its \f$x\f$-range.
  • An unbounded face in case \f$v\f$ is incident to an unbounded face, and there is no curve lying above (respectively below) it.
  • An empty object, in case \f$v\f$ is the lower (respectively upper) endpoint of a vertical edge in the arrangement.

    \cgalExample{Arrangement_on_surface_2/bounded_vertical_decomposition.cpp}

    As you might have noticed, the code above contains a call to an
    instance of a the function template read_objects(). It reads the
    description of geometric objects from a file and constructs them. It
    accepts the name of an input file that contains the plain-text
    description of the geometric objects and an output iterator for
    storing the newly constructed objects. When the function is
    instantiated, the first template parameter, namely Type, must be
    substituted by the type of objects to read. It is assumed that an
    extractor operator (>>) that extracts objects of the given type from
    the input stream is available. The listing of the function template,
    which is defined in the file read_objects.h, is omitted here

    \cgalAdvancedBegin

    In Section \ref aos_sec-unbounded you will learn that we also support
    arrangements induced by unbounded curves, referred to as
    unbounded arrangements. For such an arrangement we maintain an
    imaginary rectangle with left, right, bottom, and top boundaries,
    which bound the concrete vertices and edges of the
    arrangement. Halfedges that represent the boundaries of the rectangle
    are fictitious. The decompose() function
    template handles unbounded arrangements. If \f$v\f$ is a vertex of an
    unbounded arrangement, and \f$v\f$ is incident to an unbounded face
    and there is no curve lying above (respectively below) it, the feature
    above (respectively below) \f$v\f$ returned by the function template
    decompose() is a fictitious edge.

    \cgalAdvancedEnd

    \section aos_sec-unbounded Arrangements of Unbounded Curves

    All the arrangements constructed and manipulated in previous chapters
    were induced only by line segments, which are, in particular, bounded
    curves. Such arrangements always have one unbounded face that contains
    all other arrangement features. In this section we explain how to
    construct arrangements of unbounded curves. For simplicity of
    exposition, we stay with linear objects and restrict our examples in
    this section to lines and rays. However, the discussion in this
    section, as well as the software described, apply more generally to
    arbitrary curves in two-dimensional surfaces.

    \subsection aos_ssec-unbounded-rep Representing Arrangements of Unbounded Curves

    Given a set \f$\mathcal{C}\f$ of unbounded curves, a simple approach
    for representing the arrangement induced by \f$\mathcal{C}\f$ would be
    to clip the unbounded curves using an axis-parallel rectangle that
    contains all finite curve endpoints and intersection points between
    curves in \f$\mathcal{C}\f$. This process would result in a set of
    bounded curves (line segments if \f$\mathcal{C}\f$ consists of lines
    and rays), and it would be straightforward to compute the arrangement
    induced by this set. However, we would like to operate directly on
    the unbounded curves without having to preprocess them. Moreover, if
    we are not given all the curves inducing the arrangement in advance,
    then the choice of a good bounding rectangle may change as more curves
    are introduced.

    \cgalFigureBegin{aos_fig-unb_dcel,unb_dcel.png}
    A \dcel representing an arrangement of four lines. Halfedges are
    drawn as thin arrows. The vertices \f$v_1, \ldots, v_8\f$ lie at
    infinity, and are not associated with valid points. The halfedges that
    connect them are fictitious, and are not associated with concrete
    curves. The face denoted \f$f_0\f$ (lightly shaded) is the fictitious
    "unbounded face" which lies outside the bounding rectangle (dashed)
    that bounds the actual arrangement. The four fictitious vertices
    \f$v_{\rm bl}, v_{\rm tl}, v_{\rm br}\f$ and \f$v_{\rm tr}\f$
    represent the four corners of the imaginary bounding rectangle.
    \cgalFigureEnd

    Instead of an explicit approach, we use an implicit bounding rectangle
    embedded in the \dcel structure. \cgalFigureRef{aos_fig-unb_dcel}
    shows the arrangement of four lines that subdivide the plane into
    eight unbounded faces and two bounded ones. Notice that in this case
    portions of the unbounded faces now have outer boundaries (those
    portions inside the bounding rectangle), and the halfedges along these
    outer CCBs are drawn as arrows. The bounding rectangle is drawn
    dashed. The vertices \f$v_1,v_2,\ldots,v_8\f$, which lie on the
    bounding rectangle, represent the unbounded ends of the four lines
    that approach infinity. The halfedges connecting them, which overlap
    with the bounding rectangle, are not associated with geometric curves.
    Thus, we refer to them as fictitious. Note that the outer
    CCBs of the unbounded faces contain fictitious halfedges. The twins of
    these halfedges form together one connected component that corresponds
    to the entire imaginary rectangle. It forms a single hole in the face
    \f$\tilde{f}\f$. We refer to \f$\tilde{f}\f$ as fictitious,
    since it does not correspond to a real two-dimensional cell of the
    arrangement. Finally, there are four additional vertices denoted by
    \f$v_{\rm bl}, v_{\rm tl}, v_{\rm br}\f$, and \f$v_{\rm tr}\f$, which
    coincide with the bottom-left, top-left, bottom-right, and top-right
    corners of the bounding rectangle, respectively. They do not lie on
    any curve, and are referred to as fictitious as well. These
    four vertices identify each of the fictitious edges as lying on the
    top, the bottom, the left, and the right edge of the imaginary
    bounding rectangle. The four fictitious vertices exist even when the
    arrangement is empty: In this case they are connected by four pairs of
    fictitious halfedges that define a single unbounded face (which
    represents the entire \f$\mathbb{R}^2\f$ plane) lying inside the
    imaginary bounding rectangle and a fictitious face lying outside.

    In summary, there are four types of arrangement vertices, which differ
    from one another by their location with respect to the imaginary
    bounding rectangle as follows:

    1. \anchor type-normal A vertex, associated with a point in \f$\mathbb{R}^2\f$. Such a vertex always lies inside the bounding rectangle and has bounded coordinates..
    2. \anchor type-unbounded A vertex that represents an unbounded end of an \f$x\f$-monotone curve that approaches \f$x = -\infty\f$ or at \f$x = \infty\f$. In case of a horizontal line or a curve with a horizontal asymptote, the \f$y\f$-coordinate of the curve end may be finite (see, for example, the vertices \f$v_2\f$ and \f$v_7\f$ in \cgalFigureRef{aos_fig-unb_dcel}), but in general the curve end also approaches \f$y = \pm\infty\f$; see for instance the vertices \f$v_1\f$, \f$v_3\f$, \f$v_6\f$ and \f$v_8\f$ in \cgalFigureRef{aos_fig-unb_dcel}). For convenience, we always take a "tall" enough bounding rectangle and treat such vertices as lying on either the left or the right rectangle edges (that is, if a curve approaches \f$x = -\infty\f$, its left end will be represented by a vertex on the left edge of the bounding rectangle, and if it approaches \f$x = \infty\f$, its right end will be represented by a vertex on the right edge).
    3. \anchor typeunboundedvertical A vertex that represents the unbounded end of a vertical linear curve (line or ray) or of a curve with a vertical asymptote (finite \f$x\f$-coordinate and an unbounded \f$y\f$-coordinate). Such a vertex always lies on one of the horizontal edges of the bounding rectangle (either the bottom one if \f$y = -\infty\f$, or the top one if \f$y = \infty\f$). The vertices \f$v_4\f$ and \f$v_5\f$ in \cgalFigureRef{aos_fig-unb_dcel} are of this type.
    4. \anchor typefictitious The fictitious vertices that represent the four corners of the bounding rectangle.

    \cgalFigureBegin{aos_fig-unb_asymptote,unb_asymptote.png}
    The portions of a horizontal line, a vertical line, and two rectangular
    hyperbolas with horizontal and vertical asymptotes confined to the
    imaginary bounding rectangle.
    \cgalFigureEnd

    A vertex (at infinity) of Type 2 or Type 3 above always has three
    incident edges---one concrete edge that is associated with an
    unbounded portion of an \f$x\f$-monotone curve, and two fictitious
    edges connecting the vertex to its neighboring vertices at infinity or
    the corners of the bounding rectangle; see
    \cgalFigureRef{aos_fig-unb_asymptote}. Fictitious vertices (of type 4
    above) have exactly two incident fictitious edges. See Section \ref
    aos_sec-geom_traits for an explanation on how the traits-class
    interface helps impose the fact that a vertex at infinity is incident
    to a single non-fictitious edge.

    The traits class that substitutes the Traits parameter of the
    Arrangement_2 class template when the latter is
    instantiated specifies whether the arrangement instance supports
    unbounded curves through the definitions of some tags nested in the
    traits class; see Section \ref aos_sssec-geom_traits-concepts_basic
    for details. Every arrangement that supports unbounded curves supports
    bounded curves as well, but not vice versa. Maintaining an arrangement
    that supports unbounded curves incurs an overhead due to the necessity
    to manage the imaginary bounding rectangle. If you know beforehand
    that all input curves that induce a particular arrangement are
    bounded, define your arrangement accordingly. That is, use a traits
    class that does not support unbounded curves.

    \subsubsection arr_sssecunb_basic Basic Manipulation and Traversal Methods

    The types \link Arrangement_on_surface_2::Vertex Vertex\endlink,
    \link Arrangement_on_surface_2::Halfedge Halfedge\endlink, and \link
    Arrangement_on_surface_2::Face Face\endlink nested in the
    Arrangement_2 class template support the methods described below in
    addition to the ones listed in Section \ref arr_ssectraverse. Let
    \f$v\f$, \f$e\f$, and \f$f\f$ be handles to a vertex of type \link
    Arrangement_on_surface_2::Vertex Vertex\endlink, a halfedge of type
    \link Arrangement_on_surface_2::Halfedge Halfedge\endlink, and a
    face of type \link Arrangement_on_surface_2::Face Face\endlink,
    respectively.

  • The calls \link Arrangement_on_surface_2::Vertex::parameter_space_in_x() `v->parameter_space_in_x()`\endlink and \link Arrangement_on_surface_2::Vertex::parameter_space_in_y() `v->parameter_space_in_y()`\endlink determine the location of the geometric embedding of the vertex \f$v\f$. The call \link Arrangement_on_surface_2::Vertex::parameter_space_in_x() `v->parameter_space_in_x()`\endlink returns `CGAL::ARR_INTERIOR` if the \f$x\f$-coordinate associated with \f$v\f$ is finite, `CGAL::ARR_LEFT_BOUNDARY` if \f$v\f$ represents the end of a curve the \f$x\f$-coordinate of which approaches \f$-\infty\f$, and `CGAL::ARR_RIGHT_BOUNDARY` if \f$v\f$ represents the end of a curve the \f$x\f$-coordinate of which approaches \f$\infty\f$. Similarly, the call \link Arrangement_on_surface_2::Vertex::parameter_space_in_y() `v->parameter_space_in_y()`\endlink returns `CGAL::ARR_INTERIOR` if the \f$y\f$-coordinate associated with \f$v\f$ is finite and `CGAL::ARR_BOTTOM_BOUNDARY` or `CGAL::ARR_TOP_BOUNDARY` if \f$v\f$ represents the end of a curve the \f$y\f$-coordinate of which approaches \f$-\infty\f$ or \f$\infty\f$, respectively.

    The nested \link Arrangement_on_surface_2::Vertex Vertex\endlink
    type also provides the Boolean predicate \link
    Arrangement_on_surface_2::Vertex::is_at_open_boundary()
    is_at_open_boundary()\endlink. If the call \link
    Arrangement_on_surface_2::Vertex::is_at_open_boundary()
    v->is_at_open_boundary()\endlink predicates evaluates to false,
    you can access the point associated with \f$v\f$. Otherwise, \f$v\f$
    is not associated with a \link Arrangement_on_surface_2::Point_2
    Point_2\endlink object, as it represents the unbounded end of a
    curve that approaches infinity.

  • The nested \link Arrangement_on_surface_2::Halfedge `Halfedge`\endlink type provides the Boolean predicate \link Arrangement_on_surface_2::Halfedge::is_fictitious `is_fictitious()`\endlink. If the call \link Arrangement_on_surface_2::Halfedge::is_fictitious `e->is_fictitious()`\endlink evaluates to `false`, you can access the \f$x\f$-monotone curve associated with \f$e\f$. Otherwise, \f$e\f$ is not associated with an \link Arrangement_on_surface_2::X_monotone_curve_2 `X_monotone_curve_2`\endlink object.
  • The nested \link Arrangement_on_surface_2::Face `Face`\endlink type provides the Boolean predicate \link Arrangement_on_surface_2::Face::is_fictitious() `is_fictitious()`\endlink. The call \link Arrangement_on_surface_2::Face::is_fictitious() `f->is_fictitious()`\endlink evaluates to `true` only when \f$f\f$ lies outside the bounding rectangle. The method \link Arrangement_on_surface_2::Face::outer_ccb() `outer_ccb()`\endlink (see Section \ref arr_sssectr_face must not be invoked for the fictitious face. \cgalFootnote{Typically, the code is guarded against such malicious calls with adequate preconditions. However, these preconditions are suppressed when the code is compiled with maximum optimization.} Note that a valid unbounded face (of an arrangement that supports unbounded curves) has a valid outer CCB, although the CCB comprises only fictitious halfedges if the arrangement is induced only by bounded curves.

    Let \f$p_l = (x_l,y_l)\f$ and \f$p_r = (x_r,y_r)\f$ be the left and
    right endpoints of a bounded \f$x\f$-monotone curve \f$c\f$,
    respectively. We say that a point \f$p = (x_p,y_p)\f$ lies in the
    \f$x\f$-range of \f$c\f$ if \f$x_l \leq x_p \leq x_r\f$. Let \f$p_l =
    (x_l,y_l)\f$ be the left endpoint of an \f$x\f$-monotone curve \f$c\f$
    unbounded from the right. A point \f$p = (x_p,y_p)\f$ lies in the
    \f$x\f$-range of \f$c\f$ if \f$x_l \leq x_p\f$. Similarly, A point
    \f$p = (x_p,y_p)\f$ lies in the \f$x\f$-range of an \f$x\f$-monotone
    curve unbounded from the left if \f$x_p \leq x_r\f$. Naturally, every
    point \f$p \in \mathbb{R}^2\f$ is in the \f$x\f$-range of an
    \f$x\f$-monotone curve unbounded from the left and from the right.

    \cgalAdvancedBegin

    The function template is_in_x_range() listed below, and defined in
    the file is_in_x_range.h, checks whether a given point \f$p\f$ is in
    the \f$x\f$-range of the curve associated with a given halfedge
    \f$e\f$. The function template also exemplifies how some of the above
    functions can be used. The traits functor \link
    AosBasicTraits_2::Compare_x_2 Compare_x_2\endlink used in
    the code is described in Section \ref
    aos_sssec-geom_traits-concepts_basic.

    \code
    // Check whether the given point is in the x-range of the curve associated
    // with the given halfedge.
    template
    bool is_in_x_range(typename Arrangement::Halfedge_const_handle he,
    const typename Arrangement::Point_2& p,
    const typename Arrangement::Traits_2& traits)
    {
    auto cmp = traits.compare_x_2_object();

    // Compare p with the source vertex (which may lie at x = +/- oo).
    CGAL::Arr_parameter_space src_px = e->source()->parameter_space_in_x();
    CGAL::Comparison_result res_s =
    (src_px == CGAL::ARR_LEFT_BOUNDARY) ? CGAL::SMALLER :
    ((src_px == CGAL::ARR_RIGHT_BOUNDARY) ? CGAL::LARGER :
    cmp(e->source()->point(), p));
    if (res_s == CGAL::EQUAL) return true;

    // Compare p with the target vertex (which may lie at x = +/- oo).
    CGAL::Arr_parameter_space trg_px = e->target()->parameter_space_in_x();
    CGAL::Comparison_result res_t =
    (trg_px == CGAL::ARR_LEFT_BOUNDARY) ? CGAL::SMALLER :
    ((trg_px == CGAL::ARR_RIGHT_BOUNDARY) ? CGAL::LARGER :
    cmp(e->target()->point(), p));

    // p lies in the x-range of the halfedge iff its source and target lie
    // at opposite x-positions.
    return (res_s != res_t);
    }
    \endcode

    \cgalAdvancedEnd

    It is important to observe that the call \link
    Arrangement_on_surface_2::number_of_vertices()
    arr.number_of_vertices()\endlink does not count the vertices at
    infinity in the arrangement arr. To find out this number you need to
    issue the call \link
    Arrangement_on_surface_2::number_of_vertices_at_infinity()
    arr.number_of_vertices_at_infinity()\endlink. Similarly, \link
    Arrangement_on_surface_2::number_of_edges()
    arr.number_of_edges()\endlink does not count the fictitious edges
    (whose number is always \link
    Arrangement_on_surface_2::number_of_vertices_at_infinity()
    arr.number_of_vertices_at_infinity()\endlink + 4) and \link
    Arrangement_on_surface_2::number_of_faces()
    arr.number_of_faces()\endlink does not count the fictitious
    faces. The vertex, halfedge, edge, and face iterators defined by the
    Arrangement_2 class template only go over true features of the
    arrangement; namely, vertices at infinity and fictitious halfedges and
    fictitious faces are skipped. On the other hand, the
    Ccb_halfedge_circulator of the outer boundary of an unbounded face
    or the Halfedge_around_vertex_circulator of a vertex at infinity do
    traverse fictitious halfedges. While an arrangement induced by bounded
    curves has a single unbounded face, an arrangement induced by
    unbounded curves may have several unbounded faces. The call \link
    Arrangement_on_surface_2::number_of_unbounded_faces()
    arr.number_of_unbounded_faces()\endlink returns the number of
    unbounded arrangement faces (Thus, \link
    Arrangement_on_surface_2::number_of_faces()
    arr.number_of_faces()\endlink - \link
    Arrangement_on_surface_2::number_of_unbounded_faces()
    arr.number_of_unbounded_faces()\endlink is the number of bounded
    faces). The calls \link
    Arrangement_on_surface_2::unbounded_faces_begin()
    arr.unbounded_faces_begin()\endlink and \link
    Arrangement_on_surface_2::unbounded_faces_end()
    arr.unbounded_faces_end()\endlink return iterators of the type
    Arrangement_on_surface_2::Unbounded_face_iterator (or its
    non-mutable, const, counterpart type) that define the range of the
    arrangement unbounded faces. Naturally, the value-type of this
    iterator is \link Arrangement_on_surface_2::Face Face\endlink.

    There is no way to directly obtain the fictitious vertices that
    represent the four corners of the imaginary bounding
    rectangle. However, you can obtain the fictitious face through the
    call \link Arrangement_on_surface_2::fictitious_face()
    arr.fictitious_face()\endlink, and then iterate over the boundary of
    its single hole, which represents the imaginary bounding
    rectangle. Recall that an arrangement of bounded curves does not have
    a fictitious face. In this case the call above returns a null handle.

    The example below exhibits the difference between an arrangement
    induced by bounded curves, which has a single unbounded face, and an
    arrangement induced by unbounded curves, which may have several
    unbounded faces. It also demonstrates the usage of the insertion
    function for pairwise interior-disjoint unbounded curves. In this case
    we use an instance of the traits class-template
    Arr_linear_traits_2<Kernel> to substitute the Traits parameter of
    the Arrangement_2 class template when instantiated.
    This traits class-template is capable of representing line segments as
    well as unbounded linear curves, namely, lines and rays. Observe that
    objects of the \link Arr_linear_traits_2::X_monotone_curve_2
    X_monotone_curve_2\endlink type nested in this traits class-template
    are constructible from objects of types \link
    Arr_linear_traits_2::Line_2 Line_2\endlink, \link
    Arr_linear_traits_2::Ray_2 Ray_2\endlink, and \link
    Arr_linear_traits_2::Segment_2 Segment_2\endlink also nested
    in the traits class-template. These three types and the \link
    Arr_linear_traits_2::Point_2 Point_2\endlink type are
    defined by the traits class-template Arr_linear_traits_2<Kernel> to
    be the corresponding types of the kernel used to instantiate the
    traits class-template; see Paragraph \ref arr_sssectr_linear.

    \cgalFigureBegin{aos_fig-unbounded_non_intersecting,unbounded_non_intersecting.png}
    An arrangement of unbounded linear objects, as constructed in
    \ref Arrangement_on_surface_2/unbounded_non_intersecting.cpp.
    \cgalFigureEnd

    The first three curves, \f$c_1\f$, \f$c_2\f$, and \f$c_3\f$, are
    inserted using the specialized insertion functions for
    \f$x\f$-monotone curves whose location in the arrangement is
    known. Notice that inserting an unbounded curve in the interior of an
    unbounded face, or from an existing vertex that represents an bounded
    end of the curve, may cause an unbounded face to split. (This is never
    the case when inserting a bounded curve---compare with Section \ref
    arr_sssecmf_insert_cv.) Three additional rays are then inserted
    incrementally using the insertion function for \f$x\f$-monotone curves,
    the interior of which is disjoint from all arrangement features; see
    the illustration in
    \cgalFigureRef{aos_fig-unbounded_non_intersecting}). Finally, the
    program prints the size of the arrangement using the function template
    print_unbounded_arrangement_size() defined in the header file
    arr_print.h. (Its listing is omitted here.) The program also
    traverses the outer boundaries of its six unbounded faces and prints
    the curves along these boundaries. The header file arr_linear.h,
    which contains the definitions used by the example program, is listed
    immediately after the listing of the main function.

    \cgalExample{Arrangement_on_surface_2/unbounded_non_intersecting.cpp}

    The type definitions used by the example below, as well as by other
    examples that use the Arr_linear_traits_2 class template, are listed
    next. These types are defined in the header file arr_linear.h.

    \code
    #include <CGAL/Exact_predicates_exact_constructions_kernel.h>
    #include <CGAL/Arr_linear_traits_2.h>
    #include <CGAL/Arrangement_2.h>

    using Kernel = CGAL::Exact_predicates_exact_constructions_kernel;
    using Number_type = Kernel::FT;

    using Traits = CGAL::Arr_linear_traits_2;
    using Point = Traits::Point_2;
    using Segment = Traits::Segment_2;
    using Ray = Traits::Ray_2;
    using Line = Traits::Line_2;
    using X_monotone_curve = Traits::X_monotone_curve_2;

    using Arrangement = CGAL::Arrangement_2;
    using Vertex_handle = Arrangement::Vertex_handle;
    using Halfedge_handle = Arrangement::Halfedge_handle;
    using Face_handle = Arrangement::Face_handle;
    \endcode

    \subsubsection arr_sssec-unb_global Free Functions

    All the free functions that operate on arrangements of bounded curves
    (see Section \ref arr_secgl_funcs) can also be applied to arrangements
    of unbounded curves. For example, consider a container of linear
    curves that has to be inserted into an arrangement object, the type of
    which is an instance of the Arrangement_2 class
    template, where the Traits parameter is substituted by the traits
    class that handles linear curves; see Section \ref
    arr_sssectr_linear. You can do it incrementally; namely, insert the
    curves one by one as follows:
    \code
    for (auto it = curves.begin(); it != curves.end(); ++it) insert(arr, *it);
    \endcode
    Alternatively, the curves can be inserted aggregately using a single
    call as follows:
    \code
    insert(arr, curves.begin(), curves.end());
    \endcode
    It is also possible to issue point-location queries and vertical
    ray-shooting queries (see also Section \ref arr_secqueries) on
    arrangements of lines, where the only restriction is that the query
    point has finite coordinates. Note that all the point-location
    strategies mentioned above, except the trapezoidal map strategy, are
    capable of handling arrangements of unbounded curves.

    \subsection arr_ssec-unb_duality Point-Line Duality

    In the following example we show how an arrangement of unbounded lines
    is utilized to solve the following problem: Given a set of points,
    does the set contain at least three collinear points? In this example
    a set of input points is read from a file. The file points.dat is
    used by default. It contains definitions of \f$100\f$ points randomly
    selected on the grid \f$[-10000,10000]\times[-10000,10000]\f$. We
    construct an arrangement of the dual lines, where the line \f$p^{}\f$
    dual to the point \f$p = (x_p, y_p)\f$ is given by the equation \f$y =
    x_p
    x - y_p\f$, and check whether three (or more) of the dual lines
    intersect at a common point, by searching for a (dual) vertex, whose
    degree is greater than \f$4\f$. If such a vertex exists, then there
    are at least three dual lines that intersect at a common point, which
    implies that there are at least three collinear points.

    \cgalExample{Arrangement_on_surface_2/dual_lines.cpp}

    Note that there are no three collinear points among the points defined
    in the input file points.dat. In the second part of the example the
    existence of a collinear triple is forced and verified as follows. A
    line dual to the midpoint of two randomly selected points is
    introduced, and inserted into the arrangement. This operation is
    followed by a test that verifies that a vertex of degree greater than
    \f$4\f$ exists.

    \section aos_sec-curved_surfaces Arrangements on Curved Surfaces

    We are given a surface \f$S\f$ in \f$\mathbb{R}^3\f$ and a set
    \f$\mathcal{C}\f$ of curves embedded in this surface. The curves
    subdivide \f$S\f$ into cells of dimension 0 (vertices), 1
    (edges), and 2 (faces). This subdivision is the
    arrangement \f$\mathcal{A}(\mathcal{C})\f$ induced by
    \f$\mathcal{C}\f$ on \f$S\f$. Arrangements embedded in curved surfaces
    in \f$\mathbb{R}^3\f$ are generalizations of arrangements embedded in
    the plane. In this section we explain how to construct, maintain, and
    manipulate two-dimensional arrangements embedded in orientable
    parametric surfaces in three dimensions, such as planes, cylinders,
    spheres, and tori, and surfaces homeomorphic to them; see
    \cgalFigureRef{aos_fig-surfaces}. Such arrangements have many
    theoretical and practical applications; see, e.g.,
    \cgalCite{as-aa-00}, \cgalCite{cgal:bfhks-apsca-10},
    \cgalCite{cgal:bfhmw-apsgf-10}, \cgalCite{cgal:fhktww-a-07}, and
    \cgalCite{cgal:h-a-04}.

    \cgalFigureAnchor{aos_fig-surfaces}

    \image html sphere.png \image html cylinder.png \image html cone.png \image html ellipsoid.png \image html torus.png \image html paraboloid.png (a) Sphere (b) Cylinder (c) Cone (d) Ellipsoid (e) Torus (f) Paraboloid

    \cgalFigureCaptionBegin{aos_fig-surfaces}
    Various two-dimensional parametric surfaces, arrangements on which
    are supported by the framework.
    \cgalFigureCaptionEnd

    \subsection aos_ssec-curved_surfaces-parametric Parametric Surfaces

    We use \f$\overline{\mathbb{R}}\f$ to denote the compactified real line
    \f$\mathbb{R} \cup {-\infty,+\infty}\f$. The mapping
    \f$x \mapsto x/(1 - x^2)\f$ is a homeomorphism between
    \f$(-1,+1)\f$ and \f$\mathbb{R}\f$ and between \f$[-1,+1]\f$ and
    \f$\overline{\mathbb{R}}\f$. So you may also think of finite intervals
    instead of the (compactified) real line in what follows.

    A parametric surface \f$S\f$ is given by a continuous function
    \f$\phi_S: \Phi \rightarrow \mathbb{R}^3\f$, where the domain \f$\Phi
    = X \times Y\f$ is a rectangular two-dimensional parameter space and
    \f$S = \phi_S(\Phi)\f$. The sets \f$X\f$ and \f$Y\f$ are open,
    half-open, or closed intervals with endpoints in
    \f$\overline{\mathbb{R}}\f$. We use \f$x_{\rm min}\f$, \f$x_{\rm
    max}\f$, \f$y_{\rm min}\f$, and \f$y_{\rm max}\f$ to denote the
    endpoints of \f$X\f$ and \f$Y\f$, respectively.

  • The left side of the boundary of \f$\Phi\f$ consists of the points \f$(x_{\rm min},y)\f$ with \f$y \in {\rm closure}(Y)\f$. It is *open*, if \f$x_{\rm min} \not\in X\f$ or \f$y\not\in Y\f$, and *closed*, otherwise. The right side is defined analogously. The bottom side consists of the points \f$(x, y_{\rm min})\f$ with \f$x \notin (x_{\rm min},x_{\rm max})\f$; the top side is defined analogously. The bottom or top sides can also be open. Note that the "corners" of the parameter space belong to the vertical sides; this asymmetry corresponds to the fact that we sweep \f$x\f$-monotone curves, and not \f$y\f$-monotone curves. The four sides together form the boundary \f$\partial \Phi\f$.
  • A point \f$p \in S\f$ is *regular* if it has only one pre-image under \f$\Phi\f$. All pre-images of a non-regular point lie in the boundary of \f$\Phi\f$. In particular, \f$\phi_S\f$ is bijective on \f$(x_{\rm min},x_{\rm max})\times(y_{\rm min},y_{\rm max})\f$. More precisely, a non-regular point has either exactly two pre-images that lie on opposite sides of the domain, or all points of exactly one side of the domain.
  • A side of the domain is contracted if \f$\phi_S\f$ is constant on it.
    The image of the side is called a contraction point.

    The bottom and top sides of the domain (similarly for the left and
    right sides) are identified if
    \f$\phi_S(x,y_{\rm min}) = \phi_S(x, y_{\rm max})\f$ for all
    \f$x \in X \f$. The curve \f$x \mapsto \phi_S(x,y_{\rm min})\f$ is
    called an identification curve.

    Rectangles, strips, quadrants, halfplanes, and planes can be modeled
    with \f$\phi_S\f$ being the identity mapping. For example,
    \f$\Phi_S(x, y) = (x, y, 0)\f$ with \f$X = Y =(-\infty, +\infty)\f$
    parameterizes a plane. Surfaces such as paraboloids can be
    modeled through continuous and bijective parameterizations, for
    example, \f$\phi_S(x,y) = (x,y,x^2 + y^2)\f$, where
    \f$U = V =(-\infty, +\infty)\f$, defines a paraboloid of revolution.
    Cylinders, tori, spheres, and surfaces homeomorphic to them, require
    more general parameterizations. For example, the unit sphere is
    commonly parameterized as
    \f$\phi_S(x, y) = (\cos x \cos y, \sin x \cos y, \sin y)\f$, where
    \f$\Phi = [-\pi, \pi] \times [-\frac{\pi}{2}, \frac{\pi}{2}]\f$. With
    respect to this parameterization, the north and the south pole and
    all points on the opposite Prime (Greenwich) Meridian are
    non-regular. The north pole \f$(0,0,1)\f$ has infinitely many
    pre-images \f$(x, \pi/2)\f$ with \f$-\pi < x < \pi\f$ and so does the
    south pole \f$(0,0,-1)\f$. The points on the opposite Prime Meridian
    have two pre-images each, namely \f$(-\pi,y)\f$ and \f$(\pi,y)\f$
    with \f$-\pi/2 \leq y \leq \pi/2\f$. We say that the top and bottom
    side of the domain are contracted and the left and right sides
    are identified. These are exactly the kinds of non-injectivity
    that we allow.

    We give more examples. A triangle with corners
    \f$(a_1, b_1), (a_2, b_2)\f$, and \f$(a_3, b_3)\f$ can be
    parameterized via \f$\Phi = [0,1] \times [0,1]\f$ with
    \f$\phi_S(x,y) = (a_1 + x(a_2 - a_1) + xy(a_3-a_2), b_1 +
    x(b_2 - b_1) + xy(b_3-b_2), 0)\f$. The left side of the rectangular
    domain contracts to a point. An open or closed cylinder is
    modeled by identifying the vertical sides and having \f$Y\f$ open or
    closed, respectively. A torus is modeled by identifying the
    vertical sides and the horizontal sides. A paraboloid or
    half-cone may be modeled by identifying the vertical sides
    and contracting one of the horizontal sides to a point. More elegantly,
    they are modeled by a bijective parameterization as given above. A
    sphere is modeled by identifying the vertical sides and
    contracting both horizontal sides. A croissant, a torus with
    one pinch point, is modeled by identifying the vertical and
    identifying the horizontal sides and, in addition, contracting one of
    the pairs. However, the croissant is excluded by our definitions. All
    surfaces supported by our framework are locally homeomorphic to a
    disk, and hence an \dcel data-structure suffices for representing
    arrangements on these surfaces. The croissant is, at the pinch point,
    not locally homeomorphic to a disk, and hence a more general
    cell-tuple data structure than an \dcel would be needed.

    A curve \f$\gamma\f$ is a continuous function \f$\gamma: I \rightarrow
    \Phi\f$, where \f$I\f$ is an open, half-open, or closed interval with
    endpoints 0 and 1, and \f$\gamma\f$ is injective except at a finite
    number of points. If \f$0 \not\in I\f$, the limit \f$\lim_{t
    \rightarrow 0+} \gamma(t)\f$ exists (in the closure of \f$\Phi\f$) and
    lies in an open side of the boundary. Similarly, if \f$1 \not\in I\f$,
    then \f$\lim_{t \rightarrow 1-} \gamma(t)\f$ exists and lies in an
    open side of the boundary. A curve \f$c\f$ in \f$S\f$ is the image of
    a curve \f$\gamma\f$ in the domain.

    A curve is closed in the domain if \f$\gamma(0) =
    \gamma(1)\f$; in particular, \f$0 \in I\f$ and \f$1 \in I\f$. A curve
    is closed in the surface \f$S\f$ (or simply closed) if
    \f$\phi_S(\gamma(0)) = \phi_S(\gamma(1))\f$. A curve \f$\gamma\f$ has
    two ends, the 0-end \f$\langle \gamma,0 \rangle\f$ and the
    1-end \f$\langle \gamma,1 \rangle\f$. If \f$d \in I\f$, the
    \f$d\f$-end has a geometric interpretation. It is a point in
    \f$\Phi\f$. If \f$d \not\in I\f$, the \f$d\f$-end has no geometric
    interpretation. You may think of it as a point on an open side of the
    domain or an initial or terminal segment of \f$\gamma\f$. If \f$d
    \not\in I\f$, we say that the \f$d\f$-end of the curve is open. The
    equator curve on the sphere in standard parameterization is given by
    \f$\gamma(t) = (\pi(2t - 1),0)\f$ for \f$t \in [0,1]\f$. The
    \f$0\f$-end of \f$\gamma\f$ is the point \f$(-\pi,0)\f$ in \f$\Phi\f$
    and a point on the equator of the sphere. It is closed on the sphere,
    but not closed in \f$\Phi\f$. The diagonal \f$(u,u)\f$ in the plane
    is, for example, given by \f$\gamma(t) = (x(t),y(t))\f$ and \f$x(t) =
    y(t) = (t - 1/2)/(t(1-t))\f$. Both ends of this curve are open. The
    \f$d\f$-end of a curve \f$\gamma\f$ is incident to the left side if
    either \f$d \in I\f$ and \f$\gamma(d)\f$ lies on the left side or \f$d
    \not\in I\f$ and \f$\lim_{t \rightarrow d} \gamma(t)\f$ lies on the
    left side, which is then an open side. Similarly for the other sides.

    A strongly \f$x\f$-monotone curve is the image of a curve
    \f$\gamma\f$, such that if \f$t_1 < t_2\f$ for \f$t_1, t_2 \in I\f$,
    then \f$x(t_1) < x(t_2)\f$. A vertical curve is the image of
    a curve \f$\gamma\f$, such that \f$x(t) = C\f$ for all \f$t \in I\f$
    and some \f$C \in X\f$ and \f$y(t_1) < y(t_2)\f$ for \f$t_1 <
    t_2\f$. For instance, every Meridian curve of a sphere parameterized
    as above is vertical. An \f$x\f$-monotone curve is either
    vertical or strongly \f$x\f$-monotone.

    \subsection aos_ssec-curved_surfaces-aos_class The Arrangement on Surface Class Template

    The class template Arrangement_on_surface_2<GeomTraits, TopolTraits>
    can be used to represent a 2D arrangement embedded in a 3D
    surface. The template is parameterized by template parameters
    geometry traits and topology traits. The
    topology-traits type deals with the topology of the parametric
    surface; see Section \ref aos_sec-topol_traits. As explained in the
    previous section, a parametric surface \f$S = \phi_S(\Phi)\f$ is given
    by a continuous function \f$\phi_S: \Phi \rightarrow \mathbb{R}^3\f$,
    where the domain \f$\Phi = X \times Y\f$ is a rectangular
    two-dimensional parameter space. \f$X\f$ and \f$Y\f$ are open,
    half-open, or closed intervals with endpoints in
    \f$\overline{\mathbb{R}}\f$.

    The geometry-traits type introduces the type names of the basic
    geometric objects (i.e., point, curve, and \f$x\f$-monotone curve)
    and the set of operations on objects of these types required to
    construct and maintain the arrangement and to operate on it. The
    traits-concept hierarchy described in Section \ref aos_sec-geom_traits
    accurately defines the requirements imposed on a model of a geometry
    traits class. Recall that requirements apply to the parameter space
    \f$\Phi = X \times Y\f$; thus, they are defined in terms of \f$x\f$
    and \f$y\f$ coordinates. Most requirements apply to all type of
    arrangements regardless of the embedding surface. However, several
    refined concepts apply only to arrangements on surfaces that are not
    in the plane, that is, modeled with \f$\phi_S\f$ not being the
    identity mapping. They differ according to the type of the side
    boundaries of the parameter space being open, closed, contracted, or
    identified.

    At this point only one type of arrangements on non planar surfaces is
    supported, namely, arrangements embedded in the sphere and induced by
    arcs of great circles, also known as geodesic arcs.
    \cgalFigureRef{aos_fig-voronoi} shows various Voronoi diagrams the
    bisectors of which are geodesic arcs. They are represented as
    arrangements induced by geodesic arcs embedded in the sphere.

    \cgalFigureAnchor{aos_fig-voronoi}

    \image html voronoi.jpg \image html degenerate_voronoi.jpg \image html power_diagram.jpg \image html degenerate_power_diagram.jpg (a) (b) (c) (d)

    \cgalFigureCaptionBegin{aos_fig-voronoi}
    Voronoi diagrams on the sphere.
    All diagram edges are geodesic arcs.
    Sites are drawn in red and Voronoi edges are drawn in blue.
    (a) The Voronoi diagram of 32 random points.
    (b) A highly degenerate case of Voronoi diagram of 30 point sites on the sphere.
    (c) The power diagram of 10 random circles.
    (d) A degenerate power diagram of 14 sites on the sphere.
    \cgalFigureCaptionEnd

    \subsection aos_ssec-curved_surfaces-basic Basic Manipulation and Traversal Methods

    The types \link Arrangement_on_surface_2::Vertex Vertex\endlink,
    \link Arrangement_on_surface_2::Halfedge Halfedge\endlink, and \link
    Arrangement_on_surface_2::Face Face\endlink nested in the
    Arrangement_on_surface_2 class template support the methods listed
    in Section \ref arr_ssectraverse and in Section \ref
    arr_sssecunb_basic. Additional methods supported by these types are
    described next. Let \f$v\f$, \f$e\f$, and \f$f\f$ be handles to a
    vertex of type \link Arrangement_on_surface_2::Vertex
    Vertex\endlink, a halfedge of type \link
    Arrangement_on_surface_2::Halfedge Halfedge\endlink, and a face of
    type \link Arrangement_on_surface_2::Face Face\endlink,
    respectively.

  • The calls \link Arrangement_on_surface_2::Vertex::parameter_space_in_x() `v->parameter_space_in_x()`\endlink and \link Arrangement_on_surface_2::Vertex::parameter_space_in_y() `v->parameter_space_in_y()`\endlink determine the location of the geometric embedding of the vertex \f$v\f$. The call \link Arrangement_on_surface_2::Vertex::parameter_space_in_x() `v->parameter_space_in_x()`\endlink returns `ARR_INTERIOR` if the geometric embedding of \f$v\f$ is a point \f$p\f$ the pre-image of which does not lie on the left nor on the right sides of the boundary of the parameter space. If the left and right sides are not identified, then `ARR_LEFT_BOUNDARY` or `ARR_RIGHT_BOUNDARY` are returned if the pre-image of \f$p\f$ lies on the left or the right side, respectively. If the left and right sides are identified, the return value is unspecified and can be either `ARR_LEFT_BOUNDARY` or `ARR_RIGHT_BOUNDARY`. Similarly, the call \link Arrangement_on_surface_2::Vertex::parameter_space_in_y() `v->parameter_space_in_y()`\endlink returns `ARR_INTERIOR` if the geometric embedding of \f$v\f$ is a point \f$q\f$, the pre-image of which does not lie on the bottom nor on the top sides of the boundary of the parameter space. If the bottom and top sides are not identified, then `ARR_BOTTOM_BOUNDARY` or `ARR_TOP_BOUNDARY` are returned if the pre-image of \f$q\f$ lies on the bottom or the top side, respectively. If the bottom and top sides are identified, the return value is unspecified.

    If you want to determine whether the pre-image of a point \f$p\f$
    lies on identified sides, you need to employ one of the two traits
    functors \link
    AosIdentifiedHorizontalTraits_2::Is_on_x_identification_2
    Is_on_x_identification_2\endlink or \link
    AosIdentifiedVerticalTraits_2::Is_on_y_identification_2
    Is_on_y_identification_2\endlink; see Section \ref
    aos_ssec-traits-curved. If the pre-image of an \f$x\f$-monotone
    curve \f$c\f$ does not entirely lie on identified sides, you can
    determine the location of the pre-image of an endpoint of \f$c\f$
    employing either the \link
    AosVerticalSideTraits_2::Parameter_space_in_x_2
    Parameter_space_in_x_2\endlink functor or the \link
    AosHorizontalSideTraits_2::Parameter_space_in_y_2
    Parameter_space_in_y_2\endlink functors; see Section \ref
    aos_ssec-traits-curved. The operations in both functors accept an
    enumeration that indicates the curve end, that is,
    CGAL::ARR_MIN_END or CGAL::ARR_MAX_END, in addition to the curve
    itself.

  • A face in a planar arrangement has at most one outer CCB. However, an arrangement embedded on a surface may present additional scenarios. For example, a face of an arrangement embedded on a torus may have two outer CCBs, and a face of an arrangement embedded on a sphere might be consider a hole inside the surrounding face or vice versa. To this end, outer CCBs and inner CCBs of faces of arrangements embedded on surfaces are symmetrically treated (while maintaining the invariant that a face always lies to the left of every halfedge of every CCB of the face regardless of whether the CCB is inner or outer). The classification of a CCB as inner or outer becomes an implementation detail. The calls \link Arrangement_on_surface_2::Face::outer_ccbs_begin() `f->outer_ccbs_begin()`\endlink and \link Arrangement_on_surface_2::Face::outer_ccbs_end() `f->outer_ccbs_end()`\endlink return iterators of type \link Arrangement_on_surface_2::Face::Outer_ccb_iterator `Outer_ccb_iterator`\endlink that define a range of outer CCBs inside the face \f$f\f$. Similarly, the methods \link Arrangement_on_surface_2::Face::inner_ccbs_begin() `f->inner_ccbs_begin()`\endlink and \link Arrangement_on_surface_2::Face::inner_ccbs_end() `f->inner_ccbs_end()`\endlink return iterators of type \link Arrangement_on_surface_2::Face::Inner_ccb_iterator `Inner_ccb_iterator`\endlink that define a range of inner CCBs inside the face \f$f\f$. (The latter pair of member functions and the iterator type are equivalent to the methods \link Arrangement_on_surface_2::Face::holes_begin() `holes_begin()`\endlink, \link Arrangement_on_surface_2::Face::holes_end() `holes_end()`\endlink, and \link Arrangement_on_surface_2::Face::Hole_iterator `Hole_iterator`\endlink; see Section \ref arr_sssectr_face.) The calls \link Arrangement_on_surface_2::Face::number_of_outer_ccbs() `f->number_of_outer_ccbs()`\endlink and \link Arrangement_on_surface_2::Face::number_of_inner_ccbs() `f->number_of_inner_ccbs()`\endlink return the number of outer CCBs and the number of inner CCBs in \f$f\f$, respectively.

    \cgalAdvancedBegin

    The function template is_in_x_range() listed below, and defined in
    the file spherical_is_in_x_range.h checks whether a given point
    \f$p\f$, in the interior of the parameter space, is in the
    \f$x\f$-range of an \f$x\f$-monotone curve \f$c\f$ that represents a
    great-circle arc. It assumes that the left and right sides of the
    parameter space are identified and the bottom and top sides are
    contracted, which is the settings used by the traits class template
    Arr_geodesic_arc_on_sphere_traits_2<Kernel,X,Y>; see Section \ref
    arr_ssectr_spherical. The traits functors \link
    AosBasicTraits_2::Construct_min_vertex_2
    Construct_min_vertex_2\endlink, \link
    AosBasicTraits_2::Construct_max_vertex_2
    Construct_min_vertex_2\endlink, and \link
    AosBasicTraits_2::Compare_x_2 Compare_x_2\endlink used in
    the code are described is Section \ref
    aos_sssec-geom_traits-concepts_basic. The traits functors \link
    AosVerticalSideTraits_2::Parameter_space_in_x_2
    Parameter_space_in_x_2\endlink, \link
    AosHorizontalSideTraits_2::Parameter_space_in_y_2
    Parameter_space_in_y_2\endlink, \link
    AosIdentifiedVerticalTraits_2::Is_on_y_identification_2
    Is_on_y_identification_2\endlink, and \link
    AosHorizontalSideTraits_2::Compare_x_on_boundary_2
    Compare_x_on_boundary_2\endlink, are described is Section \ref
    aos_ssec-traits-curved.

    \code
    template
    bool is_in_x_range(const typename GeometryTraits::X_monotone_curve_2& c,
    const typename GeometryTraits::Point_2& p,
    const GeometryTraits& traits) {
    CGAL_assertion(! traits.is_on_y_identification_2_object()(p));

    if (traits.is_on_y_identification_2_object()(c)) return false;

    // Note that a great-circle arc that is incident to a pole is vertical.
    auto cmp_x_boundary = traits.compare_x_on_boundary_2_object();
    auto psy = traits.parameter_space_in_y_2_object();
    auto psy_min = psy(c, CGAL::ARR_MIN_END);
    if (psy_min == CGAL::ARR_BOTTOM_BOUNDARY)
    return cmp_x_boundary(p, c, CGAL::ARR_MIN_END) == CGAL::EQUAL;
    auto psy_max = psy(c, CGAL::ARR_MAX_END);
    if (psy_max == CGAL::ARR_TOP_BOUNDARY)
    return cmp_x_boundary(p, c, CGAL::ARR_MAX_END) == CGAL::EQUAL;
    auto psx = traits.parameter_space_in_x_2_object();
    auto psx_min = psx(c, CGAL::ARR_MIN_END);
    auto psx_max = psx(c, CGAL::ARR_MAX_END);
    if ((psx_min == CGAL::ARR_LEFT_BOUNDARY) &&
    (psx_min == CGAL::ARR_RIGHT_BOUNDARY))
    return true;
    auto cmp_x = traits.compare_x_2_object();
    if (psx_min == CGAL::ARR_LEFT_BOUNDARY) {
    const auto& p_right = traits.construct_max_vertex_2_object()(c);
    auto res = cmp_x(p, p_right);
    return ((res == CGAL::SMALLER) || (res == CGAL::EQUAL));
    }
    if (psx_max == CGAL::ARR_RIGHT_BOUNDARY) {
    const auto& p_left = traits.construct_min_vertex_2_object()(c);
    auto res = cmp_x(p_left, p);
    return ((res == CGAL::SMALLER) || (res == CGAL::EQUAL));
    }
    const auto& p_left = traits.construct_min_vertex_2_object()(c);
    auto res = cmp_x(p_left, p);
    if (res == CGAL::LARGER) return false;
    const auto& p_right = traits.construct_max_vertex_2_object()(c);
    res = cmp_x(p, p_right);
    if (res == CGAL::LARGER) return false;
    return true;
    }
    \endcode

    \cgalAdvancedEnd

    \section aos_sec-geom_traits The Geometry Traits

    A geometry traits class encapsulates the definitions of the geometric
    entities and the implementation of the geometric predicates and
    constructions that handle these geometric entities, used by the
    Arrangement_on_surface_2 class template and by the peripheral
    modules. The identified minimal requirements imposed by the various
    algorithms that apply to arrangements are organized in a hierarchy of
    refined geometry-traits concepts. The requirements listed by each
    concept include only the utterly essential types and operations needed
    to implement specific algorithms. This modular structuring yields
    controllable parts that can be produced, maintained, and utilized with
    less effort. For each operation, all the preconditions that its
    operands must satisfy are specified as well, as these may simplify the
    implementation of models of these concepts even further. Each traits
    class models one or more concepts. This section contains a detailed
    description of the concepts in the refinement hierarchy and the
    various traits classes that model these concepts.

    All the algebra required for constructing and manipulating
    arrangements is concentrated in the traits classes. The knowledge
    required to devise a good traits class is very different from the
    knowledge required for the development of the rest of the package or
    for using the package. It has less to do with computational geometry
    and it involves mainly algebra and numerical computation. This way,
    traits classes for new types of curves can be developed with little
    knowledge of algorithms and data structures in computational
    geometry. In this section we discuss how to use existing traits
    classes, but we also explain the concepts these traits classes
    model---a starting point for every novice developer of such classes.

    This section is divided into three parts. The first part describes the
    refinement hierarchy of the arrangement geometry-traits concepts. The
    second part reviews various models of these concepts. These traits
    classes handle different curve families, such as line segments,
    polylines, conic arcs, Bézier curves, algebraic curves, and
    geodesic arcs on the sphere. The last part introduces decorators for
    geometric traits classes. A decorator of a traits class attaches
    auxiliary data to the geometric objects handled by the original traits
    class, thereby extending it.

    \subsection aos_ssec-geom_traits-concepts The Hierarchy of the Geometry Traits Concepts

    A hierarchy of related concepts can be viewed as a directed acyclic
    graph, where a node of the graph represents a concept and an arc
    represents a refinement relation. An arc directed from concept A to concept B
    indicates that concept B refines concept
    A. A rather large directed acyclic graph
    is required to capture the entire hierarchy of the geometry
    traits-class concepts. In the following sections we review individual
    clusters of the graph and describe the relations between them.
    \cgalFigureRef{aos_fig-central_concept_cluster} depicts the central
    cluster.

    \cgalFigureBegin{aos_fig-central_concept_cluster,central_concept_cluster.png}
    The hierarchy of the main geometry traits concepts.
    \cgalFigureEnd

    \subsubsection aos_sssec-geom_traits-concepts_basic The Basic Concept

    A model of the basic concept AosBasicTraits_2 needs to
    define the types \link AosBasicTraits_2::Point_2
    Point_2\endlink and \link
    AosBasicTraits_2::X_monotone_curve_2
    X_monotone_curve_2\endlink, where objects of the former type are the
    geometric mapping of arrangement vertices, and objects of the latter
    type are the geometric mapping of edges. In addition, it has to
    support the set of predicates listed below. This basic set of
    predicates is sufficient for constructing arrangements of bounded
    \f$x\f$-monotone curves that are pairwise disjoint in their interiors
    and points that do not lie in the interiors of the curves. The basic
    set of predicates is also sufficient for answering vertical
    ray-shooting queries and point-location queries with a small
    exception: Locating a point using the landmark strategy requires a
    traits class that models the concept AosLandmarkTraits_2;
    see Section \ref aos_sssec-tr_landmarks_concept.

    \link AosBasicTraits_2::Compare_x_2 **`Compare_x_2`**\endlink:
    Compares the \f$x\f$-coordinates of two points.
    \link AosBasicTraits_2::Compare_xy_2 **`Compare_xy_2`**\endlink:
    Compares two points lexicographically, first by their \f$x\f$-coordinates, and if they are equal, by their \f$y\f$-coordinates.
    \link AosBasicTraits_2::Equal_2 **`Equal_2`**\endlink:
    There are two overloaded Boolean operators that test equality. One returns `true` iff two given points represent the same geometric point in the two-dimensional surface, and the second returns `true` iff the graphs of two given \f$x\f$-monotone curves are the same.\cgalFootnote{The predicate that tests equality between graphs of two \f$x\f$-monotone curves is used only for testing as part of the test suite.}
    \link AosBasicTraits_2::Construct_min_vertex_2 **`Construct_min_vertex_2`**\endlink:
    Returns the lexicographically smallest (or left) endpoint of an \f$x\f$-monotone curve.
    \link AosBasicTraits_2::Construct_max_vertex_2 **`Construct_max_vertex_2`**\endlink:
    Returns the lexicographically largest (or right) endpoint of an \f$x\f$-monotone curve.
    \link AosBasicTraits_2::Is_vertical_2 **`Is_vertical_2`**\endlink:
    Determines whether an \f$x\f$-monotone curve is vertical.
    \link AosBasicTraits_2::Compare_y_at_x_2 **`Compare_y_at_x_2`**\endlink:
    Given an \f$x\f$-monotone curve \f$c\f$ and a point \f$p\f$ that lies in the \f$x\f$-range of \f$c\f$, determines whether \f$p\f$ is below, above or lies on \f$c\f$.
    \link AosBasicTraits_2::Compare_y_at_x_right_2 **`Compare_y_at_x_right_2`**\endlink:
    Given two \f$x\f$-monotone curves \f$c_1\f$ and \f$c_2\f$ that share a common minimal (left) endpoint \f$p\f$, determines whether \f$c_1\f$ is above or below \f$c_2\f$ immediately to the right of \f$p\f$, or whether the two curves overlap there.
    \link AosBasicTraits_2::Do_intersect_2 **`Do_intersect_2`**\endlink:
    Determines whether two given \f$x\f$-monotone curves intersect. An input flag determines whether the curve are closed or open.

    Every model of the concept AosBasicTraits_2 needs to define
    a nested type named \link AosBasicTraits_2::Has_left_category
    Has_left_category\endlink. It determines whether the traits class
    supports the following predicate:

    \link AosBasicTraits_2::Compare_y_at_x_left_2 **`Compare_y_at_x_left_2`**\endlink:
    Given two \f$x\f$-monotone curves \f$c_1\f$ and \f$c_2\f$ that share a common maximal (right) endpoint \f$p\f$, determines whether \f$c_1\f$ is above or under \f$c_2\f$ immediately to the left of \f$p\f$, or whether the two curves overlap there.

    If the AosBasicTraits_2::Has_left_category type nested in a
    model of the basic concept is defined as Tag_true\cgalFootnote{In
    principle, the category type may only be convertible to the tag type,
    but in practice the category is typically explicitly defined as the
    tag.} the model must support the predicate. If the type is defined as
    Tag_false, we resort to an internal version, which is based just on
    the reduced set of provided operations. The internal version might be
    less efficient, but it exempts the traits developer from the providing
    an (efficient) implementation of this predicate---a task that turns
    out to be nontrivial in some cases.

    The basic set of predicates is sufficient for constructing
    arrangements of \f$x\f$-monotone curves that do not reach or approach
    the boundary of the parameter space. The nature of the input curves,
    whether they are expected to reach or approach the left, right,
    bottom, or top side of the boundary of the parameter space, must be
    conveyed by the traits class. This is done through the definition of
    four additional nested types, namely

    1. \link AosBasicTraits_2::Left_side_category `Left_side_category`\endlink,
    2. \link AosBasicTraits_2::Right_side_category `Right_side_category`\endlink,
    3. \link AosBasicTraits_2::Bottom_side_category `Bottom_side_category`\endlink, and
    4. \link AosBasicTraits_2::Top_side_category `Top_side_category`\endlink.
    Each of those types must be convertible to the type `Arr_oblivious_side_tag` for the class to be a model of the concept `AosBasicTraits_2`.

    \subsubsection aos_sssec-geom_traits-concepts_intersecting Intersections

    Constructing an arrangement induced by \f$x\f$-monotone curves that
    may intersect in their interior requires operations that are not part
    of the AosBasicTraits_2 concept. The additional operations
    are listed by the concept AosXMonotoneTraits_2, which
    refines the basic arrangement geometry-traits concept described above.
    While models of the AosXMonotoneTraits_2 concept still
    handle only \f$x\f$-monotone curves, the curves are not restricted to
    be disjoint in their interiors. Such a model must be capable of
    computing points of intersection between \f$x\f$-monotone curves,
    splitting curves at these intersection points to obtain pairs of
    interior-disjoint subcurves, and optionally merging pairs of
    subcurves. A point of intersection between two curves is also
    represented by the \link AosBasicTraits_2::Point_2
    Point_2\endlink type. A model of the refined concept must define an
    additional type called Multiplicity. An object of this type
    indicates the multiplicity of the intersection point of two curves,
    also referred to as the intersection
    number.\cgalFootnote{See, e.g.,
    https://en.wikipedia.org/wiki/Intersection_number for more information
    about intersection numbers.} Loosely speaking, if two curves intersect
    at a point \f$p\f$ but have different tangents (first derivatives) at
    \f$p\f$, The point \f$p\f$ is of multiplicity 1. If the curve tangents
    are equal but their curvatures (second derivatives) are not, \f$p\f$
    is of multiplicity 2, and so on. The multiplicity of points of
    intersection between line segments is always 1, and the multiplicity
    of a point of intersection between two polylines is 1 if the
    intersection point is interior to the corresponding two line segments
    of the polylines, and undefined (coded as 0) otherwise. A model of the
    refined concept thus has to support the following additional
    operations:

    \link AosXMonotoneTraits_2::Split_2 **`Split_2`**\endlink:
    Splits an \f$x\f$-monotone curve \f$c\f$ into two subcurves at a given point \f$p\f$ that lies in the interior of \f$c\f$.
    \link AosXMonotoneTraits_2::Are_mergeable_2 **`Are_mergeable_2`**\endlink:
    Determines whether two \f$x\f$-monotone curves \f$c_1\f$ and \f$c_2\f$ that share a common endpoint can be merged into a single continuous \f$x\f$-monotone curve representable by the traits class.\cgalFootnote{On the face of it this seems a difficult predicate to implement. In practice we use very simple tests to decide whether two curves are mergeable: We check whether their underlying curves are identical and whether they do not bend to form a non-\f$x\f$-monotone curve.}
    \link AosXMonotoneTraits_2::Merge_2 **`Merge_2`**\endlink:
    Merges two mergeable \f$x\f$-monotone curves into a single curve.
    \link AosXMonotoneTraits_2::Intersect_2 **`Intersect_2`**\endlink:
    Computes all intersection points and overlapping sections of two given \f$x\f$-monotone curves. If possible, computes also the multiplicity of each intersection point. Providing the multiplicity of an intersection point is not required, but it can expedite the arrangement construction. Typically, the multiplicity is a byproduct of the intersection computation. However, if it is not available, undefined multiplicity (coded as 0) is assumed. Having the multiplicity of intersection points while constructing arrangements enables the exploitation of the geometric knowledge intersection points may have.

    Using a model of the AosXMonotoneTraits_2 it is
    possible to construct arrangements of sets of \f$x\f$-monotone curves
    (and points) that may intersect one another. The two operations
    listed above, regarding the merging of curves, are optional, and should
    be provided only if the type Has_merge_category nested in a model of
    the AosXMonotoneTraits_2 concept is defined as Tag_true.
    Otherwise, it is not possible to merge \f$x\f$-monotone curve and
    redundant vertices may be left in the arrangement due to the removal of
    edges.

    \subsubsection aos_sssec-geom_traits-concepts_arbitrary Supporting Arbitrary Curves

    The concept AosTraits_2 refines the
    AosXMonotoneTraits_2 concept. A model of the refined concept
    must define an additional type that is used to represent general, not
    necessarily \f$x\f$-monotone and not necessarily continuous, curves,
    named \link AosTraits_2::Curve_2 Curve_2\endlink. It also
    has to support the subdivision of a curve of that type into a set of
    continuous \f$x\f$-monotone curves and isolated points. For example,
    the curve \f$c:\ (x^2 + y^2)(x^2 + y^2 - 1) = 0\f$ comprises the unit
    circle (the locus of all points for which \f$x^2 + y^2 = 1\f$) and the
    origin (the singular point \f$(0,0)\f$). \f$c\f$ should therefore be
    subdivided into two circular arcs, the upper part and the lower part
    of the unit circle, and a single isolated point. In particular a
    model of the refined concept has to support the following additional
    operation:

    \link AosTraits_2::Make_x_monotone_2 **`Make_x_monotone_2`**\endlink:
    Divides a given general curve of type \link AosTraits_2::Curve_2 `Curve_2`\endlink into continuous weakly \f$x\f$-monotone curves and isolated points.

    Note that a model of the refined concept AosTraits_2 is
    required only when using the free insert() function templates (see
    Section \ref arr_secgl_funcs) that accept an object of type \link
    AosTraits_2::Curve_2 Curve_2\endlink or a range of objects
    of that type. In all other cases it is sufficient to use a model of
    the AosXMonotoneTraits_2 concept.

    \subsubsection aos_sssec-tr_landmarks_concept The Landmark Concept

    \cgalFigureBegin{aos_fig-landmark_concept_cluster,landmark_concept_cluster.png}
    The traits-concept hierarchy for arrangements associated with the landmark
    point-location strategy.
    \cgalFigureEnd

    The type of an arrangement associated with the landmark point-location
    strategy (see Section \ref arr_ssecpl) must be an instance of the
    Arrangement_on_surface_2<GeomTraits, TopolTraits> class template,
    where the GeomTraits parameter is substituted by a model of the
    concept AosLandmarkTraits_2. (Naturally, it can also model
    either the AosXMonotoneTraits_2 concept or the
    AosTraits_2 concept.) The AosLandmarkTraits_2
    concept refines the two concepts AosApproximatePointTraits_2 and
    AosConstructXMonotoneCurveTraits_2. Each of these two
    concepts, in turn, refines the concept AosBasicTraits_2.

    A model of the AosApproximatePointTraits_2 concept must define a
    fixed precision number type (typically the double-precision
    floating-point double) and support the operation below (in addition
    to fulfilling the requirements listed by the AosBasicTraits_2
    concept).

    \link AosApproximatePointTraits_2::Approximate_2 **`Approximate_2`**\endlink:
    Given a point `p`, approximate the \f$x\f$ and \f$y\f$-coordinates of `p` using a not necessarily multi-precision number type. We use this operation for approximate computations---there are certain operations performed during the search for the location of the point that need not be exact, and that can be performed faster when carried out, for example, using a fixed-precision number type.

    A model of the AosConstructXMonotoneCurveTraits_2 concept
    must support the operation below (in addition to fulfilling the
    requirements listed by the AosBasicTraits_2 concept).

    \link AosConstructXMonotoneCurveTraits_2::Construct_x_monotone_curve_2 **`Construct_x_monotone_curve_2`**\endlink:
    Given two points \f$p_1\f$ and \f$p_2\f$, construct an \f$x\f$-monotone curve connecting \f$p_1\f$ and \f$p_2\f$.

    Most traits classes model the AosTraits_2 concept, and some
    also model the AosLandmarkTraits_2 concept.

    The concept AosConstructCurveTraits_2 refines the concept
    AosBasicTraits_2. A model of the AosConstructCurveTraits_2 concept
    must support the operation below (in addition to fulfilling the
    requirements listed by the AosBasicTraits_2 concept).

    \subsubsection aos_sssec-tr_additional_concepts The Construct Curve Concept

    \link AosConstructCurveTraits_2::Construct_curve_2 **`Construct_curve_2`**\endlink:
    Given two points \f$p_1\f$ and \f$p_2\f$, construct a curve connecting \f$p_1\f$ and \f$p_2\f$.

    The Arr_polyline_traits_2<SubcurveTraits_2> class template handles
    polylines; see Section ~\ref arr_sssectr_polylines.
    The type that substitutes the template parameter SubcurveTraits_2
    when Arr_polyline_traits_2<SubcurveTraits_2> is instantiated must be
    a geometry-traits class that models the concept AosConstructCurveTraits_2
    to enable the construction of polylines from a sequence of two or more points.

    \subsubsection aos_sssec-tr_approximatetion_concept Supporting Approximations of Curves

    Operations on arrangements are guaranteed to be robust only if the
    operations of the geometry traits used to carry out the high-level
    operations are robust. Geometry traits constructors are guaranteed to
    be robust only if the kernel in use supports exact constructions, such
    as the Epec kernel. Even if you only intend to perform point-location
    queries on an arrangement induced by a collection of curves, you need
    an exact-construction kernel, if the curves are not pairwise disjoint
    in their interiors. However, when using an exact-construction kernel
    you still may desire to perform (independent) operations on
    approximations of the points or the interior-disjoint \f$x\f$-monotone
    curves of the arrangements in order to gain speed, for example drawing
    the arrangement on a raster window. Naturally, reconstructing an
    arrangement from the approximations of its points and
    interior-disjoint \f$x\f$-monotone curves, may result with an arrangement
    of a different topology, or even worse, intersections in the interior
    of the curves.

    The concept AosApproximateTraits_2 refines the concept
    AosApproximatePointTraits_2. In addition to the type
    Approximate_number_type required by the latter, a model of the
    AosApproximateTraits_2 concept must define the type
    Approximate_point_2, which is typically defined as
    CGAL::Cartesian<Approximate_number_type>::%Point_2. Also, it must
    support the operations below (in addition to the operation required by
    the concept AosApproximatePointTraits_2).

    \link AosApproximateTraits_2::Approximate_2 **`Approximate_2`**\endlink:
    This operation is overloaded with three versions. The first one returns an approximation of the \f$x\f$- or \f$y\f$-coordinates of a given point as required by the concept `AosApproximatePointTraits_2`; see Section \ref aos_sssec-tr_landmarks_concept. The description of the remaining two follow.

    (i) Given a point \f$p\f$, obtain an approximation of \f$p\f$, which is an
    object of type Approximate_point_2. This is trivially
    implemented using the first version.

    (ii) Given an \f$x\f$-monotone curve \f$c\f$, a small number \f$\epsilon\f$ of
    type Approximate_number_type that serves as an error bound, an
    output iterator associated with a container
    of approximate points, and a flag that indicates whether to
    approximate \f$c\f$ starting from its smallest lexicographic endpoint,
    compute a polyline that approximates \f$c\f$ in the indicated
    direction, such that the largest distance between \f$c\f$ and the
    polyline is not larger than \f$\epsilon\f$. The polyline is
    represented as a sequence of approximate points.

    \subsubsection aos_ssec-traits-curved Supporting Unbounded Curves or Curved Surfaces

    We descend to the bottom level of the hierarchy. The refinements
    described in this section provide the requirements imposed on traits
    classes used with arrangements induced by curves with boundary
    conditions. In particular, these requirements list additional
    operations that handle curves that either reach specific sides of the
    parameter-space boundary (the pre-images of their endpoints lie on
    boundary sides) or approach them (the pre-images of their endpoints
    approach boundary sides). These boundary conditions typically occur
    with unbounded curves or with arrangements embedded in curved
    surfaces. The category types \link
    AosBasicTraits_2::Left_side_category
    Left_side_category\endlink, \link
    AosBasicTraits_2::Right_side_category
    Right_side_category\endlink, \link
    AosBasicTraits_2::Bottom_side_category
    Bottom_side_category\endlink, and \link
    AosBasicTraits_2::Top_side_category
    Top_side_category\endlink, nested in every geometry traits class
    indicate whether the corresponding boundary side (i.e., left, right,
    bottom, and top) is open, closed, contracted, or identified, and
    whether this information is relevant at all. When all curves inserted
    into the arrangement are expected to neither approach nor reach that
    particular boundary side, the information is irrelevant. (Note that we
    explicitly distinguish closed-only, contracted, and identified sides,
    although the latter two are closed in the parameter space as well.)
    Each one of the categories above must be convertible to one of the tag
    types listed below according to the boundary condition that should be
    handled.

  • `Arr_open_side_tag`
  • `Arr_closed_side_tag`
  • `Arr_contracted_side_tag`
  • `Arr_identified_side_tag`
  • `Arr_oblivious_side_tag`

    For each of the four sides of the parameter space there are four
    available concepts, models of which can be used to handle open,
    closed, contracted, and identified sides, respectively. (When curves
    are expected to neither reach nor approach a particular side, special
    handling is not required; thus, there is no need for a corresponding
    concept.) For example, it is required that the category type \link
    AosOpenBottomTraits_2::Bottom_side_category
    Bottom_side_category\endlink, nested in models of the concept
    AosOpenBottomTraits_2, is convertible to the tag type
    Arr_open_side_tag. This makes for a total of 16 abstract concepts
    (combine one of left, right, bottom, and top with one of open, closed,
    contracted, identified). Any one of these individual abstract concept
    is useless on its own; only concepts that refine a combination of 0,
    1, 2, 3, or 4 abstract concepts (which capture the conditions that
    occur in the four sides simultaneously) are purposeful. Theoretically,
    there are \f$\sum_{i=0}^4\binom{i}{4} \cdot 4^i = 5^4 = 625\f$ such
    concepts. However, only a subset of them is meaningful. If a side is
    identified, the opposite side must also be identified. In addition, a
    contracted side must be adjacent to two identified sides. While this
    narrows down the number of tangible concepts, the total number is
    still high; in practice we have used only two so far (not counting the
    "plain" concept, models of which do not handle boundary conditions at
    all), namely, AosOpenBoundaryTraits_2 and
    AosSphericalBoundaryTraits_2; see below for more
    details. Many of the traits class-templates provided by the \ref
    PkgArrangementOnSurface2 package do not handle boundary conditions at
    all. Some of them, such as the Arr_segment_traits_2 traits (see
    Section \ref arr_ssectr_segs) only handle bounded curves. Thus, the
    four category types nested in these models are defined to be
    Arr_oblivious_side_tag.

    \cgalFigureBegin{aos_fig-open_concept_hierarchy,open_concept_hierarchy.png}
    Bottom portion of the refinement hierarchy of the geometry-traits
    concepts for curves embedded in an open surface, for instance, the
    entire plane.
    \cgalFigureEnd

    Several predicates are required to handle \f$x\f$-monotone curves that
    approach the boundary of the parameter space. These predicates are
    sufficient to handle not only curves embedded in an unbounded
    parameter space, but also curves embedded in a bounded parameter space
    with open boundaries. The arrangement type instantiated with a traits
    class that models the combined concept
    AosOpenBoundaryTraits_2 shown in
    \cgalFigureRef{aos_fig-open_concept_hierarchy} can handle curves that
    are open in any direction. Recall that an arrangement that supports
    unbounded \f$x\f$-monotone curves maintains an implicit bounding
    rectangle in the \dcel structure; see Section \ref
    aos_sec-unbounded. If some curves inserted into an arrangement object
    are expected to be unbounded; namely, there exists \f$d \in {0,1}\f$
    such that \f$\lim_{t \rightarrow d}x(t) = \pm\infty\f$ or \f$\lim_{t
    \rightarrow d}y(t) = \pm\infty\f$ holds for at least one input curve
    \f$c(t) = (x(t),y(t))\f$, the arrangement template must be
    instantiated with a model of the AosOpenBoundaryTraits_2
    concept.\cgalFootnote{A curve that reaches the boundary of the
    parameter space in this case is open and unbounded.}

    \cgalFigureBegin{aos_fig-spherical_concept_hierarchy,spherical_concept_hierarchy.png}
    The entire spherical boundary cluster of the refinement hierarchy of the
    geometry-traits concepts for curves embedded in a sphere-like parameterized
    surface.
    \cgalFigureEnd

    A suitable geometry-traits component for arrangements embedded in
    surfaces homeomorphic to a sphere is a model of the combined concept
    AosSphericalBoundaryTraits_2 shown in
    \cgalFigureRef{aos_fig-spherical_concept_hierarchy}. Here the two
    vertical sides of the parameter space are identified and the two
    horizontal sides are contracted.

    \cgalFigureBegin{aos_fig-left_side_cluster,left_side_cluster.png}
    Top portion of the refinement hierarchy of the geometry-traits
    concepts for curves that either reach the left side of the boundary
    of the parameter space or approach it. A similar hierarchy also
    exists for the right, bottom, and top sides.
    \cgalFigureEnd

    The shared requirements for the four options of a side are collected
    in abstract layers called AosLeftSideTraits_2,
    AosRightSideTraits_2, AosBottomSideTraits_2, and
    AosTopSideTraits_2; see, e.g.,
    \cgalFigureRef{aos_fig-left_side_cluster}.

    \cgalFigureBegin{aos_fig-side_clusters,side_clusters.png}
    Top portion of the refinement hierarchy of the geometry-traits
    concepts for curves that either reach the vertical sides of the
    boundary of the parameter space or approach it, and similarly for
    curves that either reach or approach horizontal sides.
    \cgalFigureEnd

    The shared requirements for the options of opposite sides are
    collected in two additional abstract layers called
    AosVerticalSideTraits_2 and
    AosHorizontalSideTraits_2; see
    \cgalFigureRef{aos_fig-side_clusters}.

    \cgalFigureBegin{aos_fig-identified_clusters,identified_clusters.png}
    Top portion of the refinement hierarchy of the geometry-traits
    concepts for curves that reach the identified vertical sides of the
    parameter space and for curves that reach the identified horizontal
    sides of the parameter space.
    \cgalFigureEnd

    Individual concepts for curves that reach the identified left side of
    the parameter space and for curves that reach the identified right
    side of the parameter space do not exist, because if one side is
    identified the opposite side must be identified as well. Similarly,
    individual concepts for curves that reach the identified bottom side
    of the parameter space and for curves that reach the identified top
    side of the parameter space do not exist either. Instead, the shared
    requirements for opposite identified sides are collected in two
    additional abstract concepts called
    AosIdentifiedVerticalTraits_2 and
    AosIdentifiedHorizontalTraits_2; see
    \cgalFigureRef{aos_fig-identified_clusters}. The former lists
    requirements for operations that handle curves that reach identified
    vertical sides of the parameter space, and the latter lists
    requirements for operations that handle curves that reach identified
    horizontal sides of the parameter space.

    In the following we list the specific requirements of all the
    aforementioned concepts.

    The abstract concept AosVerticalSideTraits_2 requires the
    following predicate:

    \link AosVerticalSideTraits_2::Parameter_space_in_x_2 **`Parameter_space_in_x_2`**\endlink:
    This three-valued predicate is overloaded with two versions as follows:

    (i) Given a curve \f$c = (x(t), y(t))\f$ and an enumerator that
    specifies either the minimum end or the maximum end of the curve, and
    thus maps to a parameter value \f$d \in {0,1}\f$, determine the
    location of the \f$d\f$-end of \f$c\f$ along the
    \f$x\f$-dimension. Formally, if \f$c\f$ is open at its \f$d\f$-end,
    determine whether \f$\lim_{t \rightarrow d} x(t)\f$ evaluates to
    \f$x_{\rm min}\f$, \f$x_{\rm max}\f$, or a value in between. If
    \f$c\f$ is not open at its \f$d\f$-end, determine whether \f$x(d)\f$
    is equal to \f$x_{\rm min}\f$, \f$x_{\rm max}\f$, or a value in
    between. Return CGAL::ARR_LEFT_BOUNDARY, CGAL::ARR_RIGHT_BOUNDARY,
    or CGAL::ARR_INTERIOR, accordingly. If \f$c\f$ is vertical and lies
    on a vertical boundary; that is, either \f$\forall p=(x_p, y_p) \in c\f$
    we have \f$x_p = x_{\rm min}\f$ or \f$\forall p=(x_p, y_p) \in c\f$ we
    have \f$x_p = x_{\rm max}\f$, then the boundary side containing \f$c\f$
    cannot be open.

    (ii) Given a point \f$p=(x_p, y_p)\f$, determine the location of the
    point with respect to the \f$x\f$-axis. Formally, determine whether
    \f$x_p\f$ is equal to \f$x_{\rm min}\f$, \f$x_{\rm max}\f$, or a value
    in between. Return CGAL::ARR_LEFT_BOUNDARY,
    CGAL::ARR_RIGHT_BOUNDARY, or CGAL::ARR_INTERIOR, accordingly. If
    \f$p\f$ is on a vertical boundary; that is, \f$x_p \in {x_{\rm
    min},x_{\rm max}}\f$, then the boundary side containing \f$p\f$
    cannot be open and must not be identified. In other words, this
    overloaded version is required only for the concepts
    AosClosedLeftTraits_2, AosClosedRightTraits_2,
    AosContractedLeftTraits_2 and
    AosContractedRightTraits_2.

    The abstract concept AosHorizontalSideTraits_2 requires the
    following predicate:

    \link AosHorizontalSideTraits_2::Parameter_space_in_y_2 **`Parameter_space_in_y_2`**\endlink:
    This three-valued predicate is overloaded with two versions as follows:

    (i) Given a curve \f$c = (x(t), y(t))\f$ and an enumerator that
    specifies either the minimum end or the maximum end of the curve, and
    thus maps to a parameter value \f$d \in {0,1}\f$, determine the
    location of the \f$d\f$-end of \f$c\f$ along the
    \f$y\f$-dimension. Formally, if \f$c\f$ is open at its \f$d\f$-end,
    determine whether \f$\lim_{t \rightarrow d} y(t)\f$ evaluates to
    \f$y_{\rm min}\f$, \f$y_{\rm max}\f$, or a value in between. If
    \f$c\f$ is not open at its \f$d\f$-end, determine whether \f$y(d)\f$
    is equal to \f$y_{\rm min}\f$, \f$y_{\rm max}\f$, or a value in
    between. Return CGAL::ARR_BOTTOM_BOUNDARY, CGAL::ARR_TOP_BOUNDARY,
    or CGAL::ARR_INTERIOR, accordingly. If \f$c\f$ is horizontal and
    lies on a horizontal boundary; that is, either \f$\forall p=(x_p, y_p)
    \in c, y_p = y_{\rm min}\f$ or \f$\forall p=(x_p, y_p) \in c, y_p =
    y_{\rm max}\f$, then the boundary side containing \f$c\f$ cannot be
    open and must not be identified.

    (ii) Given a point \f$p=(x_p, y_p)\f$, determine the location of the
    point along the \f$y\f$-dimension. Formally, determine whether
    \f$y_p\f$ is equal to \f$y_{\rm min}\f$, \f$y_{\rm max}\f$, or a value
    in between. Return CGAL::ARR_BOTTOM_BOUNDARY,
    CGAL::ARR_TOP_BOUNDARY, or CGAL::ARR_INTERIOR, accordingly. If
    \f$p\f$ is on a horizontal boundary; that is, \f$y_p \in {y_{\rm
    min},y_{\rm max}}\f$, then the boundary side containing \f$p\f$
    cannot be open and must not be identified. In other words, this
    overloaded version is required only for the concepts
    AosClosedBottomTraits_2, AosClosedTopTraits_2,
    AosContractedBottomTraits_2 and
    AosContractedTopTraits_2.

    The two symmetric predicates above determine the location of a
    curve-end in the parameter space. However, in general,
    \f$x\f$-coordinates and \f$y\f$-coordinates are handled
    differently. This asymmetry is brought on by the various algorithms
    applied to arrangements, the input and output arguments of which are
    \f$x\f$-monotone curves. Indeed, all curves maintained by any
    arrangement are continuous weakly \f$x\f$-monotone curves. A non
    \f$x\f$-monotone curve is divided into \f$x\f$-monotone sub curves
    (and perhaps points) before it is inserted into an arrangement. This
    asymmetry is also reflected in the predicates listed below. They help
    determining the order of curve-ends lying on the boundary of the
    parameter space with respect to regular points and among each other.

    The concepts AosClosedLeftTraits_2,
    AosClosedRightTraits_2, and
    AosIdentifiedVerticalTraits_2 require the following
    additional predicate:

    \link AosIdentifiedVerticalTraits_2::Compare_y_on_boundary_2 **`Compare_y_on_boundary_2`**\endlink:
    Given two points \f$p_1=(x_{p_1},y_{p_1})\f$ and \f$p_2=(x_{p_2},y_{p_2})\f$, such that at least one of them lies on a vertical boundary side, compare the \f$y\f$-coordinates of the points. That is, compare \f$y_{p_1}\f$ and \f$y_{p_2}\f$. If \f$p_1\f$ (resp. \f$p_2\f$) is on the boundary; that is, \f$x_{p_1} \in \{x_{\rm min},x_{\rm max}\}\f$ (resp. \f$x_{p_2} \in \{x_{\rm min},x_{\rm max}\}\f$), then the vertical boundary side containing \f$p_1\f$ (resp. \f$p_2\f$) must be either closed or identified. In other words, this overloaded version is required only for the concepts `AosClosedLeftTraits_2`, `AosClosedRightTraits_2`, and `AosIdentifiedVerticalTraits_2`.

    The concept AosVerticalSideTraits_2 requires the following additional predicate:

    \link AosVerticalSideTraits_2::Compare_y_near_boundary_2 **`Compare_y_near_boundary_2`**\endlink:

    | \image html compare_y_near_boundary.png
    \image latex compare_y_near_boundary.png | Given two \f$x\f$-monotone curves \f$c_1\f$ and \f$c_2\f$, and an
    enumerator \f$i\f$ that specifies either the minimum ends or the
    maximum ends of the two curves, and thus maps to a parameter value
    \f$d \in {0,1}\f$, compare the \f$y\f$-coordinates of the curves
    near their respective ends. More precisely, compare the
    \f$y\f$-coordinates of the vertical projections of a point \f$p\f$
    onto \f$c_1\f$ and onto \f$c_2\f$. If the enumerator \f$i\f$ specifies
    the minimum ends, the curves must approach the left boundary-side. In
    this case \f$p\f$ is located sufficiently close to the left
    boundary-side, such that the result is invariant under a translation
    of \f$p\f$ closer to the left boundary-side. If \f$i\f$ specifies the
    maximum ends, the curves must approach the right boundary-side. In
    that case \f$p\f$ is located sufficiently close to the right

    boundary-side in a similar manner. |
    | --- | --- |

    The concept AosHorizontalSideTraits_2 requires two additional
    predicates:

    \link AosHorizontalSideTraits_2::Compare_x_on_boundary_2 **`Compare_x_on_boundary_2`**\endlink:
    This predicate is overloaded with three versions. We distinguish between open and non-open sides as explained below.

    (i) Given a regular point \f$p=(x_p,y_p)\f$, an \f$x\f$-monotone curve
    \f$c = (x(t),y(t))\f$, and an enumerator that specifies either the
    minimum end or the maximum end of the curve, and thus maps to a
    parameter value \f$d \in {0,1}\f$, compare the \f$x\f$-coordinate of
    \f$p\f$ and the \f$x\f$-coordinate of \f$c\f$ at its respective limit
    or end depending on whether it is open or non-open. More precisely, if
    \f$c\f$ is open at its \f$d\f$-end, compare the values \f$x_p\f$ and
    \f$\lim_{t \rightarrow d} x(t)\f$. A precondition assures that \f$c\f$
    has a vertical asymptote at its \f$d\f$-end; that is \f$\lim_{t
    \rightarrow d} x(t)\f$ is a real value. If \f$c\f$ is not open,
    compare the values \f$x_p\f$ and \f$x(d)\f$.

    | \image html compare_x_on_boundary.png
    \image latex compare_x_on_boundary.png | (ii) Given two curves \f$c_1 = (x_1(t),y_1(t))\f$ and \f$c_2 =
    (x_2(t),x_2(t))\f$ and enumerators that specify either the minimum end
    or the maximum end of each curve, and thus map to parameter values
    \f$d_1, d_2 \in {0,1}\f$, compare the \f$x\f$-coordinates of the
    curves at their respective limits or ends. More precisely, if
    \f$c_1\f$ (resp. \f$c_2\f$) is open at its \f$d_1\f$-end
    (resp. \f$d_2\f$-end), use the value \f$\lim_{t \rightarrow d_1}
    x_1(t)\f$ (resp. \f$\lim_{t \rightarrow d_2} x_2(t)\f$) for the
    comparison. A precondition assures that \f$c_1\f$ (resp. \f$c_2\f$)
    has a vertical asymptote at its \f$d_1\f$-end (resp. \f$d_2\f$-end);
    that is \f$\lim_{t \rightarrow d_1} x_1(t)\f$ is (resp. \f$\lim_{t
    \rightarrow d_2} x_2(t)\f$) a real value. If \f$c_1\f$
    (resp. \f$c_2\f$) is not open at its \f$d_1\f$-end
    (resp. \f$d_2\f$-end), use the value \f$x_1(d_1)\f$

    (resp. \f$x_2(d_2)\f$) for the comparison. |
    | --- | --- |

    (iii) Given two points \f$p_1=(x_{p_1},y_{p_1})\f$ and
    \f$p_2=(x_{p_2},y_{p_2})\f$, such that at least one of them lies on a
    horizontal boundary side, compare the \f$x\f$-coordinates of the
    points. That is, compare \f$x_{p_1}\f$ and \f$x_{p_2}\f$. If \f$p_1\f$
    (resp. \f$p_2\f$) is on the boundary; that is, \f$y_{p_1} \in {y_{\rm
    min},y_{\rm max}}\f$ (resp. \f$y_{p_2} \in {y_{\rm min},y_{\rm
    max}}\f$), then the boundary side containing \f$p_1\f$
    (resp. \f$p_2\f$) must be either closed or identified. In other words,
    this overloaded version is required only for the concepts
    AosClosedBottomTraits_2, AosClosedTopTraits_2,
    and AosIdentifiedHorizontalTraits_2.

    \link AosHorizontalSideTraits_2::Compare_x_near_boundary_2 **`Compare_x_near_boundary_2`**\endlink:

    | \image html compare_x_near_boundary.png
    \image latex compare_x_near_boundary.png | Given two \f$x\f$-monotone curves \f$c_1\f$ and \f$c_2\f$ and an
    enumerator \f$i\f$ that specifies either the minimum ends or the
    maximum ends of the two curves, and thus map to parameter values
    \f$d_1, d_2 \in {0,1}\f$, respectively, compare the
    \f$x\f$-coordinate of the curves near their respective limits or
    ends. A precondition assures that the \f$x\f$-coordinates of the
    limits or ends of the curves at their respective ends are equal. That
    is, the predicate Compare_x_on_boundary_2 applied to \f$c_1\f$,
    \f$c_2\f$, and \f$i\f$ evaluates to CGAL::EQUAL. Formally, compare
    the \f$x\f$-coordinates of the horizontal projection of a point
    \f$p\f$ onto \f$c_1\f$ and onto \f$c_2\f$. A precondition assures that
    \f$c_1\f$ and \f$c_2\f$ have vertical asymptotes at their respective
    ends. Furthermore, both curves approach the same boundary-side, either
    the bottom or the top, at their respective ends. If both curves
    approach the bottom boundary-side, \f$p\f$ is located far to the
    bottom, such that the result is invariant under a translation of
    \f$p\f$ farther to the bottom. If both curves approach the top

    boundary-side, \f$p\f$ is located far to the top in a similar manner. |
    | --- | --- |

    The concept AosIdentifiedVerticalTraits_2 requires the following
    additional predicate:

    \link AosIdentifiedVerticalTraits_2::Is_on_y_identification_2 **`Is_on_y_identification_2`**\endlink:
    This predicate is overloaded with two versions.

    (i) Given a point \f$p=(x_p, y_p)\f$, determine whether \f$p\f$ lies
    in the image of the vertical (and identified) sides of the
    boundary. More precisely, determine whether \f$x_p \in {x_{\rm
    min},x_{\rm max}}\f$ for all pre-images of \f$p\f$.

    (ii) Given a curve \f$c\f$, determine whether the entire curve \f$c\f$
    lies in the image of the vertical (and identified) sides of the
    boundary.

    Similarly, the concept AosIdentifiedHorizontalTraits_2
    requires the following additional predicate:

    \link AosIdentifiedHorizontalTraits_2::Is_on_x_identification_2 **`Is_on_x_identification_2`**\endlink:
    This predicate is overloaded with two versions.

    (i) Given a point \f$p=(x_p, y_p)\f$, determine whether \f$p\f$ lies
    in the image of the horizontal (and identified) sides of the
    boundary. More precisely, determine whether \f$y_p \in {y_{\rm
    min},y_{\rm max}}\f$ for all pre-images of \f$p\f$.

    (ii) Given a curve \f$c\f$, determine whether the entire curve \f$c\f$
    lies in the image of the horizontal (and identified) sides of the
    boundary.

    \subsection aos_ssec-geom_traits-models Models of the Geometry Traits Concepts

    In this section we review the traits classes that are models of
    concepts introduced in the previous sections. They handle line
    segments, circular arcs, polylines, conic arcs, rational functions,
    arcs of Bézier, and arcs of algebraic curves. The last
    subsection describes decorators for geometric traits classes
    distributed with \cgal, which extend geometric traits-classes by
    attaching auxiliary data with the geometric objects.

    \subsubsection arr_ssectr_segs Traits Classes for Line Segments and Linear Objects

    There are two distinct traits classes that handle line segments. One
    caches information in the curve records (see Section \ref
    arr_sssectr_caching_segs), while the other retains the minimal amount
    of data (see Section \ref arr_sssectr_non_caching_segs). Operations
    on arrangements instantiated with the former traits class consume more
    space, but they are more efficient for dense arrangements (namely,
    arrangements induced by line segments with a large number of
    intersections). Another model handles not only (bounded) line
    segments, but also rays and lines; see Section \ref
    arr_sssectr_linear.

    \paragraph arr_sssectr_caching_segs The Caching Segment-Traits Class

    An instance of the Arr_segment_traits_2<Kernel> class template used
    in most example programs so far is instantiated by substituting the
    Kernel template parameter with a geometric kernel that must conform
    to the Kernel concept; see Package \ref PkgKernel23Concepts. This
    traits class defines its point type to be the Kernel::Point_2
    type. However, neither the \link Arr_segment_traits_2::Curve_2
    Curve_2\endlink nor the \link
    Arr_segment_traits_2::X_monotone_curve_2 X_monotone_curve_2\endlink
    nested types of the traits are defined as the Kernel::Segment_2
    type. A kernel segment is represented by its two endpoints, and these
    may have a large bit size representation when the segment is the
    result of several split operations in comparison with the
    representation of the original-segment endpoints. The large bit size
    representation may significantly slow down the various traits-class
    operations involving such segments. (A straightforward solution would
    be to repeatedly normalize the results of all computations. However,
    our experience shows that indiscriminate normalization considerably
    slows down the arrangement construction.)

    In contrast, the Arr_segment_traits_2 class template represents a
    segment using its supporting line in addition to the two endpoints.
    Most computations are performed on the supporting line, which never
    changes as the segment is split. The Arr_segment_traits_2 class
    template also caches some additional information with each segment to
    speed up various predicates, i.e., two Boolean flags indicating (i)
    whether the segment is vertical and (ii) whether the segment
    target-point is lexicographically larger than its source. The
    calculation of the supporting line and two Boolean flags is delayed to
    the point in time when needed to achieve further improvement in
    efficiency. An \link Arr_segment_traits_2::X_monotone_curve_2
    X_monotone_curve_2\endlink object is still constructible from two
    endpoints or from a kernel segment and converted to an
    X_monotone_curve_2 object. Moreover, an \link
    Arr_segment_traits_2::X_monotone_curve_2 X_monotone_curve_2\endlink
    instance can also be cast or to a Kernel::Segment_2 object. The two
    types are thus convertible to one another.

    Computing the intersection between two segments is preceded by an
    application of an efficient predicate that tests whether an
    intersection exists at all. This optimization has negligible overhead;
    Thus, using an instance of the Arr_segment_traits_2<Kernel> class
    template is still very efficient when constructing arrangements
    induced by line segments with a large number of intersections.
    Efficiency is affected by the substituted geometric kernel. Using
    Exact_predicates_exact_constructions_kernel as the kernel type is in
    general not a bad choice; the coordinates of the segment endpoints are
    represented as multi-precision rational numbers, which ensures the
    correctness of all computations regardless of the input. Computations
    on multi-precision number types (such as Gmpq) take longer than
    computations on machine-precision floating-point. A kernel object of
    the aforementioned type uses numerical filtering to expedite
    computation; see Kernel_2 and Kernel_3. If the input set of line
    segments do not have degeneracies; namely, no two segments in the set
    share a common endpoint, and no three segments intersect at a common
    point, or at least, degeneracies exist but their number is relatively
    small, then filtered computation incurs only negligible overhead
    compared to floating-point arithmetic, which is error-prone. Indeed,
    in almost all examples and applications given in this manual, the
    predefined filtered kernel
    Exact_predicates_exact_constructions_kernel is used to instantiate
    the line-segment traits class.

    \cgalFigureBegin{aos_figpredef_kernels,fan_grids.png,Europe.png}
    (a) An arrangement of \f$104\f$ line segments from the input file
    fan_grids.dat. (b) An arrangement of more than \f$3000\f$ interior
    disjoint line segments, defined in the input file Europe.dat.
    \cgalFigureEnd

    In the following example we use the predefined
    Exact_predicates_exact_constructions_kernel for instantiating our
    segment-traits class. This kernel uses interval arithmetic to filter
    the exact computations. The program reads a set of line segments with
    integer coordinates from a file and computes their arrangement. By
    default it opens the fan_grids.dat input-file, located in the
    examples folder, which contains \f$104\f$ line segments that form
    four "fan-like" grids and induce a dense arrangement, as illustrated
    in \cgalFigureRef{aos_figpredef_kernels} (a):

    \cgalExample{Arrangement_on_surface_2/predefined_kernel.cpp}

    \paragraph arr_sssectr_non_caching_segs The Non-Caching Segment-Traits Class

    The arrangement package offers an alternative segment-traits class
    template that handles line segments, namely the
    Arr_non_caching_segment_basic_traits_2<Kernel> class template. This
    class template and the Arr_segment_traits_2<Kernel> class template
    are both parameterized by a geometric kernel and model the concepts
    AosTraits_2 and AosLandmarkTraits_2.
    \cgalFootnote{They also model the refined concept
    \cgalFootnoteCode{AosDirectionalXMonotoneTraits_2}, which enables Boolean set
    operations; see Package \ref PkgBooleanSetOperations2.} The class
    template Arr_non_caching_segment_traits_2<Kernel> derives from the
    instance Arr_non_caching_segment_basic_traits_2<Kernel>, which
    models the AosLandmarkTraits_2 traits concept but not the
    refined AosXMonotoneTraits_2 concept. Like the
    Arr_segment_traits_2 class template it derives from the Kernel
    type. Unlike the Arr_segment_traits_2 class template it defines its
    point and segment types as Kernel::Point_2 and Kernel::Segment_2,
    respectively, and most of its defined operations are delegations of
    the corresponding operations of the Kernel type. For example, the
    functor Compare_xy_2 is defined as Kernel::Compare_xy_2. The
    remaining operations are defined in terms of just a few other kernel
    operations. For example, the Compare_y_at_x_right_2 predicate is
    defined in terms of the Kernel::Compare_slope_2 predicate (ignoring
    preconditions for the sake of clarity); see Section \ref
    aos_sssec-geom_traits-concepts_basic for the description of this
    predicate. The class template
    Arr_non_caching_segment_basic_traits_2<Kernel> is slightly less
    efficient than the Arr_segment_traits_2 class template for
    constructing arrangements of pairwise interior-disjoint line-segments
    in many cases, as it does not exploit caching at all. Nevertheless,
    you may choose to use this traits class, as it consumes less
    memory. For arrangements of line segments that do intersect you may
    use the class template
    Arr_non_caching_segment_traits_2<Kernel>. However, the performance
    difference in favor of the Arr_segment_traits_2 class template is
    much larger, especially when the number of intersections is large.

    In the following example we read an input file containing a set of
    line segments that are pairwise disjoint in their interior. As the
    segments do not intersect, no new points are constructed and we can
    instantiate the Arr_non_caching_segment_traits_basic_2<Kernel>
    class-template with the predefined
    Exact_predicates_inexact_constructions_kernel. Note that we use the
    insert_non_intersecting_curves() function to construct the
    arrangement. By default, the example opens the Europe.dat
    input-file, located in the examples folder, which contains more than
    \f$3000\f$ line segments with floating-point coordinates that form
    the map of Europe, as depicted in
    \cgalFigureRef{aos_figpredef_kernels} (b):

    \cgalExample{Arrangement_on_surface_2/predefined_kernel_non_intersecting.cpp}

    \paragraph arr_sssectr_linear The Linear-Traits Class

    The Arr_linear_traits_2<Kernel> class used in Section \ref
    aos_sec-unbounded for demonstrating the construction of arrangements
    of unbounded curves is capable of handling bounded and unbounded
    linear objects, namely, lines, rays, and line segments. It models the
    concepts AosTraits_2, AosLandmarkTraits_2, and
    {AosOpenBoundaryTraits_2. It is parameterized by a geometric
    kernel and its nested \link Arr_linear_traits_2::Point_2
    Point_2\endlink type is defined to be the kernel-point type. The
    \link Arr_linear_traits_2::Curve_2 Curve_2\endlink (and \link
    Arr_linear_traits_2::X_monotone_curve_2 X_monotone_curve_2\endlink)
    nested types are constructible from a Kernel::Line_2, a
    Kernel::Ray_2, or from a Kernel::Segment_2 object. Given a
    linear-curve object \f$c\f$, you can use the calls c.is_line(),
    c.is_ray(), and c.is_segment() to find out whether it has a source
    point or a target point. Based on the curve type, you can access its
    endpoints using the methods c.source() (for rays and for line
    segments) and c.target() (for segments only). It is also possible to
    cast a curve into a Kernel::Line_2, a Kernel::Ray_2, or a
    Kernel::Segment_2 type, using the methods c.line(), c.ray(), and
    c.segment(), respectively. Just like the default segment-traits
    class, the linear-curve traits class uses caching techniques to speed
    up its predicate evaluations and object constructions.

    \subsubsection arr_ssectr_polylines The Polyline and Polycurve Traits Classes

    Polylines are continuous piecewise linear curves. Polylines are of
    particular interest, as they can be used to approximate more complex
    curves in the plane. At the same time they are easier to handle in
    comparison to higher-degree algebraic curves, as rational arithmetic
    is sufficient to carry out computations on polylines, and to construct
    arrangements of polylines in an exact and robust manner. Here, we
    extend the notion of polylines and use the term to refer to chains of
    subcurves that are not necessarily linear. However, each subcurve must
    be uniquely defined by (and, thus, can be uniquely constructed from)
    two points within the handled family of curves; see Section \ref
    arr_sssectr_polylines. We also provide a similar traits class that
    handles continuous piecewise curves that are not necessarily linear
    and are not subject to the aforementioned constraint; see Section \ref
    arr_sssectr_polycurves.

    \paragraph arr_sssectr_polylines The Polyline Traits Class

    The Arr_polyline_traits_2<SubcurveTraits_2> class template handles
    polylines. It models the following four concepts:

    • AosTraits_2,

    • AosDirectionalXMonotoneTraits_2

    • AosConstructXMonotoneCurveTraits_2, and

    • AosConstructCurveTraits_2.

    The type that substitutes the template parameter SubcurveTraits_2
    when Arr_polyline_traits_2<SubcurveTraits_2> is instantiated must be
    a geometry-traits class that models the same four concepts. We refer
    to the type that substitutes the template parameter SubcurveTraits_2
    as the subcurve traits hereafter. If, in addition, the
    subcurve traits also models the concept
    AosApproximatePointTraits_2 then the instantiated
    Arr_polyline_traits_2<SubcurveTraits> type models the concept
    AosApproximatePointTraits_2 as well. (By definition, modeling the
    concepts AosApproximatePointTraits_2 and
    AosConstructXMonotoneCurveTraits_2 implies modeling the
    concept AosLandmarkTraits_2.) Similarly, if the subcurve
    traits also models the concept AosOpenBoundaryTraits_2 then
    the instantiated Arr_polyline_traits_2<SubcurveTraits> type models
    the concept AosOpenBoundaryTraits_2 as well. Modeling the
    AosConstructXMonotoneCurveTraits_2 concept implies that the
    subcurve traits must support the construction of a unique
    (\f$x\f$-monotone) segment given two input points.

    An instance of the polyline traits class-template inherits its nested
    point type, i.e., \link Arr_polyline_traits_2::Point_2
    Point_2\endlink, from the subcurve traits, and defines the nested
    types \link Arr_polyline_traits_2::Curve_2 Curve_2\endlink and \link
    Arr_polyline_traits_2::X_monotone_curve_2
    X_monotone_curve_2\endlink, which are used to represent polylines
    and \f$x\f$-monotone polylines, respectively. A polyline of the
    nested type \link Arr_polyline_traits_2::Curve_2 Curve_2\endlink is
    stored as a vector of SubcurveTraits_2::Curve_2 objects, and an
    \f$x\f$-monotone polyline of the nested type \link
    Arr_polyline_traits_2::X_monotone_curve_2 X_monotone_curve_2\endlink
    is stored as a vector of SubcurveTraits_2::X_monotone_curve_2
    objects. The nested X_monotone_curve_2 type inherits from the
    nested type \link Arr_polyline_traits_2::Curve_2 Curve_2\endlink.
    By default, Arr_segment_traits_2 is used as the subcurve traits (in
    case where the SubcurveTraits_2 parameter is omitted). In this case
    the nested types SubcurveTraits_2::Curve_2 and
    SubcurveTraits_2::X_monotone_curve_2 are identical types
    representing line segments.

    A polyline can be constructed given one of the following inputs:

    • A range of points, where two succeeding points in the
      range represent the endpoints of a segment of the polyline.

    • A range of segments.

    • A pair of points \a or a single segment. In this case a polyline
      that consists of a single segment is constructed.

    Note that degenerate polylines are not supported. That is, it is
    impossible to construct a polyline that contains a segment of length
    zero, or an isolated point. Finally, a polyline is
    continuous and well-oriented.
    Moreover, the target of the \f$i\f$th segment is the source of
    the \f$i+1\f$st segment. If the macro CGAL_ALWAYS_LEFT_TO_RIGHT is
    set to 1, then \f$x\f$-monotone polylines are always directed from
    left-to-right. (This option is retained for backward compatibility.)
    Also, note that a single polyline can be split into several
    \f$x\f$-monotone polylines, and that the number of intersection points
    (or overlapping sections) between two polylines can be large.

    For example, the general polyline

    \image html generic-polyline.png
    \image latex generic-polyline.png

    can be represented by one of the following two orientations.

    \image html well_oriented_polyline.png
    \image latex well_oriented_polyline.png

    Distinct \f$x\f$-monotone polylines are rendered in different colors.

    \cgalAdvancedBegin
    Technically speaking, it is possible to construct a general polyline
    that is neither well-oriented nor continuous. However, it is
    impossible to use such polylines for the purpose of computing an
    arrangement.
    \cgalAdvancedEnd

    The polyline traits class also supports the traversal over the range
    of defining segments of a given polyline. The \a first and \a
    past-the-end iterators can be obtained through the access methods
    \link
    CGAL::Arr_polyline_traits_2::X_monotone_curve_2::begin_segments()
    begin_segments()\endlink and \link
    CGAL::Arr_polyline_traits_2::X_monotone_curve_2::end_segments()
    end_segments()\endlink, respectively, of a polyline \f$c\f$. The
    vertices of an \f$x\f$-monotone curve are always stored in a strongly
    monotonic lexicographical order. In other words, \f$x\f$-monotone
    polylines can be directed \a either left-to-right \a or right-to-left.

    The polyline-traits class does not perform any geometric operations
    directly. Instead, it solely relies on the functionality of the
    segment traits. For example, when we need to determine the position of
    a point with respect to an \f$x\f$-monotone polyline, we use binary
    search to locate the relevant segment that contains the point in its
    \f$x\f$-range. Then, we compute the position of the point with respect
    to this segment. Thus, operations on \f$x\f$-monotone polylines of
    size \f$m\f$ typically take \cgalBigO{\log m} time.

    You are free to choose the underlying segment traits class. Your
    decision could be based, for example, on the number of expected
    intersection points; see Section \ref arr_ssectr_segs. Moreover, it is
    possible to substitute the SubcurveTraits_2 template parameter with
    a traits class that handles segments with some additional data
    attached to each individual segment; see Section \ref
    arr_sssec_tr_data_decorators. This makes it possible to associate
    different data objects with the different segments that compose a
    polyline.

    \cgalFigureBegin{aos_fig-polylines,polylines.png}

    An arrangement of three polylines, as constructed in \ref
    Arrangement_on_surface_2/polylines.cpp. Red disks mark vertices
    associated with polyline endpoints, while rings mark vertices that
    correspond to intersection points. The target endpoint of \f$\pi_3\f$
    is also an intersection point; it is rendered as a ring. Observe that
    the polyline \f$\pi_2\f$ is split into three \f$x\f$-monotone
    polylines, and that the two curves \f$\pi_1\f$ and \f$\pi_3\f$ have
    two overlapping sections---an impossible scenario in arrangements of
    line segments. \cgalFigureEnd

    The following example program constructs an arrangement of three
    polylines, \f$\pi_1\f$, \f$\pi_2\f$, and \f$\pi_3\f$, as depicted in
    \cgalFigureRef{aos_fig-polylines}. In this example, each polyline is
    constructed from points stored in a different container, i.e., array,
    list, and vector. Points defining the polylines are not necessarily
    associated with arrangement vertices. The arrangement vertices are
    either the extreme points of each \f$x\f$-monotone polyline (drawn as
    red discs) or the intersection points between two polylines (drawn as
    rings).

    \cgalExample{Arrangement_on_surface_2/polylines.cpp}

    The common types used by the example programs involving arrangements
    of polylines are listed below, and defined in the header file
    arr_polylines.h. As we do in the case of segments and linear
    objects, we use the predefined kernel to instantiate our traits class.
    However, in this case we have yet another layer of template
    instantiation, namely the instantiation of the polyline-traits
    class-template with an instance of a subcurve traits
    class-template. Naturally, we use the Arr_segment_traits_2 class
    template, instantiated with the predefined filtered kernel.

    \code{.cpp}
    #include <CGAL/Exact_predicates_exact_constructions_kernel.h>
    #include <CGAL/Arr_segment_traits_2.h>
    #include <CGAL/Arr_polyline_traits_2.h>
    #include <CGAL/Arrangement_2.h>

    using Kernel = CGAL::Exact_predicates_exact_constructions_kernel;
    using Number_type = Kernel::FT;

    using Segment_traits = CGAL::Arr_segment_traits_2;
    using Traits = CGAL::Arr_polyline_traits_2;
    using Point = Traits::Point_2;
    using Polyline = Traits::Curve_2;
    using Arrangement = CGAL::Arrangement_2;
    \endcode

    \paragraph arr_sssectr_polycurves The Polycurve Traits Class

    The traits class Arr_polycurve_traits_2<SubcurveTraits_2> handles
    piecewise curves that are not necessarily linear, such as conic arcs,
    circular arcs, Bézier curves, or line segments. We call such a
    compound curve a polycurve. Similar to a polyline, a
    polycurve is a chain of subcurves, where each two neighboring
    subcurves in the chain share a common endpoint; that is, the polycurve
    is continuous. As a matter of fact, most characteristics of the
    Arr_polyline_traits_2<SubcurveTraits_2> traits class template apply
    also to the Arr_polycurve_traits_2<SubcurveTraits_2> traits class
    template. The only difference between the two, is that the latter is
    not a model of the concepts
    AosConstructXMonotoneCurveTraits_2 nor
    AosConstructCurveTraits_2, and as such, it is not
    able to construct a subcurve from only two points. As a consequence,
    it does not support the operations that (i) construct a polycurve from
    a sequence of points, and (ii) push a point at the back or at the
    front of a non-empty polycurve.

    \subsubsection arr_ssectr_algebraic Traits Classes for Algebraic Curves

    A curve in our context is typically (but not necessarily) defined as
    the zero set of a bivariate nonzero polynomial with rational (or,
    equivalently, integral) coefficients. We call such polynomials and the
    curves they define \a algebraic. When dealing with linear curves
    (e.g., line segments and polylines), having rational coefficients
    guarantees that all intersection points also have rational
    coordinates, such that the arrangement of such curves can be
    constructed and maintained using only rational arithmetic. The \ref
    PkgArrangementOnSurface2 package also offers geometry traits-classes
    that handle algebraic curves defined by algebraic polynomials of
    degree higher than~\f$1\f$. Unfortunately, the coordinates of the
    intersection points constructed by these traits models are in general
    algebraic numbers\cgalFootnote{A number is called \a algebraic, if it
    is the root of a univariate algebraic polynomial with rational
    coefficients.} of degree higher than \f$1\f$. It is therefore clear
    that we have to use number types different from plain rational to
    represent point coordinates and be able to apply arithmetic operations
    on them.

    Several types of algebraic curves are handled by more than one traits
    model. Section \ref arr_sssectr_linear introduces a few different
    traits models that handle line segments. This duplication becomes more
    evident with the introduction of traits classes that handle algebraic
    curves. The different traits models have different properties. In some
    cases they were developed by different authors at different times
    exploiting different tools that were available at the time they were
    developed. As a general rule, you should always use the minimal traits
    model that still satisfies your needs, as the most dedicated model is
    most likely to be the most efficient.

    \paragraph arr_sssectr_circ_seg Circular Arcs and Line Segments

    Arrangement of circular arcs and of line segments are very useful and
    frequently arise in applications, where curves of interleaved line
    segments and circular arcs are used to model the boundaries of complex
    shapes. Such curves can fit the original boundary more tightly and
    more compactly than, for example, a simple polyline. For example, when
    dilating a polygon by some radius we obtain a shape whose boundary
    comprises of line segments, which correspond to dilated polygon edges,
    and circular arcs, which result from dilated polygon vertices. Using
    the arrangement of the boundary curves it is possible, for example, to
    compute the union of a set of dilated polygons. Besides the
    importance of arrangements of circular arcs and line segments it turns
    out that it is possible to implement efficient traits models that
    handle curves restricted to circular arcs and line segments. Rational
    numbers cannot represent the coordinates of intersection points that
    may arise in such arrangements in an exact manner. Thus, algebraic
    numbers must be used. However, the performance impact that (general)
    algebraic numbers incur can be reduced by the use of an efficient type
    of exact algebraic numbers called square root extension that
    uses rational arithmetic in an almost straightforward fashion.

    Square root numbers have the form \f$\alpha + \beta\sqrt{\gamma}\f$,
    where \f$\alpha\f$, \f$\beta\f$, and \f$\gamma\f$ are rational
    numbers. (Square root numbers are also called one-root numbers.) The
    rational number \f$\gamma\f$ is referred to as the extension. Each
    subset that has a particular extension is closed under arithmetic
    operations and order relations; hence, it is a valid algebraic
    structure.\cgalFootnote{The term algebraic structure refers to the set
    closed under one or more operations satisfying some axioms; see, e.g.,
    https://en.wikipedia.org/wiki/Algebraic_structure. For example, all
    numbers that can be expressed as \f$\alpha + \beta\sqrt{K}\f$, where
    \f$\alpha\f$ and \f$\beta\f$ are rational and \f$K\f$ is a rational
    constant, compose an algebraic structure.} The class template
    CGAL::Sqrt_extension<NT,Root> implements the square root extension
    type. Instances of this template represent square root numbers. It is
    equipped with the implementation of a set of arithmetic operations and
    order relations that exploit identical extensions of operands. It also
    provides the ability to compare two numbers with different extensions
    \f$\gamma_1 \neq \gamma_2\f$ efficiently. Each operation is
    implemented using only few rational arithmetic operations. Here, NT
    is the type of \f$\alpha\f$ and \f$\beta\f$, and Root is the type of
    \f$\gamma\f$. The running times of the arithmetic operations and
    order relations provided by the square root extension when the
    identical-extension condition is met are comparable to the running
    times of the corresponding arithmetic operations of rational-number
    types. The running times of order relations when the condition is not
    met are only slightly larger. In practice, using number types that
    represent (arbitrary) algebraic numbers increases the running time of
    the application significantly.

    We call circles whose center coordinates and squared radii are
    rational numbers rational circles. The equation of such a
    circle, that is, \f$(x - x_0)^2 + (y - y_0)^2 = r^2\f$, where
    \f$(x_0,y_0)\f$ and \f$r\f$ denote the circle center and its radius,
    respectively, has rational coefficients. The coordinates of the points
    of intersection between two such circles are therefore solutions of
    quadratic equations with rational coefficients, in other words,
    algebraic numbers of degree~\f$2\f$ or simply square root numbers. The
    same applies to intersection points between such a rational circle and
    a line, or a line segment, with rational coefficients (a line whose
    equation is \f$ax + by + c = 0\f$, where \f$a\f$, \f$b\f$, and \f$c\f$
    are rational).

    The \ref PkgArrangementOnSurface2 package offers a traits
    class-template called Arr_circle_segment_traits_2<Kernel> that
    exclusively handles line segments, circular arcs, and whole circles
    and models the concepts AosTraits_2 and
    AosDirectionalXMonotoneTraits_2; see Package \ref
    PkgBooleanSetOperations2Ref. Note that it is not a model of the
    AosLandmarkTraits_2 concept. It exploits efficient
    computations with square root numbers, which makes it attractive for
    arrangements induced by line segments, circular arcs, and whole
    circles. When the traits class-template is instantiated, the Kernel
    template parameter must be substituted by a geometric kernel that
    models the Kernel concept. Always plug in a kernel that uses a
    rational number type, such as
    Exact_predicates_exact_constructions_kernel. Observe that the nested
    type \link CGAL::Arr_circle_segment_traits_2::Point_2
    Point_2\endlink defined by the traits class, whose coordinates are
    typically algebraic numbers of degree 2, is \a not the same as the
    Kernel::Point_2 type. The coordinates of a point are represented
    using the number type CoordNT, nested in the traits class-template.

    \cgalFigureBegin{aos_fig-circles,circles.png}
    An arrangement of three circles constructed in \ref
    Arrangement_on_surface_2/circles.cpp. Each circle is split into two
    \f$x\f$-monotone circular arcs, whose endpoints are drawn as red
    disks. Rings mark vertices that correspond to intersection points. The
    vertex \f$v_{\rm max}\f$ is a common intersection point of all three
    circles.
    \cgalFigureEnd

    In the following example an arrangement of three full circles is
    constructed, as shown in \cgalFigureRef{aos_fig-circles}. Each Index is
    split into two \f$x\f$-monotone circular arcs, the endpoints of which
    are drawn as red discs; rings mark vertices that correspond to
    intersection points. Once the arrangement is constructed, we locate
    the vertex of maximal degree in the arrangement. The geometric mapping
    of this vertex, denoted by \f$v_{\rm max}\f$, is the point
    \f$(4,3)\f$, as all three circles intersect at this point and the
    associated vertex has six incident edges.

    \cgalExample{Arrangement_on_surface_2/circles.cpp}

    The types common to the example programs that use the
    Arr_circle_segment_traits_2 class template are listed below and
    defined in the header file arr_circular.h. Even though algebraic
    numbers are required to represent coordinates of points where the
    inducing curves are circles or circular arcs, such as the curves
    handled by the Arr_circle_segment_traits_2 class template, an
    (exact) rational kernel suffices, and a filtered one improves the
    performance further.

    \code{.cpp}
    #include <CGAL/Exact_predicates_exact_constructions_kernel.h>
    #include <CGAL/Arr_circle_segment_traits_2.h>
    #include <CGAL/Arrangement_2.h>

    using Kernel = CGAL::Exact_predicates_exact_constructions_kernel;
    using Number_type = Kernel::FT;
    using Traits = CGAL::Arr_circle_segment_traits_2;
    using CoordNT = Traits::CoordNT;
    using Point = Traits::Point_2;
    using Curve = Traits::Curve_2;
    using Rational_point = Traits::Rational_point_2;
    using Segment = Traits::Rational_segment_2;
    using Circle = Traits::Rational_circle_2;
    using Arrangement = CGAL::Arrangement_2;
    \endcode

    The \link Arr_circle_segment_traits_2::Curve_2 Curve_2\endlink type
    nested in Arr_circle_segment_traits_2 can be used to represent
    circles, circular arcs, or line segments. We now describe and
    demonstrate a variety of ways in which the curves of this type can be
    constructed. A Curve object can be constructed from a
    Kernel::Circle_2 object or from a Kernel::Segment_2 object. A
    circular arc is typically defined by a supporting circle and two
    endpoints, where the endpoints are of type \link
    Arr_circle_segment_traits_2::Point_2 Point_2\endlink, with rational
    or irrational coordinates. The orientation of the arc is determined by
    the orientation of the supporting circle. Similarly, we also support
    the construction of line segments given their supporting line (of type
    Kernel::Line_2) and two endpoints, which may have irrational
    coordinates (unlike the Kernel::Segment_2 type).

    Note that the Kernel::Circle_2 type is used to represent a circle
    whose squared radius is rational, where the radius itself may
    be irrational. However, if the radius is known to be rational, its
    use is recommended for efficiency. It is therefore also possible to
    construct a circle, or a circular arc specifying the circle center (a
    Kernel::Point_2), its rational radius (of type Kernel::FT), and
    its orientation. Finally, we also support the construction of a
    circular arc that is defined by two endpoints and an arbitrary
    interior point that lies on the arc in between its endpoints. In this
    case, all three points are required to have rational coordinates;
    namely, they are all given as Kernel::Point_2 objects.

    \cgalFigureBegin{aos_fig-circular_arcs,circular_arcs.png}
    An arrangement of two full circles, two line segments, and three
    circular arcs as constructed in \ref
    Arrangement_on_surface_2/circular_arcs.cpp. Endpoints are drawn as
    red disks and intersection points are drawn as rings.
    \cgalFigureEnd

    The following example demonstrates the usage of the various
    construction methods for circular arcs and line segments. The
    resulting arrangement is depicted in
    \cgalFigureRef{aos_fig-circular_arcs}. Note the usage of the
    constructor of CoordNT(alpha, beta, gamma), which creates a
    degree-\f$2\f$ algebraic number whose value is \f$\alpha +
    \beta\sqrt{\gamma}\f$.

    \cgalExample{Arrangement_on_surface_2/circular_arcs.cpp}

    It is also possible to construct \f$x\f$-monotone curve objects that
    represent \f$x\f$-monotone circular arcs or line segments using
    similar constructors. (Full circles are not \f$x\f$-monotone.)

    The traits class-template
    Arr_circular_line_arc_traits_2<CircularKernel> offered by the
    arrangement package also handles circular arcs and line segments. It
    is an alternative to the Arr_circle_segment_traits_2<Kernel>
    class-template. These two class templates, while serve similar
    purposes, are based on different concepts, and posses different
    characteristics. You are encouraged to experiment with both, compare
    their performance, and use the most suitable for your case.

    \paragraph arr_sssectr_conic A Traits Class for Conic Arcs

    A conic curve is an algebraic curve of degree 2. Namely, it
    is the locus of all points \f$(x,y)\f$ satisfying the equation \f$c:
    r x^2 + s y^2 + t xy + u x + v y + w = 0\f$, where the six
    coefficients \f$\langle r, s, t, u, v, w \rangle\f$ completely
    characterize the curve. The sign of the expression \f$\Delta_{c} = 4 r
    s - t^2\f$ determines the type of curve:

  • If \f$\Delta_{c} > 0\f$, the curve is an ellipse. A circle is a special case of an ellipse, where \f$r = s\f$ and \f$t = 0\f$.
  • If \f$\Delta_{c} = 0\f$, the curve is a parabola---an unbounded conic curve with a single connected branch. When \f$r = s = t = 0\f$ we have a line, which can be considered as a degenerate parabola.
  • If \f$\Delta_{c} < 0\f$, the curve is a hyperbola. That is, it comprises of two disconnected unbounded branches.

    The Arr_conic_traits_2<RatKernel, AlgKernel, NtTraits> class
    template is capable of handling only bounded arcs of conic curves,
    referred to as conic arcs. A conic arc \f$a\f$ may be either
    (i) a full ellipse, or (ii) defined by the tuple \f$\langle \kappa,
    p_s, p_t, o \rangle\f$, where \f$\kappa\f$ is a conic curve and
    \f$p_s\f$ and \f$p_t\f$ are two points on \f$c\f$ (namely
    \f$\kappa(p_s) = \kappa(p_t) = 0\f$) that define the source
    and target of the arc, respectively. The arc is formed by
    traversing \f$\kappa\f$ from the source to the target going in the
    orientation specified by \f$o\f$, which is typically clockwise or
    counterclockwise orientation, but may also be collinear in case of
    degenerate conic conic-curves, namely, lines or pairs of lines.

    We always assume that the conic coefficients \f$\langle r, s, t, u, v,
    w \rangle\f$ are rational. The coordinates of points of intersection
    between two conic curves with rational coefficients are in general
    algebraic numbers of degree 4. Namely, they are roots of algebraic
    polynomials of degree 4. In addition, conic arcs may not necessarily
    be \f$x\f$-monotone, and must be split at points where the tangent to
    the arc is vertical. In the general case such points typically have
    coordinates that are algebraic numbers of degree 2. Note that as
    arrangement vertices induced by intersection points and points with
    vertical tangents are likely to have algebraic coordinates, we also
    allow the original endpoints of the input arcs \f$p_s\f$ and \f$p_t\f$
    to have algebraic coordinates.

    The Arr_conic_traits_2<RatKernel, AlgKernel, NtTraits> class
    template is designed for efficient handling of arrangements of
    bounded conic arcs. The template has three parameters, defined as
    follows:

  • The `RatKernel` template parameter must be substituted by a geometric kernel whose field type is an exact rational type. It is used to define basic geometric entities (e.g., a line segment or a circle) with rational coefficients. Typically we use one of the standard \cgal kernels, instantiated with the number type `NtTraits::Rational` (see below).
  • The `AlgKernel` template parameter must be substituted by a geometric kernel whose field type is an exact algebraic type. It is used to define points with algebraic coordinates. Typically, we use one of the standard \cgal kernels, instantiated with the number type `NtTraits::Algebraic` (see below).
  • The `NtTraits` template parameter must be substituted by a type that encapsulates all the numeric operations needed for performing geometric computation carried out by the geometric traits class. It defines the `Integer`, `Rational`, and `Algebraic` number-types, and supports several operations on these types, such as conversion between these types, solving quadratic equations, and extracting the real roots of polynomials with integer coefficients. The use of the `CORE_algebraic_number_traits` class, which is included in the arrangement package, is highly recommended. The traits class-template relies on the multi-precision number types implemented in the \core library and performs exact computations on the number types it defines.

    The instantiation of the conic traits class-template is slightly more
    complicated than the instantiation of the traits classes you have
    encountered so far. This instantiation is exemplified in the header
    file arr_conics.h. Note how we first define the rational and
    algebraic kernels using the number types given by the \core number
    type traits-class, then use them to define the conic traits
    class-template. Also note the types defined by the rational kernels,
    which we need for conveniently constructing conic arcs.

    The Arr_conic_traits_2 models the AosTraits_2 and
    AosLandmarkTraits_2 concepts. Its \link
    Arr_conic_traits_2::Point_2 Point_2\endlink type is derived from
    AlgKernel::Point_2, while the \link Arr_conic_traits_2::Curve_2
    Curve_2\endlink type represents a bounded, not necessarily
    \f$x\f$-monotone, conic arc. The \link
    Arr_conic_traits_2::X_monotone_curve_2 X_monotone_curve_2\endlink
    type is derived from \link Arr_conic_traits_2::Curve_2
    Curve_2\endlink, but its constructors are used only by the traits
    class. Users should therefore construct only \link
    Arr_conic_traits_2::Curve_2 Curve_2\endlink objects and insert them
    into the arrangement using the insert() function.

    Conic arcs are constructible from full ellipses or by specifying a
    supporting curve, two endpoints, and an orientation. However, several
    constructors of \link Arr_conic_traits_2::Curve_2 Curve_2\endlink
    are available to allow for some special cases, such as circular arcs
    or line segments. The \link Arr_conic_traits_2::Curve_2
    Curve_2\endlink and the derived \link
    Arr_conic_traits_2::X_monotone_curve_2 X_monotone_curve_2\endlink
    classes also support basic access functions such as source(),
    target(), and %orientation().

    \cgalFigureBegin{aos_fig-conics,conics.png}
    An arrangement of mixed conic arcs, as constructed in conics.cpp
    \cgalFigureEnd

    The following example demonstrates the usage of the various
    constructors for conic arcs. The resulting arrangement is depicted in
    \cgalFigureRef{aos_fig-conics}. Especially noteworthy are the
    constructor of a circular arc that accepts three points, the
    constructor of a conic arc that accepts five points, and the
    constructor that allows specifying approximate endpoints, where the
    exact endpoints are given explicitly as intersections of the
    supporting conic with two other conic curves. The approximate
    endpoints are used to select the specific exact endpoints out of all
    intersection points of the pair of curves (the supporting conic curve
    and the auxiliary conic curve). Also note that as the preconditions
    required by some of these constructors are rather complicated (see the
    Reference Manual for the details), a precondition violation does not
    cause the program to terminate---instead, an invalid arc is
    created. The call a.is_valid() verifies the validity of the arc
    \f$a\f$. Naturally, inserting invalid arcs into an arrangement is not
    allowed, so the validity of an arc should be checked once it is
    constructed.

    \cgalExample{Arrangement_on_surface_2/conics.cpp}

    The types common to the example programs that use the
    Arr_conic_traits_2 class template are listed below and
    defined in the header file arr_conics.h.

    \code{.cpp}
    #include <CGAL/Cartesian.h>
    #include <CGAL/CORE_algebraic_number_traits.h>
    #include <CGAL/Arr_conic_traits_2.h>
    #include <CGAL/Arrangement_2.h>

    using Nt_traits = CGAL::CORE_algebraic_number_traits;
    using Rational = Nt_traits::Rational;
    using Rat_kernel = CGAL::Cartesian;
    using Rat_point = Rat_kernel::Point_2;
    using Rat_segment = Rat_kernel::Segment_2;
    using Rat_circle = Rat_kernel::Circle_2;
    using Algebraic = Nt_traits::Algebraic;
    using Alg_kernel = CGAL::Cartesian;
    using Traits = CGAL::Arr_conic_traits_2<Rat_kernel, Alg_kernel, Nt_traits>;
    using Point = Traits::Point_2;
    using Conic_arc = Traits::Curve_2;
    using X_monotone_conic_arc = Traits::X_monotone_curve_2;
    using Arrangement = CGAL::Arrangement_2;
    \endcode

    \cgalFigureBegin{aos_fig-conic_multiplicities,conic_multiplicities.png}
    An arrangement of a circular arc and a hyperbolic arc, as constructed
    in \ref Arrangement_on_surface_2/conic_multiplicities.cpp.
    \cgalFigureEnd

    The last example in this section demonstrates how the conic-traits
    class can handle intersection points with multiplicity. The resulting
    arrangement is depicted in
    \cgalFigureRef{aos_fig-conic_multiplicities}. The supporting curves of
    the two arcs, a circle centered at \f$(0,\frac{1}{2})\f$ with radius
    \f$\frac{1}{2}\f$, and the hyperbola \f$y =
    \frac{x^2}{1-x}\f$,\cgalFootnote{This curve can also be written as
    \f$c: x^2 + xy - y = 0\f$. It is a hyperbola since \f$\Delta_{c} =
    -1\f$.} intersect at the origin such that the intersection point has
    multiplicity \f$3\f$ (note that they both have the same horizontal
    tangent at \f$(0,0)\f$ and the same curvature \f$1\f$). In addition,
    they have another intersection point at
    \f$(\frac{1}{2},\frac{1}{2})\f$ of multiplicity \f$1\f$.

    \cgalExample{Arrangement_on_surface_2/conic_multiplicities.cpp}

    \paragraph arr_sssectr_ratfunc A Traits Class for Arcs of Rational Functions

    A rational function is given by the equation \f$y =
    \frac{P(x)}{Q(x)}\f$, where \f$P\f$ and \f$Q\f$ are polynomials of
    arbitrary degrees. In particular, if \f$Q(x) = 1\f$, then the
    function is simply a polynomial function. A bounded rational
    arc is defined by the graph of a rational function over some
    interval \f$[x_{\rm min}, x_{\rm max}]\f$, where \f$Q\f$ does not have
    any real roots in this interval (thus, the arc does not contain any
    singularities). However, we may consider functions defined over
    unbounded intervals, namely, over \f$(-\infty, x_{\max}]\f$,
    \f$[x_{\min}, \infty)\f$, or \f$(-\infty, \infty)\f$. Rational
    functions, and polynomial functions in particular, are not only
    interesting in their own right, they are also useful for approximating
    more complicated curves and for interpolation; see, e.g.,
    \cgalCite{cgal:ptvf-nrcpp-02} Chapter 3.

    Using the Arr_rational_function_traits_2 class template it is
    possible to construct and maintain arrangements induced by rational
    arcs. Every instance of the Arr_rational_function_traits_2 class
    template models the concepts AosTraits_2 and
    AosOpenBoundaryTraits_2, but it does not model the
    AosLandmarkTraits_2 concept. It also models the refined
    concept AosDirectionalXMonotoneTraits_2, which enables
    Boolean set operations; see Package \ref PkgBooleanSetOperations2.
    Note that it is not a model of AosLandmarkTraits_2 concept,
    so it is impossible to use the landmark point-location strategy with
    this traits class.

    \cgalFigureBegin{aos_fig-rat_func_singular,rational_function_singular.png}
    An arrangement of an arc of a rational functions that has
    singularities at \f$x = 1\f$ and at \f$x = 2\f$.
    \cgalFigureEnd

    A rational arc is always \f$x\f$-monotone in the mathematical sense.
    However, it is not necessarily continuous, as it may have
    singularities. An arc that has singularities must be split into
    continuous portions before being inserted into the arrangement.
    Consider, for example, the rational arc given by the equation \f$y =
    \frac{1}{(x-1)(2-x)}\f$ defined over the interval \f$[0,3]\f$, as
    depicted in \cgalFigureRef{aos_fig-rat_func_singular}. This arc has
    two singularities, at \f$x = 1\f$ and at \f$x = 2\f$. It is split into
    three continuous portions defined over the intervals \f$[0,1)\f$,
    \f$(1,2)\f$, and \f$(2,3]\f$ by the traits operation \link
    AosTraits_2::Make_x_monotone_2
    Make_x_monotone_2\endlink. Arbitrary rational functions are
    represented by the nested type \link
    Arr_rational_function_traits_2::Curve_2 Curve_2\endlink and
    continuous portions of rational functions are represented by the
    nested type \link Arr_rational_function_traits_2::X_monotone_curve_2
    X_monotone_curve_2\endlink. Constructors for both types are
    provided by the traits in form of functors.

    When the Arr_rational_function_traits_2<AlgebraicKernel_d_1> class
    template is instantiated, the template parameter must be substituted
    by a model of the AlgebraicKernel_d_1 concept. Models of this
    concept, such as the Algebraic_kernel_d_1<Coefficient> class
    template provided by the package \ref PkgAlgebraicFoundations are
    meant to support algebraic functionalities on univariate polynomials
    of arbitrary degree. See the documentation of the concept
    AlgebraicKernel_d_1 for more information. A rational function is
    then represented as the quotient of two polynomials, \f$P\f$ and
    \f$Q\f$, of type Polynomial_1 nested in every model of the concept
    AlgebraicKernel_d_1 and in particular in the algebraic-kernel type
    that substitutes the template parameter AlgebraicKernel_d_1 when the
    traits class-template is instantiated. Such a rational function is
    constructible from a single polynomial \f$P\f$ (with \f$Q(x) = 1\f$),
    or from two polynomials \f$P\f$ and \f$Q\f$. The type of the
    polynomial coefficients, namely Coefficient, and the type of the
    interval bounds, namely Bound, are also nested in the
    algebraic-kernel type. If an instance of the
    Algebraic_kernel_d_1<Coefficient> class template is used, for
    example, as the algebraic-kernel type, the type that substitutes its
    template parameter is defined as the Coefficient type. This type
    cannot be algebraic. Moreover, it is recommended that this type is not
    made rational either, since using rational (as opposed to integral)
    coefficients does not extend the range of the rational arcs and is
    typically less efficient.\cgalFootnote{The \cgalFootnoteCode{Algebraic_kernel_d_1}
    class template uses the types provided by the \ref PkgPolynomial
    package to define its nested \cgalFootnoteCode{Polynomial_1} type and conveniently
    expose it to the user.} The Bound type, however, can be algebraic. A
    point of type \link Arr_rational_function_traits_2::Point_2
    Point_2\endlink nested in the Arr_rational_function_traits_2 class
    template is represented by a rational function and its
    \f$x\f$-coordinate, which is derived from the type Algebraic_real_1
    nested in the algebraic-kernel type. An explicit representation by the
    nested type Algebraic_real_1 of the \f$y\f$-coordinate is only
    computed upon request, as it can be a rather costly operation.

    The aforementioned types, Polynomial_1, Coefficient,
    Bound, and Algebraic_real_1, are conveniently nested in
    the Arr_rational_function_traits_2 class template among
    the others and obtained from there in the type definitions used
    in the examples given in this section and listed below. These types
    are defined in the header file arr_rat_functions.h.

    \code{.cpp}
    #include <CGAL/basic.h>
    #include <CGAL/CORE_BigInt.h>
    #include <CGAL/Algebraic_kernel_d_1.h>
    #include <CGAL/Arr_rational_function_traits_2.h>
    #include <CGAL/Arrangement_2.h>

    using Number_type = CORE::BigInt;
    using AK1 = CGAL::Algebraic_kernel_d_1;
    using Traits = CGAL::Arr_rational_function_traits_2;

    using Polynomial = Traits::Polynomial_1;
    using Alg_real = Traits::Algebraic_real_1;
    using Bound = Traits::Bound;

    using Arrangement = CGAL::Arrangement_2;
    \endcode

    The constructed rational functions are cached by the traits class. The
    cache is local to each traits class object. It is therefore necessary
    to construct curves using only the constructor objects provided by
    member functions of the traits class. Moreover, a curve must only be
    used by the traits class object that was used to construct it. The
    cache is automatically cleaned up from time to time. The amortized
    clean up costs are constant. In addition, there is also a separate
    member function that cleans up the cache upon request.

    \cgalFigureBegin{aos_fig-rational_functions,rational_functions.png}
    An arrangement of four arcs of rational functions, as constructed in
    \ref Arrangement_on_surface_2/rational_functions.cpp.
    \cgalFigureEnd

    The following example demonstrates the construction of an arrangement
    induced by rational arcs depicted in
    \cgalFigureRef{aos_fig-rational_functions}. It uses constructors both
    for polynomial arcs and for rational arcs.

    \cgalExample{Arrangement_on_surface_2/rational_functions.cpp}

    \cgalFigureBegin{aos_fig-unbounded_rational_functions,unbounded_rational_functions.png}
    An arrangement of six arcs of rational functions, as constructed in
    \ref Arrangement_on_surface_2/unbounded_rational_functions.cpp.
    \cgalFigureEnd

    The following example demonstrates the construction of an arrangement
    of six rational arcs, four unbounded arcs and two bounded ones, as
    depicted in \cgalFigureRef{aos_fig-unbounded_rational_functions}. Note
    the usage of the constructors of an entire rational function and of an
    infinite "ray" of such a function. Also observe that the hyperbolas
    \f$y = \pm\frac{1}{x}\f$ and \f$y = \pm\frac{1}{2x}\f$ never
    intersect, although they have common vertical and horizontal
    asymptotes, so very "thin" unbounded faces are created between them:

    \cgalExample{Arrangement_on_surface_2/unbounded_rational_functions.cpp}

    The curve constructors have an additional advantage. They conveniently
    enable the provision of two polynomials that define a rational arc
    using rational coefficients. For example, let \f$P\f$ and \f$Q\f$
    denote two polynomials with integral coefficients that define a
    rational arc of interest, and let \f$P'\f$ and \f$Q'\f$ denote two
    polynomials with rational coefficients that define the same rational
    arc; that is, the quotients \f$P/Q\f$ and \f$P'/Q'\f$ are
    identical. You can construct the rational arc providing the
    coefficients of \f$P'\f$ and \f$Q'\f$ to the constructor. In this case
    the constructor normalizes the coefficients and generates the desired
    polynomials \f$P\f$ and \f$Q\f$. To this end, the curve constructors
    of both types, namely \link Arr_rational_function_traits_2::Curve_2
    Curve_2\endlink and \link
    Arr_rational_function_traits_2::X_monotone_curve_2
    X_monotone_curve_2\endlink, have operators that accept ranges of
    polynomial coefficients as well as polynomials. The coefficients in a
    given range must be in the order of the degrees of the corresponding
    variables starting from the constant term.

    \paragraph arr_sssectr_bez A Traits Class for Planar Bézier Curves

    A planar Bézier curve \f$B\f$ is a parametric curve
    defined by a sequence of control points \f$p_0, \ldots,
    p_n\f$ as follows:

    \f{eqnarray*}{
    B(t) = \left(X(t), Y(t)\right)
    = \ccSum{k=0}{n}{p_k \cdot \frac{n!}{k! (n-k)!} \cdot
    t^k (1-t)^{n-k}}\ .
    \f}

    where \f$t \in [0, 1]\f$. The degree of the curve is therefore \f$n\f$;
    namely, \f$X(t)\f$ and \f$Y(t)\f$ are polynomials of degree
    \f$n\f$. Bézier curves have numerous applications in computer
    graphics and solid modeling. They are used, for example, in free-form
    sketches and for defining the true-type fonts.

    Using the Arr_Bezier_curve_traits_2<RatKernel, AlgKernel, NtTraits>
    class template you can construct and maintain arrangements induced by
    Bézier curves (including self-intersecting Bézier
    curves) of arbitrary degree. The curves are given by rational control
    points, that is, a sequence of objects of the RatKernel::Point_2
    type. (In general, a sequence of \f$n+1\f$ control points define a
    Bézier curve of degree \f$n\f$.) The three types that
    substitute the template parameters RatKernel, AlgKernel, and
    NtTraits, respectively, when the traits is instantiated must fulfill
    the same requirements of the corresponding types used to instantiate
    the Arr_conic_traits_2 class template. Here, the use of the
    CORE_algebraic_number_traits class is also recommended with
    %Cartesian kernels instantiated with the Rational and Algebraic
    number types defined by this class. The examples given in this manual
    use the type definitions listed below. These types are defined in the
    header file arr_Bezier.h.

    \code{.cpp}
    #include <CGAL/Cartesian.h>
    #include <CGAL/CORE_algebraic_number_traits.h>
    #include <CGAL/Arr_Bezier_curve_traits_2.h>
    #include <CGAL/Arrangement_2.h>

    using Nt_traits = CGAL::CORE_algebraic_number_traits;
    using NT = Nt_traits::Rational;
    using Rational = Nt_traits::Rational;
    using Algebraic = Nt_traits::Algebraic;
    using Rat_kernel = CGAL::Cartesian;
    using Alg_kernel = CGAL::Cartesian;
    using Rat_point = Rat_kernel::Point_2;
    using Traits =
    CGAL::Arr_Bezier_curve_traits_2<Rat_kernel, Alg_kernel, Nt_traits>;
    using Bezier_curve = Traits::Curve_2;
    using Arrangement = CGAL::Arrangement_2;
    \endcode

    As mentioned above, we assume that the coordinates of all control
    points that define a Bézier curve are rational numbers, so both
    \f$X(t)\f$ and \f$Y(t)\f$ are polynomials with rational
    coefficients. The intersection points between curves are, however,
    algebraic numbers, and their exact computation is time-consuming. The
    traits class therefore contains a layer of geometric filtering that
    performs all computations in an approximate manner whenever
    possible. Thus, it resorts to exact computations only when the
    approximate computation fails to produce an unambiguous result. Most
    arrangement vertices are therefore associated with approximated
    points. You cannot access the coordinates of such points as algebraic
    numbers. However, access to the approximate coordinates is possible.
    See the Reference Manual for the exact interface of the \link
    Arr_Bezier_curve_traits_2::Point_2 Point_2\endlink, \link
    Arr_Bezier_curve_traits_2::Curve_2 Curve_2\endlink, and \link
    Arr_Bezier_curve_traits_2::X_monotone_curve_2
    X_monotone_curve_2\endlink types defined by the traits class.

    Every instance of the Arr_Bezier_curve_traits_2 class templates
    models the concept AosTraits_2 (but it does not model the
    AosLandmarkTraits_2 concept). It also models the refined
    concept AosDirectionalXMonotoneTraits_2, which enables
    Boolean set operations; see Package \ref PkgBooleanSetOperations2.

    \cgalFigureBegin{aos_fig-bezier_curves,bezier_curves.png}
    An arrangement of ten Bézier curves of degree \f$5\f$, as
    constructed in \ref Arrangement_on_surface_2/Bezier_curves.cpp.
    \cgalFigureEnd

    The following example reads a set of Bézier curves from an
    input file, where each file is specified by an integer stating its
    number of control points, followed by the sequence of control points
    given as integer or rational coordinates. By default, the program uses
    the Bezier.dat file, which contains ten curves of degree \f$5\f$
    each; their resulting arrangement is depicted in
    \cgalFigureRef{aos_fig-bezier_curves}.

    \cgalExample{Arrangement_on_surface_2/Bezier_curves.cpp}

    \paragraph arr_sssectr_alg A Traits Class for Planar Algebraic Curves of Arbitrary Degree

    The traits class, namely Arr_algebraic_segment_traits_2, is based on
    the Algebraic_kernel_d_1 class template, which models the
    algebraic-kernel concept AlgebraicKernel_d_1; see Section \ref
    arr_sssectr_ratfunc. The traits class handles (i) algebraic curves and
    (ii) continuous (weakly) \f$x\f$-monotone segments of algebraic
    curves, which, however, are not necessarily maximal. (A formal
    definition is given below.) Observe that non-\f$x\f$-monotone
    segments are not supported. Still, it is the traits class that
    supports the most general type of curves among the traits classes
    included in the package.

    Recall that an algebraic curve \f$c\f$ in the plane is defined as the
    (real) zero set of a bivariate polynomial \f$f(x,y)\f$. The curve is
    uniquely defined by \f$f\f$, although several polynomials might define
    the same curve. We call \f$f\f$ a defining polynomial of
    \f$c\f$.

    A formal definition of (weakly) \f$x\f$-monotone segments of algebraic
    curves follows. A point \f$p\f$ on a curve \f$c_f \subset \mathbb{R}^2\f$
    (with defining polynomial \f$f\f$) is called semi-regular if,
    locally around \f$p\f$, the curve \f$c_f\f$ can be written as a
    function graph of some continuous function in \f$x\f$ or in
    \f$y\f$. (We also say that \f$p\f$ is parameterizable in \f$x\f$ or
    \f$y\f$, respectively.) The only two cases of non-semi-regular points
    are isolated points and self-intersections. A segment of a
    curve in this context is a closed and continuous point set such that
    each interior point is semi-regular. It follows that a segment is
    either vertical or a closed connected point set, with all interior
    points parameterizable in \f$x\f$.

    Every instance of the Arr_algebraic_segment_traits_2<Coefficient>
    class template models the AosTraits_2 and
    AosOpenBoundaryTraits_2 concepts (but it does not model the
    AosLandmarkTraits_2 concept). The template argument
    Coefficient determines the type of the scalar coefficients of the
    polynomial. Currently supported integral number types are Gmpz,
    leda_integer, and CORE::BigInt. This is reflected in the
    statements included in the header file integer_type.h, the listings
    of which are omitted here. This header file is used by the two example
    programs listed in this section. The template parameter Coefficient
    can be substituted in addition by an instance of the
    Sqrt_extension<A,B> class template, where the template parameters
    NT and Root are substituted in turn by one of the integral
    number types above. Finally, the template parameter Coefficient can
    be substituted also by a rational number type, where the type of the
    numerator and denominator is one of the types above.

    The type \link Arr_algebraic_segment_traits_2::Curve_2
    Curve_2\endlink nested in the Arr_algebraic_segment_traits_2 class
    template defines an algebraic curve. An object of this type can be
    constructed by the \link
    Arr_algebraic_segment_traits_2::Construct_curve_2
    Construct_curve_2\endlink functor also nested in the class
    template. Its function operator accepts as an argument an object of
    type \link Arr_algebraic_segment_traits_2::Polynomial_2
    Polynomial_2\endlink, nested as well in the traits class-template.
    The type \link Arr_algebraic_segment_traits_2::Polynomial_2
    Polynomial_2\endlink models the concept Polynomial_d. An object of
    the nested type \link Arr_algebraic_segment_traits_2::Polynomial_2
    Polynomial_2\endlink represents a bivariate polynomial. It can be
    constructed in a few convenient ways, some are exemplified by the
    programs listed below. Consult the reference guide for the complete
    set of options.

    \cgalFigureBegin{aos_fig-algebraic_curves,algebraic_curves.png}
    An arrangement of algebraic curves of degrees \f$1\f$, \f$2\f$,
    \f$3\f$, and \f$6\f$, as constructed in
    \ref Arrangement_on_surface_2/algebraic_curves.cpp.
    \cgalFigureEnd

    The following examples computes the arrangement depicted in
    \cgalFigureRef{aos_fig-algebraic_curves}. The arrangement is induced
    by four algebraic curves, \f$c_1\f$, \f$c_2\f$, \f$c_3\f$, and
    \f$c_4\f$, of degrees \f$1\f$, \f$2\f$, \f$3\f$, and \f$6\f$,
    respectively. For each curve the defining polynomial is constructed
    first. Then, the algebraic curve is constructed using the \link
    Arr_algebraic_segment_traits_2::Construct_curve_2
    Construct_curve_2\endlink functor. Finally, the curve is inserted
    into the arrangement.

    \cgalExample{Arrangement_on_surface_2/algebraic_curves.cpp}

    The Arr_algebraic_segment_traits_2 class template carries state to
    expedite some of its computations. Thus, it is essential to have only
    one copy of the traits object during the life time of a program that
    utilizes this traits class. To this end, the example above uses the
    constructor of the Arrangement_2 data structure that accepts the traits
    object as input. Carrying state is not a unique property of the
    Arr_algebraic_segment_traits_2 class template; it is common to many
    traits classes, especially to traits classes that handle algebraic
    curves. Therefore, as a general rule, if your application requires
    direct access to a traits object, define it locally, and pass it to
    the constructor of the Arrangement_2 data structure to avoid the
    construction of a duplicate traits-class object.

    A weakly \f$x\f$-monotone segment of an algebraic curve is represented
    by the \link Arr_algebraic_segment_traits_2::X_monotone_curve_2
    X_monotone_curve_2\endlink type nested in the traits
    class-template. You can construct such segments in two ways as
    follows: (i) using the \link AosTraits_2::Make_x_monotone_2
    Make_x_monotone_2\endlink functor or (ii) using the \link
    Arr_algebraic_segment_traits_2::Construct_x_monotone_segment_2
    Construct_x_monotone_segment_2\endlink functor. Both functors are
    nested in the traits class-template. The former is required by the
    concept AosTraits_2 our traits class models; see Section
    \ref aos_sssec-geom_traits-concepts_arbitrary. The latter enables the
    construction of individual segments. The \link
    Arr_algebraic_segment_traits_2::X_monotone_curve_2
    X_monotone_curve_2\endlink type represents weakly \f$x\f$-monotone
    segments of a curve; however, for technical reasons, segments may need
    to be further subdivided into several sub-segments, called terminal
    segments. Therefore, \link
    Arr_algebraic_segment_traits_2::Construct_x_monotone_segment_2
    Construct_x_monotone_segment_2\endlink constructs a sequence of
    \link Arr_algebraic_segment_traits_2::X_monotone_curve_2
    X_monotone_curve_2\endlink objects, whose union represents the
    desired weakly \f$x\f$-monotone segment. The function operator of the
    \link Arr_algebraic_segment_traits_2::Construct_x_monotone_segment_2
    Construct_x_monotone_segment_2\endlink functor accepts as arguments
    the underlying algebraic curve, the leftmost point of the segment, the
    rightmost point of the segment, and an output iterator associated with
    a container of output terminal segments. The function operator is
    overloaded. In addition to the variant above, there is one that
    accepts the underlying algebraic curve, a single point \f$p\f$, an
    enumerator that delimits the segment, and an output iterator. It
    returns the maximal \f$x\f$-monotone segment that contains
    \f$p\f$. The enumerator specifies whether \f$p\f$ is interior to the
    returned segment, its left endpoint, or its right endpoint. The third
    variant accepts only two delimiting points and an output iterator. It
    constructs line segments.

    \cgalAdvancedBegin The subdivision terminal segments is due to the
    internal representation of \f$x\f$-monotone segments, which is based
    on a vertical decomposition. We assume the defining polynomial
    \f$f\f$ of the curve \f$c\f$ to be square-free. That is, it
    contains no divisor \f$g^2\f$ of total degree greater than zero. We
    define a (complex) critical point \f$p\in\mathbb{C}^2\f$ by
    \f[ f(p)=0=\frac{\partial f}{\partial y}(p). \f] An \f$x\f$-coordinate
    \f$\alpha\in\mathbb{R}\f$ is critical either if some critical
    point has \f$x\f$-coordinate \f$\alpha\f$, or if the leading
    coefficient of \f$f\f$, considered as a polynomial in \f$y\f$,
    vanishes. In particular, vertical lines and isolated points of \f$c\f$
    can only take place at critical \f$x\f$-coordinates. Between two
    consecutive critical \f$x\f$-coordinates the curve decomposes into a
    finite number of \f$x\f$-monotone segments (the same holds to the left
    of the leftmost, and to the right of the rightmost critical
    \f$x\f$-coordinate). The type \link
    Arr_algebraic_segment_traits_2::X_monotone_curve_2
    X_monotone_curve_2\endlink is only capable of representing such
    segments (and sub-segments of them). Formally, a terminal segment is
    either a vertical line-segment or a segment of an \f$x\f$-monotone
    curve whose \f$x\f$-range does not contain critical points in its
    interior. See \cgalFigureRef{aos_fig-algebraic_curves_decomposition}
    for an example of a quartic curve and its decomposition into terminal
    segments. Notice that six vertices split the curve into
    \f$x\f$-monotone segments, and four additional vertices further split
    the corresponding \f$x\f$-monotone segments into terminal segments.
    \cgalAdvancedEnd

    \cgalFigureBegin{aos_fig-algebraic_curves_decomposition,algebraic_curves_decomposition.png}

    The critical \f$x\f$-coordinates of an algebraic curve (dashed
    lines), and its decomposition into terminal segments (in different
    colors). The segment from \f$p\f$ to \f$q\f$ consists of the union
    of three terminal segments.
    \cgalFigureEnd

    The type Algebraic_real_1 must be defined by any model of the
    AlgebraicKernel_d_1 concept. The traits class-template
    Arr_algebraic_segment_traits_2 exploits an instance of the
    Algebraic_kernel_d_1 class template, which models the concept
    AlgebraicKernel_d_1. The exploited instance is nested in the traits
    class-template. You can use this model to create algebraic numbers as
    roots of univariate polynomials, and process them, for instance,
    compare them or approximate them to any precision. See the
    documentation of the concept AlgebraicKernel_1 for more information.
    Coordinates of points are represented by the type Algebraic_real_1
    nested in the traits class-template. This type is defined as the
    corresponding type nested in the instance of Algebraic_kernel_d_1.

    You can construct an object of type \link
    Arr_algebraic_segment_traits_2::Point_2 Point_2\endlink using the
    \link Arr_algebraic_segment_traits_2::Construct_point_2
    Construct_point_2\endlink functor nested in the traits
    class-template. Its function operator is overloaded with a couple of
    variants that accepts the \f$x\f$ and \f$y\f$ coordinates of the
    point. Their types must be either Algebraic_real_1 or
    Coefficient. Another efficient variant accepts a triple
    \f$(x_0,c,i)\f$, which identifies the \f$i\f$-th point (counted from
    below) in the fiber of \f$c\f$ at the \f$x\f$-coordinate
    \f$x_0\f$. \cgalFootnote{The fiber of a curve \f$c\f$ at some
    \f$x\f$-coordinate \f$x'\f$ is the set of all points on \f$c\f$ with
    \f$x\f$-coordinate \f$x'\f$. Formally, for a curve \f$c\f$ and \f$x'
    \in \mathbb{R}\f$, the fiber of \f$c\f$ at \f$x'\f$ is \f$c \cap
    {(x',b),|,b \in \mathbb{R}}\f$.} In the example depicted in
    \cgalFigureRef{aos_fig-algebraic_curves_decomposition}, if \f$x_1\f$
    denotes the \f$x\f$-coordinate of \f$p\f$, and \f$c\f$ represents the
    algebraic curve, then \f$p\f$ could be represented by
    \f$(x_1,c,3)\f$. If \f$x_2\f$ is the \f$x\f$-coordinate of \f$q\f$,
    then \f$(x_2,c,1)\f$ is a valid representation of \f$q\f$. Points are
    represented internally using the triple described above. Although the
    \f$y\f$-coordinate of a point represented by an object of the nested
    type Algebraic_real_1 can be obtained, we advise caution with that
    option, since computing an explicit representation of the
    \f$y\f$-coordinate can be rather expensive.

    \cgalFigureBegin{aos_fig-algebraic_segments,algebraic_segments.png}
    An arrangement of algebraic segments (solid lines), as constructed in
    \ref Arrangement_on_surface_2/algebraic_segments.cpp. The supporting
    curves are drawn as dashed lines.
    \cgalFigureEnd

    The following code exemplifies the method to construct points and the
    various methods to construct algebraic segments. The computed
    arrangement is depicted in \cgalFigureRef{aos_fig-algebraic_segments}.

    \cgalExample{Arrangement_on_surface_2/algebraic_segments.cpp}

    \subsubsection arr_ssectr_spherical Arcs of Great Circles Embedded in the Sphere

    A great circle of a sphere is the intersection of the sphere and a
    plane that passes through the center point of the sphere. For all
    pairs of distinct points on the sphere except for antipodal points,
    there is a unique great circle through the two points. There are
    infinitely many great circles through antipodal points. The minor arc
    of a great circle between two points is the shortest spherical-path
    between them. In this sense, minor arcs are analogous to line
    segments in Euclidean geometry.

    The Arr_geodesic_arc_on_sphere_traits_2<Kernel,X,Y> class template
    handles arcs of great circles (also known as geodesic arcs) of a unit
    sphere (centered at the origin in \f$\mathbb{R}^3\f$). It is a model of the
    concept AosSphericalBoundaryTraits_2; see Section \ref
    aos_ssec-traits-curved. An arrangement type (an instance of the
    template Arrangement_on_surface_2<GeomTraits, TopolTraits>) that
    uses an instance of this traits class as the geometry traits must use
    a matching topology traits. Currently, this package provides one
    template, namely, Arr_spherical_topology_traits_2<GeometryTraits_2, Dcel> an instance of which can be used as the topology traits.

    The unit sphere is defined over a parameter space \f$\Phi =
    [\tau,2\pi+\tau] \times [-\frac{\pi}{2}, \frac{\pi}{2}]\f$, where
    \f$\tau = \arctan(X, Y)\f$. By default, \f$X = -1, Y = 0\f$, which
    implies \f$\tau = -\pi\f$, which implies a default parameterization
    \f$\Phi = [-\pi, \pi] \times [-\frac{\pi}{2}, \frac{\pi}{2}]\f$. The
    equator curve, for example, is given by \f$\gamma(t) = (2t\pi + \tau,
    0)\f$, for \f$t \in [0,1]\f$. The surface is given by
    \f$\phi_S(\alpha,\beta) = (\cos \alpha \cos \beta, \sin \alpha \cos
    \beta, \sin \beta)\f$; see Section \ref aos_sec-curved_surfaces for
    more details. This parameterization induces two contraction points
    \f$(0,0,-1) = \phi_S(\alpha,-\frac{\pi}{2})\f$ and \f$(0,0,1) =
    \phi_S(\alpha,\frac{\pi}{2})\f$, for all \f$\alpha\f$, referred to as
    the south and north poles, respectively, and an identification curve
    \f${\phi_S(\alpha,\beta),|,-\frac{\pi}{2} \leq \beta \leq
    \frac{\pi}{2}}\f$, as \f$\phi_S(\pi,\beta) = \phi_S(2\pi +
    \tau,\beta)\f$ for all \f$\beta\f$. When \f$\tau = -\pi\f$ (the
    default), the identification curve coincides with the opposite Prime
    (Greenwich) Meridian. In other words, the left and right boundary
    sides of the parameter space are identified and the top and bottom
    boundary sides are contracted. The arguments that substitute the
    template parameters X and Y when
    Arr_geodesic_arc_on_sphere_traits_2<Kernel, X, Y> is instantiated
    determine the value of \f$\tau\f$. Essentially, overriding their default
    values rotates the identification curve about the vertical axes of the
    image coordinate system (that is, the sphere coordinate system). These
    arguments must be integral values. They define a not-necessarily
    normalized vector \f$(x,y)\f$ in the \f$xy\f$-plane in the image
    coordinate system, that bisects the identification curve. The explicit
    expression for the surface above is not used at all in the
    implementation of the traits. Indeed, all the required geometric
    operations listed in the traits concept are implemented using only
    rational arithmetic.

    The following example constructs an arrangement induced by 12 arcs of
    great circles embedded in the sphere. The arrangement is depicted in
    \cgalFigureRef{spherical_insert}.

    \cgalFigureBegin{spherical_insert,spherical_insert.png}
    An arrangement induced by 12 arcs of great circles, as constructed in
    \ref Arrangement_on_surface_2/spherical_insert.cpp. The number of
    vertices, edges, and faces of the arrangement is 7, 13, and 8,
    respectively. The intersection of the curve \f$(-1,0,0),(0,1,0)\f$
    with the identification curve induces a vertex at
    \f$(\frac{-11}{\sqrt{11^2+7^2}},\frac{7}{\sqrt{11^2+7^2}},0)\f$ drawn
    in green. The north and south poles are drawn as little spheres. The
    identification curve is drawn as a gray tube.
    \cgalFigureEnd

    \cgalExample{Arrangement_on_surface_2/spherical_insert.cpp}

    Use the Arr_geodesic_arc_on_sphere_traits_2::Construct_point_2,
    Arr_geodesic_arc_on_sphere_traits_2::Construct_x_monotone_curve_2,
    and Arr_geodesic_arc_on_sphere_traits_2::Construct_curve_2 functors
    to construct a point, an \f$X\f$-monotone curve and a curve objects,
    respectively. Observe that an \f$X\f$-monotone curve cannot intersect
    the identification curve in its interior. A curve can be constructed
    from either (i) two endpoints, (ii) two endpoints and a normal, or
    (iii) a normal. The two endpoints determine the plane. The normal
    determines the orientation of the plane and the final arc (whether it
    is the minor arc or the major arc). If the normal is not provided, the
    minor arc is constructed. If a curve is constructed and only the
    normal is provided a full great circle is constructed. If an
    \f$X\f$-monotone curve is constructed and only the normal is provided
    an arc that resembles a full circle is constructed; this arc has one
    endpoint that lies on the identification curve; this point is
    considered both the source and target (and also the left and right)
    point of the arc. See \cgalFigureRef{aos_fig-right_hand_rule} for an
    illustration of the right-hand rule, which depicts the relation
    between the arc and the normal.

    \cgalFigureBegin{aos_fig-right_hand_rule,right_hand_rule.png}
    To use the right hand rule, point your right thumb in the direction of
    the normal and curl your fingers in the direction of the arc starting
    with source endpoint and ending at the target endpoint.
    \cgalFigureEnd

    \subsection arr_ssec_tr_decorators Traits-Class Decorators

    Decorator is a structural pattern that allows adding new behaviors to
    objects by placing them inside special wrapper objects, called
    decorators. One type of decorators attaches auxiliary data to the
    geometric objects handled by the original traits. Another type enables
    the retrieval of debugging and informative metadata.

    \subsubsection arr_sssec_tr_data_decorators Data Decorators

    Geometric traits-class decorators allow you to attach auxiliary data
    to the geometric objects (curves and to points). The data is
    automatically manipulated by the decorators and distributed to the
    constructed geometric entities. Additional information can
    alternatively be maintained by extending the vertex, halfedge, or face
    types provided by the \dcel class used by the arrangement; see
    Section \ref arr_ssecex_dcel for details. In many cases, however, it is
    convenient to attach the data to the curve itself, exploiting the
    automatic proliferation of the additional data fields from each curve
    to all its induced subcurves. Moreover, as two halfedges are
    associated with a single curve, storing the data once in the curve
    record either saves space or avoids an indirect access from one
    halfedge to its twin.

    The \ref PkgArrangementOnSurface2 package includes a traits-class
    decorator used to attach a data field to curves and to
    \f$x\f$-monotone curves. It is a class template named
    Arr_curve_data_traits_2 parameterized by a base-traits class, which must
    be substituted by one of the geometric traits models described in
    the previous subsections or with a user-defined traits model, when the
    decorator is instantiated. The curve-data decorator derives from the
    base-traits class, and in particular inherits its \link
    Arr_curve_data_traits_2::Point_2 Point_2\endlink type. The remaining
    nested types are defined as follows:

  • \link Arr_curve_data_traits_2::Curve_2 `Curve_2`\endlink is derived from the basic `BaseTraits::Curve_2` class, extending it by an extra field of type `CurveData`.
  • \link Arr_curve_data_traits_2::X_monotone_curve_2 `X_monotone_curve_2`\endlink is derived from the basic `BaseTraits::X_monotone_curve_2` class, extending it by an extra field of type `XMonotoneCurveData`, which must model the concepts CopyConstructible, EqualityComparable, and DefaultConstructible. The latter ensures that every instance of the class template `Arr_curve_data_traits_2` obtained by substituting the `BaseTraits` template parameter with a model of the `AosLandmarkTraits_2` concept models the `AosLandmarkTraits_2` concept as well

    Note that the nested \link Arr_curve_data_traits_2::Curve_2
    Curve_2\endlink and \link
    Arr_curve_data_traits_2::X_monotone_curve_2
    X_monotone_curve_2\endlink are not the same, even if the
    BaseTraits::Curve_2 and BaseTraits::X_monotone_curve_2 are (as in
    the case of the segment-traits class, for example). The extended curve
    types support the additional methods \link
    CGAL::Arr_curve_data_traits_2::Curve_2::data() data()\endlink and \link
    CGAL::Arr_curve_data_traits_2::Curve_2::set_data() set_data()\endlink for accessing and
    modifying the data field.

    You can create an extended curve (or an extended \f$x\f$-monotone curve)
    from a basic curve and a curve-data object. When curves are
    inserted into an arrangement, they may be split, and the
    decorator handles their data fields automatically as follows:

  • When a curve is subdivided into \f$x\f$-monotone subcurves, its data field of type `CurveData` is converted to an object of type `XMonotoneCurveData` using the `Convert` functor. The object is automatically associated with each of the resulting \f$x\f$-monotone subcurves.

    Note that by default, the CurveData type is identical to the
    XMonotoneCurveData type (and the conversion functor Convert is
    trivially defined). Thus, the data field associated with the
    original curve is just duplicated and stored with the
    \f$x\f$-monotone subcurves.

  • When an \f$x\f$-monotone curve is split into two (typically, when it intersects another curve), the decorator class automatically copies its data field to both resulting subcurves.
  • When two \f$x\f$-monotone curves, \f$c_1\f$ and \f$c_2\f$, intersect, the result may include overlapping sections represent