init
This commit is contained in:
@@ -0,0 +1,10 @@
|
||||
---
|
||||
BasedOnStyle: LLVM
|
||||
---
|
||||
Language: Cpp
|
||||
DerivePointerAlignment: false
|
||||
PointerAlignment: Left
|
||||
ColumnLimit: 120
|
||||
TabWidth: 4
|
||||
IndentWidth: 2
|
||||
...
|
||||
@@ -0,0 +1,25 @@
|
||||
# debug: clangd --check=modules/iue-io/ccsv.h
|
||||
# debug: clangd --check=task1.hpp
|
||||
# debug: clangd --check=task1.test.cpp
|
||||
InlayHints:
|
||||
Enabled: No
|
||||
ParameterNames: Yes
|
||||
DeducedTypes: No
|
||||
---
|
||||
CompileFlags:
|
||||
Add:
|
||||
# - --target=x86_64-w64-windows-gnu
|
||||
# - --target=x86_64-pc-linux-gnu
|
||||
- -Wall
|
||||
- -Wno-unused-function
|
||||
- -Wno-unused-variable
|
||||
---
|
||||
If:
|
||||
PathMatch: [.*\.c, .*\.h]
|
||||
CompileFlags:
|
||||
Add: [-std=c11]
|
||||
---
|
||||
If:
|
||||
PathMatch: [.*\.cpp, .*\.hpp]
|
||||
CompileFlags:
|
||||
Add: [-std=c++20]
|
||||
@@ -0,0 +1,3 @@
|
||||
task1
|
||||
task2
|
||||
task3
|
||||
@@ -0,0 +1,3 @@
|
||||
task1.main.cpp
|
||||
task2.cpp
|
||||
task3.cpp
|
||||
@@ -0,0 +1,16 @@
|
||||
## source: https://docs.github.com/en/get-started/getting-started-with-git/configuring-git-to-handle-line-endings
|
||||
|
||||
# Set the default behavior, in case people don't have core.autocrlf set.
|
||||
* text=auto
|
||||
|
||||
# Explicitly declare text files you want to always be normalized and converted
|
||||
# to native line endings on checkout.
|
||||
*.h text
|
||||
*.hpp text
|
||||
*.c text
|
||||
*.cpp text
|
||||
*.py text
|
||||
*.ipynb text
|
||||
*.md text
|
||||
*.txt text
|
||||
*.csv text
|
||||
@@ -0,0 +1,360 @@
|
||||
# custom
|
||||
|
||||
*.csv
|
||||
*.png
|
||||
build
|
||||
doc
|
||||
.cache
|
||||
.vscode
|
||||
.idea
|
||||
|
||||
# https://github.com/github/gitignore/blob/main/CMake.gitignore
|
||||
|
||||
CMakeLists.txt.user
|
||||
CMakeCache.txt
|
||||
CMakeFiles
|
||||
CMakeScripts
|
||||
Testing
|
||||
Makefile
|
||||
cmake_install.cmake
|
||||
install_manifest.txt
|
||||
compile_commands.json
|
||||
CTestTestfile.cmake
|
||||
_deps
|
||||
|
||||
# ttps://github.com/github/gitignore/blob/main/C.gitignore
|
||||
|
||||
# Prerequisites
|
||||
*.d
|
||||
|
||||
# Object files
|
||||
*.o
|
||||
*.ko
|
||||
*.obj
|
||||
*.elf
|
||||
|
||||
# Linker output
|
||||
*.ilk
|
||||
*.map
|
||||
*.exp
|
||||
|
||||
# Precompiled Headers
|
||||
*.gch
|
||||
*.pch
|
||||
|
||||
# Libraries
|
||||
*.lib
|
||||
*.a
|
||||
*.la
|
||||
*.lo
|
||||
|
||||
# Shared objects (inc. Windows DLLs)
|
||||
*.dll
|
||||
*.so
|
||||
*.so.*
|
||||
*.dylib
|
||||
|
||||
# Executables
|
||||
*.exe
|
||||
*.out
|
||||
*.app
|
||||
*.i*86
|
||||
*.x86_64
|
||||
*.hex
|
||||
|
||||
# Debug files
|
||||
*.dSYM/
|
||||
*.su
|
||||
*.idb
|
||||
*.pdb
|
||||
|
||||
# Kernel Module Compile Results
|
||||
*.mod*
|
||||
*.cmd
|
||||
.tmp_versions/
|
||||
modules.order
|
||||
Module.symvers
|
||||
Mkfile.old
|
||||
dkms.conf
|
||||
|
||||
# https://github.com/github/gitignore/blob/main/C%2B%2B.gitignore
|
||||
|
||||
# Prerequisites
|
||||
*.d
|
||||
|
||||
# Compiled Object files
|
||||
*.slo
|
||||
*.lo
|
||||
*.o
|
||||
*.obj
|
||||
|
||||
# Precompiled Headers
|
||||
*.gch
|
||||
*.pch
|
||||
|
||||
# Compiled Dynamic libraries
|
||||
*.so
|
||||
*.dylib
|
||||
*.dll
|
||||
|
||||
# Fortran module files
|
||||
*.mod
|
||||
*.smod
|
||||
|
||||
# Compiled Static libraries
|
||||
*.lai
|
||||
*.la
|
||||
*.a
|
||||
*.lib
|
||||
|
||||
# Executables
|
||||
*.exe
|
||||
*.out
|
||||
*.app
|
||||
|
||||
# source: https://github.com/github/gitignore/blob/main/Python.gitignore
|
||||
|
||||
# Byte-compiled / optimized / DLL files
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*$py.class
|
||||
|
||||
# C extensions
|
||||
*.so
|
||||
|
||||
# Distribution / packaging
|
||||
.Python
|
||||
build/
|
||||
develop-eggs/
|
||||
dist/
|
||||
downloads/
|
||||
eggs/
|
||||
.eggs/
|
||||
lib/
|
||||
lib64/
|
||||
parts/
|
||||
sdist/
|
||||
var/
|
||||
wheels/
|
||||
share/python-wheels/
|
||||
*.egg-info/
|
||||
.installed.cfg
|
||||
*.egg
|
||||
MANIFEST
|
||||
|
||||
# PyInstaller
|
||||
# Usually these files are written by a python script from a template
|
||||
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||
*.manifest
|
||||
*.spec
|
||||
|
||||
# Installer logs
|
||||
pip-log.txt
|
||||
pip-delete-this-directory.txt
|
||||
|
||||
# Unit test / coverage reports
|
||||
htmlcov/
|
||||
.tox/
|
||||
.nox/
|
||||
.coverage
|
||||
.coverage.*
|
||||
.cache
|
||||
nosetests.xml
|
||||
coverage.xml
|
||||
*.cover
|
||||
*.py,cover
|
||||
.hypothesis/
|
||||
.pytest_cache/
|
||||
cover/
|
||||
|
||||
# Translations
|
||||
*.mo
|
||||
*.pot
|
||||
|
||||
# Django stuff:
|
||||
*.log
|
||||
local_settings.py
|
||||
db.sqlite3
|
||||
db.sqlite3-journal
|
||||
|
||||
# Flask stuff:
|
||||
instance/
|
||||
.webassets-cache
|
||||
|
||||
# Scrapy stuff:
|
||||
.scrapy
|
||||
|
||||
# Sphinx documentation
|
||||
docs/_build/
|
||||
|
||||
# PyBuilder
|
||||
.pybuilder/
|
||||
target/
|
||||
|
||||
# Jupyter Notebook
|
||||
.ipynb_checkpoints
|
||||
|
||||
# IPython
|
||||
profile_default/
|
||||
ipython_config.py
|
||||
|
||||
# pyenv
|
||||
# For a library or package, you might want to ignore these files since the code is
|
||||
# intended to run in multiple environments; otherwise, check them in:
|
||||
# .python-version
|
||||
|
||||
# pipenv
|
||||
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
||||
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
||||
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
||||
# install all needed dependencies.
|
||||
#Pipfile.lock
|
||||
|
||||
# poetry
|
||||
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
||||
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
||||
# commonly ignored for libraries.
|
||||
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
||||
#poetry.lock
|
||||
|
||||
# pdm
|
||||
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
||||
#pdm.lock
|
||||
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
|
||||
# in version control.
|
||||
# https://pdm.fming.dev/#use-with-ide
|
||||
.pdm.toml
|
||||
|
||||
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
||||
__pypackages__/
|
||||
|
||||
# Celery stuff
|
||||
celerybeat-schedule
|
||||
celerybeat.pid
|
||||
|
||||
# SageMath parsed files
|
||||
*.sage.py
|
||||
|
||||
# Environments
|
||||
.env
|
||||
.venv
|
||||
env/
|
||||
venv/
|
||||
ENV/
|
||||
env.bak/
|
||||
venv.bak/
|
||||
|
||||
# Spyder project settings
|
||||
.spyderproject
|
||||
.spyproject
|
||||
|
||||
# Rope project settings
|
||||
.ropeproject
|
||||
|
||||
# mkdocs documentation
|
||||
/site
|
||||
|
||||
# mypy
|
||||
.mypy_cache/
|
||||
.dmypy.json
|
||||
dmypy.json
|
||||
|
||||
# Pyre type checker
|
||||
.pyre/
|
||||
|
||||
# pytype static type analyzer
|
||||
.pytype/
|
||||
|
||||
# Cython debug symbols
|
||||
cython_debug/
|
||||
|
||||
# jetbrain IDEs: https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
||||
|
||||
# User-specific stuff
|
||||
.idea/**/workspace.xml
|
||||
.idea/**/tasks.xml
|
||||
.idea/**/usage.statistics.xml
|
||||
.idea/**/dictionaries
|
||||
.idea/**/shelf
|
||||
|
||||
# AWS User-specific
|
||||
.idea/**/aws.xml
|
||||
|
||||
# Generated files
|
||||
.idea/**/contentModel.xml
|
||||
|
||||
# Sensitive or high-churn files
|
||||
.idea/**/dataSources/
|
||||
.idea/**/dataSources.ids
|
||||
.idea/**/dataSources.local.xml
|
||||
.idea/**/sqlDataSources.xml
|
||||
.idea/**/dynamic.xml
|
||||
.idea/**/uiDesigner.xml
|
||||
.idea/**/dbnavigator.xml
|
||||
|
||||
# Gradle
|
||||
.idea/**/gradle.xml
|
||||
.idea/**/libraries
|
||||
|
||||
# Gradle and Maven with auto-import
|
||||
# When using Gradle or Maven with auto-import, you should exclude module files,
|
||||
# since they will be recreated, and may cause churn. Uncomment if using
|
||||
# auto-import.
|
||||
# .idea/artifacts
|
||||
# .idea/compiler.xml
|
||||
# .idea/jarRepositories.xml
|
||||
# .idea/modules.xml
|
||||
# .idea/*.iml
|
||||
# .idea/modules
|
||||
# *.iml
|
||||
# *.ipr
|
||||
|
||||
# CMake
|
||||
cmake-build-*/
|
||||
|
||||
# Mongo Explorer plugin
|
||||
.idea/**/mongoSettings.xml
|
||||
|
||||
# File-based project format
|
||||
*.iws
|
||||
|
||||
# IntelliJ
|
||||
out/
|
||||
|
||||
# mpeltonen/sbt-idea plugin
|
||||
.idea_modules/
|
||||
|
||||
# JIRA plugin
|
||||
atlassian-ide-plugin.xml
|
||||
|
||||
# Cursive Clojure plugin
|
||||
.idea/replstate.xml
|
||||
|
||||
# SonarLint plugin
|
||||
.idea/sonarlint/
|
||||
|
||||
# Crashlytics plugin (for Android Studio and IntelliJ)
|
||||
com_crashlytics_export_strings.xml
|
||||
crashlytics.properties
|
||||
crashlytics-build.properties
|
||||
fabric.properties
|
||||
|
||||
# Editor-based Rest Client
|
||||
.idea/httpRequests
|
||||
|
||||
# Android studio 3.1+ serialized cache file
|
||||
.idea/caches/build_file_checksums.ser
|
||||
|
||||
# VSCODE source: https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore
|
||||
.vscode/*
|
||||
!.vscode/settings.json
|
||||
!.vscode/tasks.json
|
||||
!.vscode/launch.json
|
||||
!.vscode/extensions.json
|
||||
!.vscode/*.code-snippets
|
||||
|
||||
# Local History for Visual Studio Code
|
||||
.history/
|
||||
|
||||
# Built Visual Studio Code Extensions
|
||||
*.vsix
|
||||
@@ -0,0 +1,4 @@
|
||||
[submodule "modules"]
|
||||
path = modules
|
||||
url = https://sgit.iue.tuwien.ac.at/360050/modules
|
||||
branch = main
|
||||
@@ -0,0 +1,50 @@
|
||||
cmake_minimum_required(VERSION 3.20)
|
||||
|
||||
# define project metadata
|
||||
|
||||
project(exercise4 LANGUAGES CXX
|
||||
DESCRIPTION "exercise4"
|
||||
HOMEPAGE_URL "https://sgit.iue.tuwien.ac.at/360050/exercise4")
|
||||
|
||||
# setting required language standards
|
||||
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED True)
|
||||
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||
|
||||
# misc settings
|
||||
|
||||
# avoid ctest dashboard targets
|
||||
set_property(GLOBAL PROPERTY CTEST_TARGETS_ADDED 1)
|
||||
# generate a compile_commands.json
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||
# make all symbols visible on windows (which is default on unix)
|
||||
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
|
||||
|
||||
# options
|
||||
|
||||
option(BUILD_TESTING "enable testing with ctest" ON)
|
||||
|
||||
# testing
|
||||
|
||||
include(CTest)
|
||||
|
||||
# get/setup dependencies
|
||||
|
||||
include_directories(modules)
|
||||
|
||||
# include own targets
|
||||
|
||||
add_executable(task1 task1.main.cpp)
|
||||
add_test(NAME task1 COMMAND task1 WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
|
||||
set_property(TEST task1 PROPERTY PASS_REGULAR_EXPRESSION "(-112|-1\\.120000e\\+02)")
|
||||
set_property(TEST task1 PROPERTY PASS_REGULAR_EXPRESSION "(-221|-2\\.110000e\\+02)")
|
||||
set_property(TEST task1 PROPERTY PASS_REGULAR_EXPRESSION "(42|4\\.200000e\\+01)")
|
||||
set_property(TEST task1 PROPERTY PASS_REGULAR_EXPRESSION "(-23|-2\\.300000e\\+01)")
|
||||
|
||||
add_executable(task2 task2.cpp task2.misc.cpp task2.test.cpp)
|
||||
add_test(NAME task2 COMMAND task2 WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
|
||||
|
||||
add_executable(task3 task2.cpp task2.misc.cpp task3.cpp task3.misc.cpp task3.test.cpp)
|
||||
add_test(NAME task3 COMMAND task3 WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
# Hausübung 4 (3 Punkte)
|
||||
|
||||
**Ausgabe**: Dienstag 16. April 2024, vormittags (Ursprünglich Donnerstag 11. April 2024).
|
||||
|
||||
**Abgabe bis**: Montag 29. April 2024, Ende des Tages. (Ursprünglich Montag 22. April)
|
||||
|
||||
**Abgabe via**: git-Repository mit dem Namen **`exercise4`** auf unserem git-Server https://sgit.iue.tuwien.ac.at
|
||||
|
||||
Details zum Abgabeprozess via `git` finden Sie hier: https://sgit.iue.tuwien.ac.at/360050/git
|
||||
|
||||
# Aufgabenstellung
|
||||
|
||||
In dieser Hausübung werden folgende Themen erstmalig einfliessen:
|
||||
|
||||
- Klassen mit ausschließlich öffentlichen Member Variablen (ohne benutzerdefinierte Konstruktoren)
|
||||
- Member Funktionen
|
||||
- Nutzung von selbst implementierter Funktionalität in einem separaten Anwendungskontext
|
||||
|
||||
**Die genaue Beschreibung und Anforderungen finden Sie in [`main.ipynb`](main.ipynb) und im Quellcode.**
|
||||
@@ -0,0 +1 @@
|
||||
-Imodules
|
||||
File diff suppressed because it is too large
Load Diff
|
After Width: | Height: | Size: 116 KiB |
@@ -0,0 +1,265 @@
|
||||
<svg preserveAspectRatio='xMidYMid meet' version='1.1' xmlns='http://www.w3.org/2000/svg' viewbox='-16.9557 -3.85356 800 34.6821 ' height='34.682081' width='800.000000'>
|
||||
<g>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='1.54143,30.8285 1.54143,19.2678 0,25.0482 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='18.1118,16.9557 16.185,14.6435 20.0385,14.6435 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='41.6185,30.8285 41.6185,19.2678 40.0771,25.0482 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='58.1888,16.9557 56.262,14.6435 60.1156,14.6435 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='81.6956,30.8285 81.6956,19.2678 80.1541,25.0482 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='98.2659,16.9557 96.3391,14.6435 100.193,14.6435 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='121.773,30.8285 121.773,19.2678 120.231,25.0482 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='138.343,16.9557 136.416,14.6435 140.27,14.6435 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='161.85,30.8285 161.85,19.2678 160.308,25.0482 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='178.42,16.9557 176.493,14.6435 180.347,14.6435 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='201.927,30.8285 201.927,19.2678 200.385,25.0482 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='218.497,16.9557 216.57,14.6435 220.424,14.6435 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='242.004,30.8285 242.004,19.2678 240.462,25.0482 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='258.574,16.9557 256.647,14.6435 260.501,14.6435 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='282.081,30.8285 282.081,19.2678 280.539,25.0482 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='298.651,16.9557 296.724,14.6435 300.578,14.6435 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='322.158,30.8285 322.158,19.2678 320.617,25.0482 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='338.728,16.9557 336.802,14.6435 340.655,14.6435 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='362.235,30.8285 362.235,19.2678 360.694,25.0482 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='378.805,16.9557 376.879,14.6435 380.732,14.6435 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='402.312,30.8285 402.312,19.2678 400.771,25.0482 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='418.882,16.9557 416.956,14.6435 420.809,14.6435 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='442.389,30.8285 442.389,19.2678 440.848,25.0482 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='458.96,16.9557 457.033,14.6435 460.886,14.6435 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='482.466,30.8285 482.466,19.2678 480.925,25.0482 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='499.037,16.9557 497.11,14.6435 500.963,14.6435 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='522.543,30.8285 522.543,19.2678 521.002,25.0482 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='539.114,16.9557 537.187,14.6435 541.04,14.6435 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='562.62,30.8285 562.62,19.2678 561.079,25.0482 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='579.191,16.9557 577.264,14.6435 581.118,14.6435 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='602.697,30.8285 602.697,19.2678 601.156,25.0482 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='619.268,16.9557 617.341,14.6435 621.195,14.6435 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='642.775,30.8285 642.775,19.2678 641.233,25.0482 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='659.345,16.9557 657.418,14.6435 661.272,14.6435 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='682.852,30.8285 682.852,19.2678 681.31,25.0482 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='699.422,16.9557 697.495,14.6435 701.349,14.6435 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='722.929,30.8285 722.929,19.2678 721.387,25.0482 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='739.499,16.9557 737.572,14.6435 741.426,14.6435 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='763.006,30.8285 763.006,19.2678 761.464,25.0482 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='779.576,16.9557 777.649,14.6435 781.503,14.6435 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='1.54143,30.8285 38.5356,30.8285 38.5356,19.2678 1.54143,19.2678 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='16.9557,19.2678 19.2678,19.2678 19.2678,15.4143 16.9557,15.4143 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='30.8285,19.2678 38.5356,19.2678 38.5356,11.5607 30.8285,11.5607 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='41.6185,30.8285 78.6127,30.8285 78.6127,19.2678 41.6185,19.2678 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='57.0328,19.2678 59.3449,19.2678 59.3449,15.4143 57.0328,15.4143 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='70.9056,19.2678 78.6127,19.2678 78.6127,11.5607 70.9056,11.5607 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='81.6956,30.8285 118.69,30.8285 118.69,19.2678 81.6956,19.2678 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='97.1098,19.2678 99.422,19.2678 99.422,15.4143 97.1098,15.4143 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='110.983,19.2678 118.69,19.2678 118.69,11.5607 110.983,11.5607 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='121.773,30.8285 158.767,30.8285 158.767,19.2678 121.773,19.2678 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='137.187,19.2678 139.499,19.2678 139.499,15.4143 137.187,15.4143 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='151.06,19.2678 158.767,19.2678 158.767,11.5607 151.06,11.5607 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='161.85,30.8285 198.844,30.8285 198.844,19.2678 161.85,19.2678 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='177.264,19.2678 179.576,19.2678 179.576,15.4143 177.264,15.4143 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='191.137,19.2678 198.844,19.2678 198.844,11.5607 191.137,11.5607 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='201.927,30.8285 238.921,30.8285 238.921,19.2678 201.927,19.2678 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='217.341,19.2678 219.653,19.2678 219.653,15.4143 217.341,15.4143 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='231.214,19.2678 238.921,19.2678 238.921,11.5607 231.214,11.5607 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='242.004,30.8285 278.998,30.8285 278.998,19.2678 242.004,19.2678 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='257.418,19.2678 259.73,19.2678 259.73,15.4143 257.418,15.4143 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='271.291,19.2678 278.998,19.2678 278.998,11.5607 271.291,11.5607 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='282.081,30.8285 319.075,30.8285 319.075,19.2678 282.081,19.2678 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='297.495,19.2678 299.807,19.2678 299.807,15.4143 297.495,15.4143 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='311.368,19.2678 319.075,19.2678 319.075,11.5607 311.368,11.5607 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='322.158,30.8285 359.152,30.8285 359.152,19.2678 322.158,19.2678 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='337.572,19.2678 339.884,19.2678 339.884,15.4143 337.572,15.4143 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='351.445,19.2678 359.152,19.2678 359.152,11.5607 351.445,11.5607 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='362.235,30.8285 399.229,30.8285 399.229,19.2678 362.235,19.2678 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='377.649,19.2678 379.961,19.2678 379.961,15.4143 377.649,15.4143 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='391.522,19.2678 399.229,19.2678 399.229,11.5607 391.522,11.5607 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='402.312,30.8285 439.306,30.8285 439.306,19.2678 402.312,19.2678 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='417.726,19.2678 420.039,19.2678 420.039,15.4143 417.726,15.4143 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='431.599,19.2678 439.306,19.2678 439.306,11.5607 431.599,11.5607 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='442.389,30.8285 479.383,30.8285 479.383,19.2678 442.389,19.2678 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='457.803,19.2678 460.116,19.2678 460.116,15.4143 457.803,15.4143 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='471.676,19.2678 479.383,19.2678 479.383,11.5607 471.676,11.5607 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='482.466,30.8285 519.461,30.8285 519.461,19.2678 482.466,19.2678 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='497.881,19.2678 500.193,19.2678 500.193,15.4143 497.881,15.4143 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='511.753,19.2678 519.461,19.2678 519.461,11.5607 511.753,11.5607 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='522.543,30.8285 559.538,30.8285 559.538,19.2678 522.543,19.2678 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='537.958,19.2678 540.27,19.2678 540.27,15.4143 537.958,15.4143 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='551.83,19.2678 559.538,19.2678 559.538,11.5607 551.83,11.5607 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='562.62,30.8285 599.615,30.8285 599.615,19.2678 562.62,19.2678 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='578.035,19.2678 580.347,19.2678 580.347,15.4143 578.035,15.4143 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='591.908,19.2678 599.615,19.2678 599.615,11.5607 591.908,11.5607 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='602.697,30.8285 639.692,30.8285 639.692,19.2678 602.697,19.2678 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='618.112,19.2678 620.424,19.2678 620.424,15.4143 618.112,15.4143 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='631.985,19.2678 639.692,19.2678 639.692,11.5607 631.985,11.5607 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='642.775,30.8285 679.769,30.8285 679.769,19.2678 642.775,19.2678 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='658.189,19.2678 660.501,19.2678 660.501,15.4143 658.189,15.4143 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='672.062,19.2678 679.769,19.2678 679.769,11.5607 672.062,11.5607 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='682.852,30.8285 719.846,30.8285 719.846,19.2678 682.852,19.2678 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='698.266,19.2678 700.578,19.2678 700.578,15.4143 698.266,15.4143 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='712.139,19.2678 719.846,19.2678 719.846,11.5607 712.139,11.5607 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='722.929,30.8285 759.923,30.8285 759.923,19.2678 722.929,19.2678 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='738.343,19.2678 740.655,19.2678 740.655,15.4143 738.343,15.4143 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='752.216,19.2678 759.923,19.2678 759.923,11.5607 752.216,11.5607 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='763.006,30.8285 800,30.8285 800,19.2678 763.006,19.2678 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='778.42,19.2678 780.732,19.2678 780.732,15.4143 778.42,15.4143 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='792.293,19.2678 800,19.2678 800,11.5607 792.293,11.5607 '/>
|
||||
<circle fill='none' stroke='black' r='1.926782' cy='32.755299' stroke-width='1' cx='5.780347'/>
|
||||
<circle fill='none' stroke='black' r='1.926782' cy='32.755299' stroke-width='1' cx='10.404624'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='16.955684'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='25.433526'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='33.911368'/>
|
||||
<circle fill='none' stroke='black' r='0.770713' cy='13.102119' stroke-width='1' cx='16.955684'/>
|
||||
<circle fill='none' stroke='black' r='1.541426' cy='10.019268' stroke-width='1' cx='19.267823'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='3.853565' stroke-width='1' cx='21.579961'/>
|
||||
<circle fill='none' stroke='black' r='1.926782' cy='32.755299' stroke-width='1' cx='45.857418'/>
|
||||
<circle fill='none' stroke='black' r='1.926782' cy='32.755299' stroke-width='1' cx='50.481696'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='57.032755'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='65.510597'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='73.988439'/>
|
||||
<circle fill='none' stroke='black' r='0.770713' cy='13.102119' stroke-width='1' cx='57.032755'/>
|
||||
<circle fill='none' stroke='black' r='1.541426' cy='10.019268' stroke-width='1' cx='59.344894'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='3.853565' stroke-width='1' cx='61.657033'/>
|
||||
<circle fill='none' stroke='black' r='1.926782' cy='32.755299' stroke-width='1' cx='85.934489'/>
|
||||
<circle fill='none' stroke='black' r='1.926782' cy='32.755299' stroke-width='1' cx='90.558767'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='97.109827'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='105.587669'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='114.065511'/>
|
||||
<circle fill='none' stroke='black' r='0.770713' cy='13.102119' stroke-width='1' cx='97.109827'/>
|
||||
<circle fill='none' stroke='black' r='1.541426' cy='10.019268' stroke-width='1' cx='99.421965'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='3.853565' stroke-width='1' cx='101.734104'/>
|
||||
<circle fill='none' stroke='black' r='1.926782' cy='32.755299' stroke-width='1' cx='126.011561'/>
|
||||
<circle fill='none' stroke='black' r='1.926782' cy='32.755299' stroke-width='1' cx='130.635838'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='137.186898'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='145.664740'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='154.142582'/>
|
||||
<circle fill='none' stroke='black' r='0.770713' cy='13.102119' stroke-width='1' cx='137.186898'/>
|
||||
<circle fill='none' stroke='black' r='1.541426' cy='10.019268' stroke-width='1' cx='139.499037'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='3.853565' stroke-width='1' cx='141.811175'/>
|
||||
<circle fill='none' stroke='black' r='1.926782' cy='32.755299' stroke-width='1' cx='166.088632'/>
|
||||
<circle fill='none' stroke='black' r='1.926782' cy='32.755299' stroke-width='1' cx='170.712909'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='177.263969'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='185.741811'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='194.219653'/>
|
||||
<circle fill='none' stroke='black' r='0.770713' cy='13.102119' stroke-width='1' cx='177.263969'/>
|
||||
<circle fill='none' stroke='black' r='1.541426' cy='10.019268' stroke-width='1' cx='179.576108'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='3.853565' stroke-width='1' cx='181.888247'/>
|
||||
<circle fill='none' stroke='black' r='1.926782' cy='32.755299' stroke-width='1' cx='206.165703'/>
|
||||
<circle fill='none' stroke='black' r='1.926782' cy='32.755299' stroke-width='1' cx='210.789981'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='217.341040'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='225.818882'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='234.296724'/>
|
||||
<circle fill='none' stroke='black' r='0.770713' cy='13.102119' stroke-width='1' cx='217.341040'/>
|
||||
<circle fill='none' stroke='black' r='1.541426' cy='10.019268' stroke-width='1' cx='219.653179'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='3.853565' stroke-width='1' cx='221.965318'/>
|
||||
<circle fill='none' stroke='black' r='1.926782' cy='32.755299' stroke-width='1' cx='246.242775'/>
|
||||
<circle fill='none' stroke='black' r='1.926782' cy='32.755299' stroke-width='1' cx='250.867052'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='257.418112'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='265.895954'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='274.373796'/>
|
||||
<circle fill='none' stroke='black' r='0.770713' cy='13.102119' stroke-width='1' cx='257.418112'/>
|
||||
<circle fill='none' stroke='black' r='1.541426' cy='10.019268' stroke-width='1' cx='259.730250'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='3.853565' stroke-width='1' cx='262.042389'/>
|
||||
<circle fill='none' stroke='black' r='1.926782' cy='32.755299' stroke-width='1' cx='286.319846'/>
|
||||
<circle fill='none' stroke='black' r='1.926782' cy='32.755299' stroke-width='1' cx='290.944123'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='297.495183'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='305.973025'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='314.450867'/>
|
||||
<circle fill='none' stroke='black' r='0.770713' cy='13.102119' stroke-width='1' cx='297.495183'/>
|
||||
<circle fill='none' stroke='black' r='1.541426' cy='10.019268' stroke-width='1' cx='299.807322'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='3.853565' stroke-width='1' cx='302.119461'/>
|
||||
<circle fill='none' stroke='black' r='1.926782' cy='32.755299' stroke-width='1' cx='326.396917'/>
|
||||
<circle fill='none' stroke='black' r='1.926782' cy='32.755299' stroke-width='1' cx='331.021195'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='337.572254'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='346.050096'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='354.527938'/>
|
||||
<circle fill='none' stroke='black' r='0.770713' cy='13.102119' stroke-width='1' cx='337.572254'/>
|
||||
<circle fill='none' stroke='black' r='1.541426' cy='10.019268' stroke-width='1' cx='339.884393'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='3.853565' stroke-width='1' cx='342.196532'/>
|
||||
<circle fill='none' stroke='black' r='1.926782' cy='32.755299' stroke-width='1' cx='366.473988'/>
|
||||
<circle fill='none' stroke='black' r='1.926782' cy='32.755299' stroke-width='1' cx='371.098266'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='377.649326'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='386.127168'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='394.605010'/>
|
||||
<circle fill='none' stroke='black' r='0.770713' cy='13.102119' stroke-width='1' cx='377.649326'/>
|
||||
<circle fill='none' stroke='black' r='1.541426' cy='10.019268' stroke-width='1' cx='379.961464'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='3.853565' stroke-width='1' cx='382.273603'/>
|
||||
<circle fill='none' stroke='black' r='1.926782' cy='32.755299' stroke-width='1' cx='406.551060'/>
|
||||
<circle fill='none' stroke='black' r='1.926782' cy='32.755299' stroke-width='1' cx='411.175337'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='417.726397'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='426.204239'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='434.682081'/>
|
||||
<circle fill='none' stroke='black' r='0.770713' cy='13.102119' stroke-width='1' cx='417.726397'/>
|
||||
<circle fill='none' stroke='black' r='1.541426' cy='10.019268' stroke-width='1' cx='420.038536'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='3.853565' stroke-width='1' cx='422.350674'/>
|
||||
<circle fill='none' stroke='black' r='1.926782' cy='32.755299' stroke-width='1' cx='446.628131'/>
|
||||
<circle fill='none' stroke='black' r='1.926782' cy='32.755299' stroke-width='1' cx='451.252408'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='457.803468'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='466.281310'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='474.759152'/>
|
||||
<circle fill='none' stroke='black' r='0.770713' cy='13.102119' stroke-width='1' cx='457.803468'/>
|
||||
<circle fill='none' stroke='black' r='1.541426' cy='10.019268' stroke-width='1' cx='460.115607'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='3.853565' stroke-width='1' cx='462.427746'/>
|
||||
<circle fill='none' stroke='black' r='1.926782' cy='32.755299' stroke-width='1' cx='486.705202'/>
|
||||
<circle fill='none' stroke='black' r='1.926782' cy='32.755299' stroke-width='1' cx='491.329480'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='497.880539'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='506.358382'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='514.836224'/>
|
||||
<circle fill='none' stroke='black' r='0.770713' cy='13.102119' stroke-width='1' cx='497.880539'/>
|
||||
<circle fill='none' stroke='black' r='1.541426' cy='10.019268' stroke-width='1' cx='500.192678'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='3.853565' stroke-width='1' cx='502.504817'/>
|
||||
<circle fill='none' stroke='black' r='1.926782' cy='32.755299' stroke-width='1' cx='526.782274'/>
|
||||
<circle fill='none' stroke='black' r='1.926782' cy='32.755299' stroke-width='1' cx='531.406551'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='537.957611'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='546.435453'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='554.913295'/>
|
||||
<circle fill='none' stroke='black' r='0.770713' cy='13.102119' stroke-width='1' cx='537.957611'/>
|
||||
<circle fill='none' stroke='black' r='1.541426' cy='10.019268' stroke-width='1' cx='540.269750'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='3.853565' stroke-width='1' cx='542.581888'/>
|
||||
<circle fill='none' stroke='black' r='1.926782' cy='32.755299' stroke-width='1' cx='566.859345'/>
|
||||
<circle fill='none' stroke='black' r='1.926782' cy='32.755299' stroke-width='1' cx='571.483622'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='578.034682'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='586.512524'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='594.990366'/>
|
||||
<circle fill='none' stroke='black' r='0.770713' cy='13.102119' stroke-width='1' cx='578.034682'/>
|
||||
<circle fill='none' stroke='black' r='1.541426' cy='10.019268' stroke-width='1' cx='580.346821'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='3.853565' stroke-width='1' cx='582.658960'/>
|
||||
<circle fill='none' stroke='black' r='1.926782' cy='32.755299' stroke-width='1' cx='606.936416'/>
|
||||
<circle fill='none' stroke='black' r='1.926782' cy='32.755299' stroke-width='1' cx='611.560694'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='618.111753'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='626.589595'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='635.067437'/>
|
||||
<circle fill='none' stroke='black' r='0.770713' cy='13.102119' stroke-width='1' cx='618.111753'/>
|
||||
<circle fill='none' stroke='black' r='1.541426' cy='10.019268' stroke-width='1' cx='620.423892'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='3.853565' stroke-width='1' cx='622.736031'/>
|
||||
<circle fill='none' stroke='black' r='1.926782' cy='32.755299' stroke-width='1' cx='647.013487'/>
|
||||
<circle fill='none' stroke='black' r='1.926782' cy='32.755299' stroke-width='1' cx='651.637765'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='658.188825'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='666.666667'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='675.144509'/>
|
||||
<circle fill='none' stroke='black' r='0.770713' cy='13.102119' stroke-width='1' cx='658.188825'/>
|
||||
<circle fill='none' stroke='black' r='1.541426' cy='10.019268' stroke-width='1' cx='660.500963'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='3.853565' stroke-width='1' cx='662.813102'/>
|
||||
<circle fill='none' stroke='black' r='1.926782' cy='32.755299' stroke-width='1' cx='687.090559'/>
|
||||
<circle fill='none' stroke='black' r='1.926782' cy='32.755299' stroke-width='1' cx='691.714836'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='698.265896'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='706.743738'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='715.221580'/>
|
||||
<circle fill='none' stroke='black' r='0.770713' cy='13.102119' stroke-width='1' cx='698.265896'/>
|
||||
<circle fill='none' stroke='black' r='1.541426' cy='10.019268' stroke-width='1' cx='700.578035'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='3.853565' stroke-width='1' cx='702.890173'/>
|
||||
<circle fill='none' stroke='black' r='1.926782' cy='32.755299' stroke-width='1' cx='727.167630'/>
|
||||
<circle fill='none' stroke='black' r='1.926782' cy='32.755299' stroke-width='1' cx='731.791908'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='738.342967'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='746.820809'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='755.298651'/>
|
||||
<circle fill='none' stroke='black' r='0.770713' cy='13.102119' stroke-width='1' cx='738.342967'/>
|
||||
<circle fill='none' stroke='black' r='1.541426' cy='10.019268' stroke-width='1' cx='740.655106'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='3.853565' stroke-width='1' cx='742.967245'/>
|
||||
<circle fill='none' stroke='black' r='1.926782' cy='32.755299' stroke-width='1' cx='767.244701'/>
|
||||
<circle fill='none' stroke='black' r='1.926782' cy='32.755299' stroke-width='1' cx='771.868979'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='778.420039'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='786.897881'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='795.375723'/>
|
||||
<circle fill='none' stroke='black' r='0.770713' cy='13.102119' stroke-width='1' cx='778.420039'/>
|
||||
<circle fill='none' stroke='black' r='1.541426' cy='10.019268' stroke-width='1' cx='780.732177'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='3.853565' stroke-width='1' cx='783.044316'/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='0,34.6821 800,34.6821 800,0 0,0 '/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 28 KiB |
@@ -0,0 +1,256 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Aufgabe 1: Ein eigenes kleines C++-Programm (*coordinate rotation*) (1 Punkt)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Erstellen Sie in [`task1.main.cpp`](task1.main.cpp) ein lauffähiges Ein-Dateien-Programm das folgende Struktur aufweist:\n",
|
||||
"\n",
|
||||
"- Einbinden benötigter Header-Dateien aus der Standardbibliothek, z.B.:\n",
|
||||
"\t```cpp\n",
|
||||
"\t#include <array> // std::array\n",
|
||||
"\t#include <cmath> // std::sin, std::cos\n",
|
||||
"\t#include <iostream> // std::cout, std::endl\n",
|
||||
"\t#include <numbers> // std::numbers::pi\n",
|
||||
"\t...\n",
|
||||
"\t```\n",
|
||||
"- Definition/Implementierung einer eigenen Funktion in einem eignene Namensraum, z.B.:\n",
|
||||
"\t```cpp\n",
|
||||
"\tnamespace task1 {\n",
|
||||
"\n",
|
||||
"\tusing Coord = std::array<double, 2>;\n",
|
||||
"\n",
|
||||
"\tCoord rotate_counter_clockwise(Coord coord, double angle) {\n",
|
||||
"\t\t...\n",
|
||||
"\t}\n",
|
||||
"\t``` \n",
|
||||
"- Definition/Implementierung einer `main`-Funktion, die Ihre selbst geschriebene Funktion verwendet und die berechneten Ergebnisse in der Konsole ausgibt, z.B.:\n",
|
||||
"\t```cpp\n",
|
||||
"\tint main(){\n",
|
||||
"\t ...\n",
|
||||
"\t auto [xrot, yrot] = rotate_counter_clockwise(...)\t\n",
|
||||
"\t std::cout << xrot << \" \" << yrot << std::endl;\n",
|
||||
"\t return 0;\n",
|
||||
"\t}\n",
|
||||
"\t``` \n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"- Eine genaue Beschreibung und Anforderungen finden Sie in [`task1.main.cpp`](task1.main.cpp)\n",
|
||||
"- Ihre Implementierung erfolgt ebenfalls in [`task1.main.cpp`](task1.main.cpp)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Aufgabe 2: Member Funktionen und Klassen-Invarianten (1 Punkt)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Gegeben ist die Definition dreier Klassen `BBox`, `Cirlce` und `Triangle`. Die Klassen sind sog. `aggregate`-Klassen und weisen u.A. folgende Eigenschaften auf:\n",
|
||||
"\n",
|
||||
"- Ausschließlich öffentliche Member-Variablen\n",
|
||||
"- Keine benutzerdefinierten Konstruktoren\n",
|
||||
"- Parameterlose Konstruktion möglich, z.B. `Aggregate aggregate = {};`\n",
|
||||
"- Listen-Initialisierung ist möglich, z.B. `Aggregate aggregate = { value1, valu2 };`\n",
|
||||
"- Struktuierte Zuweisung ist möglich, z.B. `const auto& [m1, m2] = aggregate;`\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Implementieren Sie die folgenden Member-Funktionen:\n",
|
||||
"\n",
|
||||
"```cpp\n",
|
||||
"namespace task2 {\n",
|
||||
"\n",
|
||||
"using Vec2d = std::array<double, 2>;\n",
|
||||
"\n",
|
||||
"/// @brief Axis-aligned bounding box\n",
|
||||
"struct BBox {\n",
|
||||
" Vec2d min; ///< coord of bottom left corner\n",
|
||||
" Vec2d max; ///< coord of top right corner\n",
|
||||
" BBox scale(const Vec2d& org, double s) const; // todo\n",
|
||||
" BBox translate(const Vec2d& offset) const; // todo\n",
|
||||
" bool check_invariants() const; // todo\n",
|
||||
"};\n",
|
||||
"\n",
|
||||
"/// @brief Circle\n",
|
||||
"struct Circle {\n",
|
||||
" Vec2d c; ///< coordinate of the center of the circle\n",
|
||||
" double r; ///< radius of the circle\n",
|
||||
" BBox bbox() const; // todo\n",
|
||||
" Circle scale(const Vec2d& org, double s) const; // todo\n",
|
||||
" Circle rotate(const Vec2d& org, double angle) const; // todo\n",
|
||||
" Circle translate(const Vec2d& offset) const; // todo\n",
|
||||
" bool check_invariants() const; // todo\n",
|
||||
"};\n",
|
||||
"\n",
|
||||
"/// @brief Triangle\n",
|
||||
"struct Triangle {\n",
|
||||
" std::array<Vec2d, 3> abc; ///< three corner points of the triangle\n",
|
||||
" BBox bbox() const; // todo\n",
|
||||
" Triangle scale(const Vec2d& org, double s) const; // todo\n",
|
||||
" Triangle rotate(const Vec2d& org, double angle) const;// todo\n",
|
||||
" Triangle translate(const Vec2d& offset) const; // todo\n",
|
||||
" bool check_invariants() const; // todo\n",
|
||||
"};\n",
|
||||
"```"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"- Die vorgegebenen Deklarationen und eine genaue Beschreibung und Anforderungen finden Sie in [`task2.hpp`](task2.hpp)\n",
|
||||
"- Ihre Implementierung erfolgt in [`task2.cpp`](task2.cpp)\n",
|
||||
"- Die zugeordneten Tests finden Sie in [`task2.test.cpp`](task2.test.cpp)\n",
|
||||
"- In [`task2.misc.hpp`](task2.misc.hpp)/[`task2.misc.cpp`](task2.misc.cpp) sind Hilfsfunktionen zum Ausgeben und Vergleichen der drei Klassen gegeben (diese werden bei den Tests verwendet, stehen Ihnen aber auch für Ihre Implementierung zur Verfügung).\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Aufgabe 3: Nutzung von bereitgestellter Funktionalität sowie der Implementierung aus Aufgabe 2 zum Erstellen einer eigenen `.svg`-Grafik (1 Punkt)\n",
|
||||
"\n",
|
||||
"Sie sollten die Funktionalität, die Sie in Aufgabe 2 implementiert haben (Skalieren/Verschieben/Rotieren) nun selbst nutzen um eine `.svg`-Grafik zu erstellen.\n",
|
||||
"\n",
|
||||
"Nutzen Sie die bereitgestellte Funktion `task3::render_wrapper` um die `.svg`-Grafik zu generieren: Sie können die Typen aus Aufgabe 2 (`BBox/Circle/Triangle`) direkt übergeben:\n",
|
||||
"\n",
|
||||
"```cpp\n",
|
||||
"// std::vector<task2::BBox> boxes = [ ... ]\n",
|
||||
"// std::vector<task2::Circle> circles = [ ... ]\n",
|
||||
"// std::vector<task2::Triangle> triangles = [ ... ]\n",
|
||||
"task3::render_wrapper(\"myimage.svg\", boxes, triangles, triangles);\n",
|
||||
"```\n",
|
||||
"\n",
|
||||
"Es gibt keine Vorgaben, lediglich, dass die erstellte Grafik mindestens 20 Elemente (Boxen/Kreise/Dreiecke) enthalten muss. \n",
|
||||
"\n",
|
||||
"Hier ein Beispiel wie so etwas aussehen kann \n",
|
||||
"\n",
|
||||
"- horizontal verschobene und skalierte \"Häuser\" mit \"Himmel\" aus zufällig angeordneten Kreisen:\n",
|
||||
"\n",
|
||||
"\t\n",
|
||||
"\n",
|
||||
"- horizontal verschobene \"Lokomotiven\"\n",
|
||||
"\n",
|
||||
"\t"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Implementieren Sie folgende Funktion:\n",
|
||||
"\n",
|
||||
"```cpp\n",
|
||||
"\n",
|
||||
"namespace task3 {\n",
|
||||
"\n",
|
||||
"int render_something(std::filesystem::path filepath); // todo\n",
|
||||
"\n",
|
||||
"}\n",
|
||||
"```"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"- Die vorgegebenen Deklaration und eine genaue Beschreibung und Anforderungen finden Sie in [`task3.hpp`](task3.hpp)\n",
|
||||
"- Ihre Implementierung erfolgt in [`task3.cpp`](task3.cpp)\n",
|
||||
"- Die zugeordneten Tests finden Sie in [`task3.test.cpp`](task3.test.cpp)\n",
|
||||
"- In [`task3.misc.hpp`](task3.misc.hpp)/[`task3.misc.cpp`](task3.misc.cpp) finden Sie die oben erwähnte Hilfsfunktion `task3::render_wrapper`.\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Kompilieren/Testen\n",
|
||||
"\n",
|
||||
"So testen Sie Ihre Implementierung (direkter Aufruf von `g++` und `python`):\n",
|
||||
"\n",
|
||||
"```shell\n",
|
||||
"# prepare\n",
|
||||
"mkdir build\n",
|
||||
"# compile\n",
|
||||
"g++ -g -std=c++20 task1.main.cpp -o build/task1\n",
|
||||
"g++ -g -Imodules -std=c++20 task2.cpp task2.misc.cpp task2.test.cpp -o build/task2\n",
|
||||
"g++ -g -Imodules -std=c++20 task2.cpp task2.misc.cpp task3.cpp task3.misc.cpp task3.test.cpp -o build/task3\n",
|
||||
"\n",
|
||||
"# run tests\n",
|
||||
"./build/task1\n",
|
||||
"./build/task2\n",
|
||||
"./build/task3\n",
|
||||
"```\n",
|
||||
"\n",
|
||||
"Alternativ (mittels CMake-Configuration):s\n",
|
||||
"\n",
|
||||
"```shell\n",
|
||||
"# prepare\n",
|
||||
"cmake -S . -B build -D CMAKE_BUILD_TYPE=Debug\n",
|
||||
"# compile\n",
|
||||
"cmake --build build --config Debug --target task1\n",
|
||||
"cmake --build build --config Debug --target task2\n",
|
||||
"cmake --build build --config Debug --target task3\n",
|
||||
"cmake --build build --config Debug # all\n",
|
||||
"# run tests\n",
|
||||
"ctest --test-dir build -C Debug -R task1 \n",
|
||||
"ctest --test-dir build -C Debug -R task2 \n",
|
||||
"ctest --test-dir build -C Debug -R task3 \n",
|
||||
"ctest --test-dir build -C Debug # all\n",
|
||||
"``` \n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": ".venv",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.6.15"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 2
|
||||
}
|
||||
Submodule
+1
Submodule exercise4/modules added at df348de23a
@@ -0,0 +1,43 @@
|
||||
/// @file
|
||||
/// @brief Task1: "single-file" excutable C++ program
|
||||
|
||||
/// @todo Include standard library headers as needed
|
||||
#include <array> // std::array
|
||||
#include <cmath>
|
||||
#include <iostream>
|
||||
|
||||
namespace task1 {
|
||||
|
||||
using Coord = std::array<double, 2>;
|
||||
|
||||
/// @todo Implement a function 'rotate_counter_clockwise' according to the description below:
|
||||
/// - the function receives a two-dimensional coordinate in form of a 'std::array<double, 2>'
|
||||
/// - the function receives a rotation angle (in radians) in form of a 'double'
|
||||
/// - the function rotates the coordinate counter clockwise around the origin
|
||||
/// - the function returns the rotated coordinate as a std::array<double, 2>
|
||||
|
||||
std::array<double, 2> rotate_counter_clockwise(const Coord& coord, double angle) {
|
||||
std::array<double, 2> rotated_coord = {0, 0};
|
||||
rotated_coord[0] = coord[0] * cos(angle) - coord[1] * sin(angle);
|
||||
rotated_coord[1] = coord[0] * sin(angle) + coord[1] * cos(angle);
|
||||
return rotated_coord;
|
||||
}
|
||||
|
||||
} // namespace task1
|
||||
|
||||
/// @todo Implement a main function conducting the following tasks in this order:
|
||||
/// - Create two coordinates (local variables):
|
||||
/// - std::array<double, 2> coord1 = {112,211};
|
||||
/// - std::array<double, 2> coord2 = {-42,23};
|
||||
/// - Use your 'rotate_counter_clockwise' function to rotate both coordinate by 180 degrees
|
||||
/// - Print the resulting rotated coordinates to the console
|
||||
/// - Hint: the expected coordinates after rotating 180 degrees are
|
||||
/// - std::array<double, 2> coord1_rotated = {-112,-211};
|
||||
/// - std::array<double, 2> coord2_rotated = {42,-23};
|
||||
int main() {
|
||||
std::array<double, 2> coord1 = {112, 211};
|
||||
std::cout << "Original coord1: " << coord1[0] << ", " << coord1[1] << std::endl;
|
||||
std::array<double, 2> coord1_rotated = task1::rotate_counter_clockwise(coord1, std::numbers::pi_v<double>);
|
||||
std::cout << "Rotated coord1: " << coord1_rotated[0] << ", " << coord1_rotated[1] << std::endl;
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,171 @@
|
||||
/// @file
|
||||
/// @brief Task2: member function definitions/implementations
|
||||
|
||||
#include "task2.hpp" // task2::Vec2, task2::BBox, task2::Circle, task2::Triangle
|
||||
#include "task2.misc.hpp" // task2::operator<<, task2::isnan, task2::isclose
|
||||
|
||||
#include "modules/iue-num/numerics.hpp" // iue::num::isclose
|
||||
|
||||
/// @todo Include standard library headers as needed
|
||||
|
||||
|
||||
namespace task2 {
|
||||
|
||||
/// ==================================== Bounding Box =================================================
|
||||
/// @todo Implement the missing member functions for bounding box as declared and specified in task2.hpp
|
||||
|
||||
/// @todo implement member function 'BBox::scale'
|
||||
BBox BBox::scale(const Vec2d& org, double s) const {
|
||||
BBox scaled_box = *this;
|
||||
scaled_box.min[0] = org[0] + s * (min[0] - org[0]);
|
||||
scaled_box.min[1] = org[1] + s * (min[1] - org[1]);
|
||||
scaled_box.max[0] = org[0] + s * (max[0] - org[0]);
|
||||
scaled_box.max[1] = org[1] + s * (max[1] - org[1]);
|
||||
return scaled_box;
|
||||
}
|
||||
|
||||
/// @todo implement member function 'BBox::translate'
|
||||
BBox BBox::translate(const Vec2d& offset) const {
|
||||
BBox translated_box = *this;
|
||||
translated_box.min[0] += offset[0];
|
||||
translated_box.min[1] += offset[1];
|
||||
translated_box.max[0] += offset[0];
|
||||
translated_box.max[1] += offset[1];
|
||||
return translated_box;
|
||||
}
|
||||
|
||||
/// @todo implement member function 'BBox::check_invariants'
|
||||
bool BBox::check_invariants() const {
|
||||
if (std::isnan(min[0]) || std::isnan(min[1]) || std::isnan(max[0]) || std::isnan(max[1])) {
|
||||
return false;
|
||||
}
|
||||
if (min[0] > max[0] || min[1] > max[1]) {
|
||||
return false;
|
||||
}
|
||||
if (iue::num::isclose(min[0], max[0]) && iue::num::isclose(min[1], max[1])) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/// ==================================== Circle ================================================
|
||||
/// @todo Implement the missing member functions for Circle as declared and specified in task2.hpp
|
||||
|
||||
/// @todo implement member function 'Circle::bbox'
|
||||
BBox Circle::bbox() const {
|
||||
BBox box = {{c[0] - r, c[1] - r}, {c[0] + r, c[1] + r}};
|
||||
return box;
|
||||
}
|
||||
|
||||
/// @todo implement member function 'Circle::scale'
|
||||
Circle Circle::scale(const Vec2d& org, double s) const {
|
||||
Circle scaled_circle = *this;
|
||||
scaled_circle.c[0] = org[0] + s * (c[0] - org[0]);
|
||||
scaled_circle.c[1] = org[1] + s * (c[1] - org[1]);
|
||||
scaled_circle.r *= s;
|
||||
return scaled_circle;
|
||||
}
|
||||
|
||||
/// @todo implement member function 'Circle::rotate'
|
||||
Circle Circle::rotate(const Vec2d& org, double angle) const {
|
||||
Circle rotated_circle = *this;
|
||||
double x = c[0] - org[0];
|
||||
double y = c[1] - org[1];
|
||||
rotated_circle.c[0] = org[0] + x * cos(angle) - y * sin(angle);
|
||||
rotated_circle.c[1] = org[1] + x * sin(angle) + y * cos(angle);
|
||||
return rotated_circle;
|
||||
}
|
||||
|
||||
/// @todo implement member function 'Circle::translate'
|
||||
Circle Circle::translate(const Vec2d& offset) const {
|
||||
Circle translated_circle = *this;
|
||||
translated_circle.c[0] += offset[0];
|
||||
translated_circle.c[1] += offset[1];
|
||||
return translated_circle;
|
||||
}
|
||||
|
||||
/// @todo implement member function 'Circle::check_invariants'
|
||||
bool Circle::check_invariants() const {
|
||||
if (std::isnan(c[0]) || std::isnan(c[1]) || std::isnan(r)) {
|
||||
return false;
|
||||
}
|
||||
if (r < 0) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/// ==================================== Triangle ================================================
|
||||
/// @todo Implement the missing member functions for Triangle as declared and specified in task2.hpp
|
||||
|
||||
/// @todo implement member function 'Triangle::bbox'
|
||||
BBox Triangle::bbox() const {
|
||||
BBox box = {{abc[0][0], abc[0][1]}, {abc[0][0], abc[0][1]}};
|
||||
for (int i = 1; i < 3; i++) {
|
||||
if (abc[i][0] < box.min[0]) {
|
||||
box.min[0] = abc[i][0];
|
||||
}
|
||||
if (abc[i][0] > box.max[0]) {
|
||||
box.max[0] = abc[i][0];
|
||||
}
|
||||
if (abc[i][1] < box.min[1]) {
|
||||
box.min[1] = abc[i][1];
|
||||
}
|
||||
if (abc[i][1] > box.max[1]) {
|
||||
box.max[1] = abc[i][1];
|
||||
}
|
||||
}
|
||||
return box;
|
||||
}
|
||||
|
||||
/// @todo implement member function 'Triangle::scale'
|
||||
Triangle Triangle::scale(const Vec2d& org, double s) const {
|
||||
Triangle scaled_triangle = *this;
|
||||
for (int i = 0; i < 3; i++) {
|
||||
scaled_triangle.abc[i][0] = org[0] + s * (abc[i][0] - org[0]);
|
||||
scaled_triangle.abc[i][1] = org[1] + s * (abc[i][1] - org[1]);
|
||||
}
|
||||
return scaled_triangle;
|
||||
}
|
||||
|
||||
/// @todo implement member function 'Triangle::rotate'
|
||||
Triangle Triangle::rotate(const Vec2d& org, double angle) const {
|
||||
Triangle rotated_triangle = *this;
|
||||
for (int i = 0; i < 3; i++) {
|
||||
double x = abc[i][0] - org[0];
|
||||
double y = abc[i][1] - org[1];
|
||||
rotated_triangle.abc[i][0] = org[0] + x * cos(angle) - y * sin(angle);
|
||||
rotated_triangle.abc[i][1] = org[1] + x * sin(angle) + y * cos(angle);
|
||||
}
|
||||
return rotated_triangle;
|
||||
}
|
||||
|
||||
/// @todo implement member function 'Triangle::translate'
|
||||
Triangle Triangle::translate(const Vec2d& offset) const {
|
||||
Triangle translated_triangle = *this;
|
||||
for (int i = 0; i < 3; i++) {
|
||||
translated_triangle.abc[i][0] += offset[0];
|
||||
translated_triangle.abc[i][1] += offset[1];
|
||||
}
|
||||
return translated_triangle;
|
||||
}
|
||||
|
||||
/// @todo implement member function 'Triangle::bbox'
|
||||
bool Triangle::check_invariants() const {
|
||||
if (std::isnan(abc[0][0]) || std::isnan(abc[0][1]) || std::isnan(abc[1][0]) || std::isnan(abc[1][1]) || std::isnan(abc[2][0]) || std::isnan(abc[2][1])) {
|
||||
return false;
|
||||
}
|
||||
if (iue::num::isclose(abc[0][0], abc[1][0]) && iue::num::isclose(abc[0][1], abc[1][1])) {
|
||||
return false;
|
||||
}
|
||||
if (iue::num::isclose(abc[0][0], abc[2][0]) && iue::num::isclose(abc[0][1], abc[2][1])) {
|
||||
return false;
|
||||
}
|
||||
if (iue::num::isclose(abc[1][0], abc[2][0]) && iue::num::isclose(abc[1][1], abc[2][1])) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace task2
|
||||
@@ -0,0 +1,87 @@
|
||||
/// @file
|
||||
/// @brief Task2: class definitions with member function declarations
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <array> // std::array
|
||||
|
||||
namespace task2 {
|
||||
|
||||
using Vec2d = std::array<double, 2>;
|
||||
|
||||
/// @brief Axis-aligned bounding box
|
||||
struct BBox {
|
||||
|
||||
Vec2d min; ///< coord of bottom left corner
|
||||
Vec2d max; ///< coord of top right corner
|
||||
|
||||
/// @brief Scales the bounding box (relative to a reference coordinate)
|
||||
/// @param org Reference coordinate
|
||||
/// @param s Scaling factor
|
||||
BBox scale(const Vec2d& org, double s) const;
|
||||
/// @brief Translates the line
|
||||
/// @param offset Translation vector
|
||||
BBox translate(const Vec2d& offset) const;
|
||||
/// @brief Checks if all invariants are fullfilled
|
||||
/// @return false if any invariant is violated, true otherwise
|
||||
/// Invariants:
|
||||
/// - no coordinate is NAN
|
||||
/// - the individual coordinates of 'min' are less or equal the respective coordinates in 'max'
|
||||
/// - 'min' is not close to 'max' (use iue::num::isclose to check)
|
||||
bool check_invariants() const;
|
||||
};
|
||||
|
||||
/// @brief Circle
|
||||
struct Circle {
|
||||
|
||||
Vec2d c; ///< coordinate of the center of the circle
|
||||
double r; ///< radius of the circle
|
||||
|
||||
/// @brief Generates the minimum axis-aligned bounding box containing this circle
|
||||
/// @return axis-aligned bounding box
|
||||
BBox bbox() const;
|
||||
/// @brief Scales the circle center (relative to a reference coordinate), and the radius with a scalar value
|
||||
/// @param org Reference coordinate
|
||||
/// @param s Scaling factor
|
||||
Circle scale(const Vec2d& org, double s) const;
|
||||
/// @brief Rotates the circle center (relative to a reference coordinate) counter clockwise
|
||||
/// @param org Reference coordinate
|
||||
/// @param angle Rotation angle (in radians)
|
||||
Circle rotate(const Vec2d& org, double angle) const;
|
||||
/// @brief Translates the circle center
|
||||
/// @param offset Translation vector
|
||||
Circle translate(const Vec2d& offset) const;
|
||||
/// @brief Checks if all invariants are fullfilled
|
||||
/// @return false if any invariant is violated, true otherwise
|
||||
/// @note Invariants: radius is non-negative and no coordinate is NAN
|
||||
bool check_invariants() const;
|
||||
};
|
||||
|
||||
/// @brief Triangle
|
||||
struct Triangle {
|
||||
|
||||
std::array<Vec2d, 3> abc; ///< three corner points of the triangle
|
||||
|
||||
/// @brief Generates the minimum axis-aligned bounding box containing this triangle
|
||||
/// @return axis-aligned bounding box
|
||||
BBox bbox() const;
|
||||
/// @brief Scales the triangle (relative to a reference coordinate)
|
||||
/// @param org Reference coordinate
|
||||
/// @param s Scaling factor
|
||||
Triangle scale(const Vec2d& org, double s) const;
|
||||
/// @brief Rotates the triangle (relative to a reference coordinate) counter clockwise
|
||||
/// @param org Reference coordinate
|
||||
/// @param angle Rotation angle (in radians)
|
||||
Triangle rotate(const Vec2d& org, double angle) const;
|
||||
/// @brief Translates the line
|
||||
/// @param offset Translation vector
|
||||
Triangle translate(const Vec2d& offset) const;
|
||||
/// @brief Checks if all invariants are fullfilled
|
||||
/// @return false if any invariant is violated, true otherwise
|
||||
/// Invariants:
|
||||
/// - no coordinate is NAN
|
||||
/// - none of the corner points are close to each other (use iue::num::isclose to check)
|
||||
bool check_invariants() const;
|
||||
};
|
||||
|
||||
} // namespace task2
|
||||
@@ -0,0 +1,86 @@
|
||||
/// @file
|
||||
/// @brief Task2: definitions of helper functions for the implementation and tests
|
||||
|
||||
#include "task2.misc.hpp"
|
||||
#include "task2.hpp" // task2::Vec2, task2::BBox, task2::Circle, task2::Triangle
|
||||
|
||||
#include "iue-num/numerics.hpp" // iue::num::isclose
|
||||
|
||||
#include <algorithm> // std::ranges::sort, std::ranges::next_permutation
|
||||
#include <array> // std::array
|
||||
#include <iostream> // std::ostream, std::endl
|
||||
|
||||
namespace task2 {
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const task2::Vec2d& v) { return os << "( " << v[0] << ", " << v[1] << " )"; }
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const task2::BBox& v) {
|
||||
return os << "BBox [ " << std::endl << " min = " << v.min << std::endl << " max = " << v.max << std::endl << "]";
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const task2::Circle& v) {
|
||||
return os << "Circle [ " << std::endl
|
||||
<< " center = " << v.c << std::endl
|
||||
<< " radius = " << v.r << std::endl
|
||||
<< "]";
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const task2::Triangle& v) {
|
||||
return os << "Triangle [ " << std::endl
|
||||
<< " a = " << v.abc[0] << std::endl
|
||||
<< " b = " << v.abc[1] << std::endl
|
||||
<< " c = " << v.abc[2] << std::endl
|
||||
<< "]";
|
||||
}
|
||||
|
||||
bool isclose(const task2::Vec2d& a, const task2::Vec2d& b) {
|
||||
if (!iue::num::isclose(a[0], b[0]))
|
||||
return false;
|
||||
if (!iue::num::isclose(a[1], b[1]))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool isclose(const task2::BBox& a, const task2::BBox& b) {
|
||||
if (!isclose(a.min, b.min))
|
||||
return false;
|
||||
if (!isclose(a.max, b.max))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool isclose(const task2::Circle& a, const task2::Circle& b) {
|
||||
if (!isclose(a.c, b.c))
|
||||
return false;
|
||||
if (!iue::num::isclose(a.r, b.r))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool isclose(const task2::Triangle& a, const task2::Triangle& b) {
|
||||
for (int n = 0; n != 3; ++n)
|
||||
if (!isclose(a.abc[n], b.abc[n]))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool isclose_permute(const task2::Triangle& a, const task2::Triangle& b) {
|
||||
auto permute = a.abc;
|
||||
std::ranges::sort(permute);
|
||||
auto keep = b.abc;
|
||||
do {
|
||||
if (isclose({permute}, {keep}))
|
||||
return true;
|
||||
} while (std::ranges::next_permutation(permute).found);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isnan(const Vec2d& v) {
|
||||
if (std::isnan(v[0]))
|
||||
return true;
|
||||
if (std::isnan(v[1]))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace task2
|
||||
@@ -0,0 +1,30 @@
|
||||
/// @file
|
||||
/// @brief Task2: declaration of helper functions for the implementation and tests
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "task2.hpp" // task2::Vec2d, task2::BBox, task2::Circle, task2::Triangle
|
||||
|
||||
#include <iostream> // std::ostream
|
||||
|
||||
namespace task2 {
|
||||
|
||||
/// @brief helper functions to print to the console
|
||||
std::ostream& operator<<(std::ostream& os, const task2::Vec2d& v);
|
||||
std::ostream& operator<<(std::ostream& os, const task2::BBox& v);
|
||||
std::ostream& operator<<(std::ostream& os, const task2::Circle& v);
|
||||
std::ostream& operator<<(std::ostream& os, const task2::Triangle& v);
|
||||
|
||||
/// @brief helper function checking if a NAN is present
|
||||
bool isnan(double v);
|
||||
|
||||
/// @brief helper functions for checking if two objects are numerically close
|
||||
bool isclose(const task2::Vec2d& a, const task2::Vec2d& b);
|
||||
bool isclose(const task2::BBox& a, const task2::BBox& b);
|
||||
bool isclose(const task2::Circle& a, const task2::Circle& b);
|
||||
bool isclose(const task2::Triangle& a, const task2::Triangle& b);
|
||||
|
||||
/// @brief helper function comparing Triangles including permutations of corners
|
||||
bool isclose_permute(const task2::Triangle& a, const task2::Triangle& b);
|
||||
|
||||
} // namespace task2
|
||||
@@ -0,0 +1,133 @@
|
||||
/// @file
|
||||
/// @brief Task2: tests
|
||||
|
||||
#include "task2.hpp" // task2::BBox, task2::Circle, task2::Triangle
|
||||
|
||||
#include "task2.misc.hpp" // task2::operator<<, task2::isclose
|
||||
|
||||
#include <cassert> // assert
|
||||
#include <cmath> // NAN
|
||||
#include <iostream> // std::cout, std::endl
|
||||
#include <numbers> // std::numbers::pi
|
||||
|
||||
int main() {
|
||||
|
||||
using namespace task2;
|
||||
|
||||
{ /// demo: using of functionality provided in 'task2.misc.hpp'
|
||||
BBox box = {{1, 2}, {3, 4}};
|
||||
Circle circle = {{1, 2}, 3};
|
||||
Triangle triangle = {Vec2d{0, 0}, Vec2d{1, 0}, Vec2d{1, 1}};
|
||||
std::cout << "printing demo:" << std::endl;
|
||||
std::cout << box << std::endl;
|
||||
std::cout << circle << std::endl;
|
||||
std::cout << triangle << std::endl;
|
||||
std::cout << "isclose demo:" << std::endl;
|
||||
std::cout << isclose(box, box) << std::endl;
|
||||
}
|
||||
|
||||
/// ======= BBox =============================
|
||||
|
||||
{ // testing function 'BBox::scale'
|
||||
BBox box = {Vec2d{-10, 10}, Vec2d{10, 10}};
|
||||
box = box.scale({-10, 0}, 2);
|
||||
BBox expected = {Vec2d{-10, 20}, Vec2d{30, 20}};
|
||||
assert(isclose(box, expected));
|
||||
}
|
||||
|
||||
{ // testing function 'BBox::translate'
|
||||
BBox box = {Vec2d{-10, 10}, Vec2d{10, 10}};
|
||||
box = box.translate({-10, 0});
|
||||
BBox expected = {Vec2d{-20, 10}, Vec2d{0, 10}};
|
||||
assert(isclose(box, expected));
|
||||
}
|
||||
|
||||
{ // testing function 'BBox::check_invariants'
|
||||
BBox box1 = {{NAN, 10}, {20, 20}};
|
||||
assert(!box1.check_invariants());
|
||||
BBox box2 = {{30, 10}, {20, 20}};
|
||||
assert(!box2.check_invariants());
|
||||
BBox box3 = {{-100, 10}, {20, 20}};
|
||||
assert(box3.check_invariants());
|
||||
}
|
||||
|
||||
/// ======= Circle =============================
|
||||
|
||||
{ // testing function 'Circle::bbox'
|
||||
Circle c = {{10, 10}, 1};
|
||||
BBox box = {{9, 9}, {11, 11}};
|
||||
assert(isclose(c.bbox(), box));
|
||||
}
|
||||
|
||||
{ // testing function 'Circle::scale'
|
||||
Circle c = {{10, 10}, 1};
|
||||
c = c.scale({0, 10}, 2);
|
||||
Circle expected = {{20, 10}, 2};
|
||||
assert(isclose(c, expected));
|
||||
}
|
||||
|
||||
{ // testing function 'Circle::rotate'
|
||||
Circle c = {{10, 10}, 1};
|
||||
c = c.rotate({0, 10}, std::numbers::pi);
|
||||
Circle expected = {{-10, 10}, 1};
|
||||
assert(isclose(c, expected));
|
||||
}
|
||||
|
||||
{ // testing function 'Circle::translate'
|
||||
Circle c = {{10, 10}, 1};
|
||||
c = c.translate({-20, -20});
|
||||
Circle expected = {{-10, -10}, 1};
|
||||
assert(isclose(c, expected));
|
||||
}
|
||||
|
||||
{ // testing function 'Circle::check_invariants'
|
||||
Circle c1 = {{10, 10}, -2};
|
||||
assert(!c1.check_invariants());
|
||||
Circle c2 = {{NAN, 10}, 1};
|
||||
assert(!c2.check_invariants());
|
||||
Circle c3 = {{-10, -10}, 1};
|
||||
assert(c3.check_invariants());
|
||||
}
|
||||
|
||||
/// ======= Triangle =============================
|
||||
|
||||
{ // testing function 'Triangle::bbox'
|
||||
Triangle t = {Vec2d{10, 10}, Vec2d{10, 20}, Vec2d{20, 10}};
|
||||
BBox box = {{10, 10}, {20, 20}};
|
||||
assert(isclose(t.bbox(), box));
|
||||
}
|
||||
|
||||
{ // testing function 'Triangle::scale'
|
||||
Triangle t = {Vec2d{10, 10}, Vec2d{10, 20}, Vec2d{20, 10}};
|
||||
t = t.scale({10, 20}, 2);
|
||||
Triangle e = {Vec2d{10, 0}, Vec2d{10, 20}, Vec2d{30, 0}};
|
||||
assert(isclose_permute(t, e));
|
||||
}
|
||||
|
||||
{ // testing function 'Triangle::rotate'
|
||||
Triangle t = {Vec2d{10, 10}, Vec2d{10, 20}, Vec2d{20, 10}};
|
||||
t = t.rotate({10, 20}, -std::numbers::pi / 2);
|
||||
Triangle e = {Vec2d{10, 20}, Vec2d{0, 20}, Vec2d{0, 10}};
|
||||
assert(isclose_permute(t, e));
|
||||
}
|
||||
|
||||
{ // testing function 'Triangle::translate'
|
||||
Triangle t = {Vec2d{10, 10}, Vec2d{10, 20}, Vec2d{20, 10}};
|
||||
t = t.translate({-10, -10});
|
||||
Triangle e = {Vec2d{0, 0}, Vec2d{0, 10}, Vec2d{10, 0}};
|
||||
assert(isclose_permute(t, e));
|
||||
}
|
||||
|
||||
{ // testing function 'Triangle::check_invariants'
|
||||
Triangle t1 = {Vec2d{NAN, 10}, Vec2d{10, 20}, Vec2d{20, 10}};
|
||||
assert(!t1.check_invariants());
|
||||
Triangle t2 = {Vec2d{0, 10}, Vec2d{10, 20}, Vec2d{20, 10}};
|
||||
assert(t2.check_invariants());
|
||||
Triangle t3 = {Vec2d{0, 10}, Vec2d{0, 10}, Vec2d{20, 10}};
|
||||
assert(!t3.check_invariants());
|
||||
}
|
||||
|
||||
std::cout << "task2.test.cpp: all asserts passed" << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
/// g++ -g -Imodules -std=c++20 task2.cpp task2.misc.cpp task3.cpp task3.misc.cpp task3.test.cpp -o build/task3.exe
|
||||
/// ./build/task3.exe
|
||||
/// @file
|
||||
/// @brief Task3: implementation
|
||||
|
||||
#include "task3.hpp" // task3::render_something
|
||||
|
||||
#include "task3.misc.hpp" // task3::render_wrapper
|
||||
|
||||
#include "task2.hpp" // task2::BBox, task2::Circle, task2::Triangle
|
||||
|
||||
#include "iue-rnd/random.hpp" // iue::rng::UniformDouble, iue::rng::UniformCircle, iue::rng::UniformTriangle
|
||||
|
||||
#include <cmath>
|
||||
#include <filesystem> // std::filesystem::path
|
||||
#include <iostream>
|
||||
#include <numbers>
|
||||
|
||||
/// @todo Include additional standard library headers as needed
|
||||
|
||||
namespace task3 {
|
||||
|
||||
/// @todo Implement function 'render_something' as declared and specified in task3.hpp
|
||||
/// Implementation Hints:
|
||||
/// - You can plot whatever you want, but you need to plot at least 20 primitives!
|
||||
/// - You can view .svg-files using your web browser (or installing a VSCode extension to preview SVGs)
|
||||
/// - use the provided function 'task3::render_wrapper' from 'task3.misc.hpp' to plot
|
||||
/// task2::BBox, task2::Circle, task2::Triangle to a SVG-file
|
||||
/// - The idea is that you make use of the functionality (scale/shift/rotate) you implemented in task2
|
||||
/// - Optional: you can make use of the random Generators in 'iue-rnd/random.hpp' to obtain random values, circles,
|
||||
/// and triangles
|
||||
int render_something(std::filesystem::path filepath) {
|
||||
|
||||
task2::Vec2d min = {0, 0};
|
||||
task2::Vec2d max = {1, 2};
|
||||
task2::BBox trunk = {min, max};
|
||||
task2::Circle leaves = {{0.5,0.5},1};
|
||||
std::vector<task2::BBox> bboxes;
|
||||
std::vector<task2::Circle> circles;
|
||||
std::vector<task2::Triangle> triangles;
|
||||
|
||||
|
||||
for(int i = 0; i < 20; i++){
|
||||
double x_trans=3*i;
|
||||
bboxes.push_back(trunk.translate({x_trans,0}));
|
||||
circles.push_back(leaves.translate({x_trans,2}));
|
||||
}
|
||||
|
||||
auto [bbmin, bbmax] = task3::render_wrapper(filepath, bboxes, circles, triangles);
|
||||
|
||||
return triangles.size() + bboxes.size() + circles.size();
|
||||
};
|
||||
|
||||
} // namespace task3
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
/// @file
|
||||
/// @brief Task3: function declarations
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <filesystem> // std::filesystem::path
|
||||
|
||||
namespace task3 {
|
||||
|
||||
/// @brief Renders an SVG image
|
||||
/// @param filepath Filename of the produced SVG-Image
|
||||
/// @return Total number of geometric primitives (Bbox, Circle, Triangle) plotted
|
||||
/// @note the content of the image is not restricted, but you need to plot at least 20 primitives
|
||||
int render_something(std::filesystem::path filepath);
|
||||
|
||||
} // namespace task3
|
||||
@@ -0,0 +1,34 @@
|
||||
/// @file
|
||||
/// @brief Task3: definitions of helper functions for the implementation and tests
|
||||
|
||||
#include "task3.misc.hpp"
|
||||
|
||||
#include "task2.hpp" // task2::BBox, task2::Circle, task2::Triangle,
|
||||
|
||||
#include "iue-svg/render.hpp" // iue::svg::render
|
||||
|
||||
#include <filesystem> // std::filesystem::path
|
||||
|
||||
namespace task3 {
|
||||
|
||||
task2::BBox render_wrapper(std::filesystem::path filepath, const std::vector<task2::BBox>& bboxes,
|
||||
const std::vector<task2::Circle>& circles, const std::vector<task2::Triangle>& triangles) {
|
||||
|
||||
auto circle_convert = [](const task2::Circle& in) -> iue::svg::Circle { return {in.c, in.r}; };
|
||||
std::vector<iue::svg::Circle> c;
|
||||
std::transform(circles.begin(), circles.end(), std::back_inserter(c), circle_convert);
|
||||
|
||||
auto triangle_convert = [](const task2::Triangle& in) -> iue::svg::Triangle { return {in.abc}; };
|
||||
std::vector<iue::svg::Triangle> t;
|
||||
std::transform(triangles.begin(), triangles.end(), std::back_inserter(t), triangle_convert);
|
||||
|
||||
auto bbox_convert = [](const task2::BBox& in) -> iue::svg::BBox { return iue::svg::BBox{in.min, in.max}; };
|
||||
std::vector<iue::svg::BBox> r;
|
||||
std::transform(bboxes.begin(), bboxes.end(), std::back_inserter(r), bbox_convert);
|
||||
|
||||
auto [bbmin, bbmax] = iue::svg::render(filepath, r, c, t);
|
||||
|
||||
return {bbmin, bbmax};
|
||||
}
|
||||
|
||||
} // namespace task3
|
||||
@@ -0,0 +1,25 @@
|
||||
/// @file
|
||||
/// @brief Task3: declaration of helper functions for the implementation
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "task2.hpp" // task3::render_something
|
||||
|
||||
#include <filesystem> // std::filesystem::path
|
||||
#include <vector> // std::vector
|
||||
|
||||
namespace task3 {
|
||||
|
||||
/// @brief Wrapper function for 'iue::svg::render' to support direct plotting of the types from task2:
|
||||
/// task2::BBox,
|
||||
/// task2::Circle
|
||||
/// task2::Triangle
|
||||
/// @param filepath Filename of the produced SVG-Image
|
||||
/// @param bboxes Sequence of bounding boxes to be plotted
|
||||
/// @param circles Sequence of circles to be plotted
|
||||
/// @param triangles Sequence of triangles to be plotted
|
||||
/// @return Enclosing bounding box of all rendered primitives
|
||||
task2::BBox render_wrapper(std::filesystem::path filepath, const std::vector<task2::BBox>& bboxes,
|
||||
const std::vector<task2::Circle>& circles, const std::vector<task2::Triangle>& triangles);
|
||||
|
||||
} // namespace task3
|
||||
@@ -0,0 +1,22 @@
|
||||
/// @file
|
||||
/// @brief Task3: tests
|
||||
|
||||
#include "task3.hpp" // task3::render_something
|
||||
|
||||
#include <cassert> // assert
|
||||
#include <filesystem> // std::filesystem::exists
|
||||
#include <iostream> // std::cout, sts::endl
|
||||
|
||||
int main() {
|
||||
|
||||
std::string filepath = "task3.test.svg";
|
||||
|
||||
std::filesystem::remove(filepath);
|
||||
int count = task3::render_something(filepath);
|
||||
assert(std::filesystem::exists(filepath));
|
||||
assert(count >= 20);
|
||||
|
||||
std::cout << "task3.test.cpp: all asserts passed" << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user