This commit is contained in:
2025-04-09 10:22:44 +02:00
commit 96ff5392c8
330 changed files with 28300 additions and 0 deletions
+10
View File
@@ -0,0 +1,10 @@
---
BasedOnStyle: LLVM
---
Language: Cpp
DerivePointerAlignment: false
PointerAlignment: Left
ColumnLimit: 120
TabWidth: 4
IndentWidth: 2
...
+25
View File
@@ -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]
+3
View File
@@ -0,0 +1,3 @@
task1
task2
task3
+3
View File
@@ -0,0 +1,3 @@
task1.main.cpp
task2.cpp
task3.cpp
+16
View File
@@ -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
+360
View File
@@ -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
+4
View File
@@ -0,0 +1,4 @@
[submodule "modules"]
path = modules
url = https://sgit.iue.tuwien.ac.at/360050/modules
branch = main
+50
View File
@@ -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})
+19
View File
@@ -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.**
+1
View File
@@ -0,0 +1 @@
-Imodules
File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 116 KiB

+265
View File
@@ -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

+256
View File
@@ -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![images/dusty_nikolaus_city.svg](images/dusty_nikolaus_city.svg)\n",
"\n",
"- horizontal verschobene \"Lokomotiven\"\n",
"\n",
"\t![images/trains.svg](images/trains.svg)"
]
},
{
"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
}
+1
Submodule exercise4/modules added at df348de23a
+43
View File
@@ -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;
}
+171
View File
@@ -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
+87
View File
@@ -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
+86
View File
@@ -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
+30
View File
@@ -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
+133
View File
@@ -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;
}
+55
View File
@@ -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
+16
View File
@@ -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
+34
View File
@@ -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
+25
View File
@@ -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
+22
View File
@@ -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;
}