├── doc ├── mole.png ├── rooster1.png ├── rep_image.png ├── pullrequest.png ├── task6_preview.png ├── branchstructure.png ├── githubclassroom.png ├── setup_glfw.md ├── setup_env.md ├── setup_eigen.md └── submit.md ├── task8 ├── slide0.png ├── slide1.png ├── preview.png ├── CMakeLists.txt ├── README.md └── main.cpp ├── task9 ├── slide0.png ├── slide1.png ├── slide2.png ├── preview.png ├── CMakeLists.txt ├── README.md └── main.cpp ├── task11 ├── preview.png ├── slide0.png ├── slide1.png ├── slide2.png ├── slide3.png ├── CMakeLists.txt ├── README.md ├── LICENSE.txt └── main.cpp ├── task2 ├── preview.png ├── CMakeLists.txt ├── README.md └── main.cpp ├── task3 ├── preview.png ├── CMakeLists.txt ├── README.md └── main.cpp ├── task5 ├── preview.png ├── jagged_array0.png ├── jagged_array1.png ├── CMakeLists.txt ├── README.md └── main.cpp ├── task6 ├── preview.png ├── lagrange0.png ├── lagrange1.png ├── CMakeLists.txt ├── README.md └── main.cpp ├── task7 ├── preview.png ├── slide_rotation0.png ├── slide_rotation1.png ├── slide_rotation2.png ├── CMakeLists.txt ├── README.md └── main.cpp ├── task0 ├── task0_preview.png ├── CMakeLists.txt ├── main.cpp └── README.md ├── task1 ├── task1_preview.png ├── CMakeLists.txt ├── README.md └── main.cpp ├── task4 ├── task4_preview.png ├── CMakeLists.txt ├── README.md └── main.cpp ├── .gitmodules ├── CMakeLists.txt ├── .gitignore ├── .github └── workflows │ ├── windows.yml │ └── ubuntu.yml ├── 3rd_party ├── FindEigen3.cmake └── FindGLFW.cmake └── README.md /doc/mole.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nobuyuki83/Physics-based_Animation_2021S/HEAD/doc/mole.png -------------------------------------------------------------------------------- /doc/rooster1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nobuyuki83/Physics-based_Animation_2021S/HEAD/doc/rooster1.png -------------------------------------------------------------------------------- /task8/slide0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nobuyuki83/Physics-based_Animation_2021S/HEAD/task8/slide0.png -------------------------------------------------------------------------------- /task8/slide1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nobuyuki83/Physics-based_Animation_2021S/HEAD/task8/slide1.png -------------------------------------------------------------------------------- /task9/slide0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nobuyuki83/Physics-based_Animation_2021S/HEAD/task9/slide0.png -------------------------------------------------------------------------------- /task9/slide1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nobuyuki83/Physics-based_Animation_2021S/HEAD/task9/slide1.png -------------------------------------------------------------------------------- /task9/slide2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nobuyuki83/Physics-based_Animation_2021S/HEAD/task9/slide2.png -------------------------------------------------------------------------------- /doc/rep_image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nobuyuki83/Physics-based_Animation_2021S/HEAD/doc/rep_image.png -------------------------------------------------------------------------------- /task11/preview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nobuyuki83/Physics-based_Animation_2021S/HEAD/task11/preview.png -------------------------------------------------------------------------------- /task11/slide0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nobuyuki83/Physics-based_Animation_2021S/HEAD/task11/slide0.png -------------------------------------------------------------------------------- /task11/slide1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nobuyuki83/Physics-based_Animation_2021S/HEAD/task11/slide1.png -------------------------------------------------------------------------------- /task11/slide2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nobuyuki83/Physics-based_Animation_2021S/HEAD/task11/slide2.png -------------------------------------------------------------------------------- /task11/slide3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nobuyuki83/Physics-based_Animation_2021S/HEAD/task11/slide3.png -------------------------------------------------------------------------------- /task2/preview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nobuyuki83/Physics-based_Animation_2021S/HEAD/task2/preview.png -------------------------------------------------------------------------------- /task3/preview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nobuyuki83/Physics-based_Animation_2021S/HEAD/task3/preview.png -------------------------------------------------------------------------------- /task5/preview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nobuyuki83/Physics-based_Animation_2021S/HEAD/task5/preview.png -------------------------------------------------------------------------------- /task6/preview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nobuyuki83/Physics-based_Animation_2021S/HEAD/task6/preview.png -------------------------------------------------------------------------------- /task7/preview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nobuyuki83/Physics-based_Animation_2021S/HEAD/task7/preview.png -------------------------------------------------------------------------------- /task8/preview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nobuyuki83/Physics-based_Animation_2021S/HEAD/task8/preview.png -------------------------------------------------------------------------------- /task9/preview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nobuyuki83/Physics-based_Animation_2021S/HEAD/task9/preview.png -------------------------------------------------------------------------------- /doc/pullrequest.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nobuyuki83/Physics-based_Animation_2021S/HEAD/doc/pullrequest.png -------------------------------------------------------------------------------- /doc/task6_preview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nobuyuki83/Physics-based_Animation_2021S/HEAD/doc/task6_preview.png -------------------------------------------------------------------------------- /task6/lagrange0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nobuyuki83/Physics-based_Animation_2021S/HEAD/task6/lagrange0.png -------------------------------------------------------------------------------- /task6/lagrange1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nobuyuki83/Physics-based_Animation_2021S/HEAD/task6/lagrange1.png -------------------------------------------------------------------------------- /doc/branchstructure.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nobuyuki83/Physics-based_Animation_2021S/HEAD/doc/branchstructure.png -------------------------------------------------------------------------------- /doc/githubclassroom.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nobuyuki83/Physics-based_Animation_2021S/HEAD/doc/githubclassroom.png -------------------------------------------------------------------------------- /task0/task0_preview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nobuyuki83/Physics-based_Animation_2021S/HEAD/task0/task0_preview.png -------------------------------------------------------------------------------- /task1/task1_preview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nobuyuki83/Physics-based_Animation_2021S/HEAD/task1/task1_preview.png -------------------------------------------------------------------------------- /task4/task4_preview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nobuyuki83/Physics-based_Animation_2021S/HEAD/task4/task4_preview.png -------------------------------------------------------------------------------- /task5/jagged_array0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nobuyuki83/Physics-based_Animation_2021S/HEAD/task5/jagged_array0.png -------------------------------------------------------------------------------- /task5/jagged_array1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nobuyuki83/Physics-based_Animation_2021S/HEAD/task5/jagged_array1.png -------------------------------------------------------------------------------- /task7/slide_rotation0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nobuyuki83/Physics-based_Animation_2021S/HEAD/task7/slide_rotation0.png -------------------------------------------------------------------------------- /task7/slide_rotation1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nobuyuki83/Physics-based_Animation_2021S/HEAD/task7/slide_rotation1.png -------------------------------------------------------------------------------- /task7/slide_rotation2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nobuyuki83/Physics-based_Animation_2021S/HEAD/task7/slide_rotation2.png -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "3rd_party/glfw"] 2 | path = 3rd_party/glfw 3 | url = https://github.com/glfw/glfw.git 4 | [submodule "3rd_party/delfem2"] 5 | path = 3rd_party/delfem2 6 | url = https://github.com/nobuyuki83/delfem2.git 7 | [submodule "3rd_party/eigen"] 8 | path = 3rd_party/eigen 9 | url = https://gitlab.com/libeigen/eigen.git 10 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.12) 2 | 3 | project(tasks) 4 | 5 | add_subdirectory(task0) 6 | add_subdirectory(task1) 7 | add_subdirectory(task2) 8 | add_subdirectory(task3) 9 | add_subdirectory(task4) 10 | add_subdirectory(task5) 11 | add_subdirectory(task6) 12 | add_subdirectory(task8) 13 | add_subdirectory(task9) 14 | add_subdirectory(task11) 15 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Compiled Object files 5 | *.slo 6 | *.lo 7 | *.o 8 | *.obj 9 | 10 | # Precompiled Headers 11 | *.gch 12 | *.pch 13 | 14 | # Compiled Dynamic libraries 15 | *.so 16 | *.dylib 17 | *.dll 18 | 19 | # Fortran module files 20 | *.mod 21 | *.smod 22 | 23 | # Compiled Static libraries 24 | *.lai 25 | *.la 26 | *.a 27 | *.lib 28 | 29 | # Executables 30 | *.exe 31 | *.out 32 | *.app 33 | 34 | .idea 35 | cmake-build-debug 36 | cmake-build-release 37 | */.idea 38 | 39 | build 40 | */build 41 | 42 | 3rd_party/GLFW_Lib 43 | 3rd_party/Eigen_Lib 44 | eigen-* 45 | 46 | 47 | .vs 48 | .vscode 49 | 50 | CMakeFiles 51 | 52 | .DS_Store 53 | 54 | !task11/fertility.obj -------------------------------------------------------------------------------- /task0/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.12) 2 | 3 | enable_language(CXX) 4 | set(CMAKE_CXX_STANDARD 11) 5 | set(CMAKE_CXX_STANDARD_REQUIRED TRUE) 6 | IF(MSVC) 7 | set(CMAKE_CXX_FLAGS "/W4 -O2 \ 8 | /wd4100 /wd4458 /wd4577 /wd4267 /wd4244 /wd4505 /wd4838 \ 9 | /wd4800 /wd4996 /wd4530 /wd4245 /wd4505 /wd4505 /wd4456 ") 10 | ELSE() 11 | set(CMAKE_CXX_FLAGS "-Wall -Wno-deprecated-declarations -g") 12 | ENDIF() 13 | 14 | project(task0) 15 | 16 | ################################ 17 | 18 | # glfw 19 | SET(GLFW_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/../3rd_party/GLFW_Lib) 20 | include(${CMAKE_CURRENT_SOURCE_DIR}/../3rd_party/FindGLFW.cmake) 21 | 22 | # opengl 23 | find_package(OpenGL REQUIRED) 24 | 25 | ################################ 26 | 27 | include_directories( 28 | ${OPENGL_INCLUDE_DIR} 29 | ${GLFW_INCLUDE_DIR} 30 | ) 31 | 32 | add_executable(${PROJECT_NAME} 33 | main.cpp 34 | ) 35 | 36 | target_link_libraries(${PROJECT_NAME} 37 | ${OPENGL_LIBRARY} 38 | ${GLFW_LIBRARIES} 39 | ) -------------------------------------------------------------------------------- /task5/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.12) 2 | 3 | enable_language(CXX) 4 | set(CMAKE_CXX_STANDARD 11) 5 | set(CMAKE_CXX_STANDARD_REQUIRED TRUE) 6 | IF(MSVC) 7 | set(CMAKE_CXX_FLAGS "/W4 -O2 \ 8 | /wd4100 /wd4458 /wd4577 /wd4267 /wd4244 /wd4505 /wd4838 \ 9 | /wd4800 /wd4996 /wd4530 /wd4245 /wd4505 /wd4505 /wd4456 ") 10 | ELSE() 11 | set(CMAKE_CXX_FLAGS "-Wall -Wno-deprecated-declarations -g") 12 | ENDIF() 13 | 14 | project(task5) 15 | 16 | ################################ 17 | 18 | # glfw 19 | SET(GLFW_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/../3rd_party/GLFW_Lib) 20 | include(${CMAKE_CURRENT_SOURCE_DIR}/../3rd_party/FindGLFW.cmake) 21 | 22 | # opengl 23 | find_package(OpenGL REQUIRED) 24 | 25 | # delfem2 26 | add_definitions(-DDFM2_HEADER_ONLY=ON) 27 | set(DELFEM2_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../3rd_party/delfem2/include") 28 | 29 | ################################ 30 | 31 | include_directories( 32 | ${OPENGL_INCLUDE_DIR} 33 | ${GLFW_INCLUDE_DIR} 34 | ${DELFEM2_INCLUDE_DIR} 35 | ) 36 | 37 | add_executable(${PROJECT_NAME} 38 | main.cpp 39 | ) 40 | 41 | target_link_libraries(${PROJECT_NAME} 42 | ${OPENGL_LIBRARY} 43 | ${GLFW_LIBRARIES} 44 | ) -------------------------------------------------------------------------------- /task1/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.12) 2 | 3 | enable_language(CXX) 4 | set(CMAKE_CXX_STANDARD 11) 5 | set(CMAKE_CXX_STANDARD_REQUIRED TRUE) 6 | IF(MSVC) 7 | set(CMAKE_CXX_FLAGS "/W4 -O2 \ 8 | /wd4100 /wd4458 /wd4577 /wd4267 /wd4244 /wd4505 /wd4838 \ 9 | /wd4800 /wd4996 /wd4530 /wd4245 /wd4505 /wd4505 /wd4456 ") 10 | ELSE() 11 | set(CMAKE_CXX_FLAGS "-Wall -Wno-deprecated-declarations -g") 12 | ENDIF() 13 | 14 | project(task1) 15 | 16 | ################################ 17 | 18 | # glfw 19 | SET(GLFW_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/../3rd_party/GLFW_Lib) 20 | include(${CMAKE_CURRENT_SOURCE_DIR}/../3rd_party/FindGLFW.cmake) 21 | 22 | # opengl 23 | find_package(OpenGL REQUIRED) 24 | 25 | # delfem2 26 | # dfm2 27 | add_definitions(-DDFM2_HEADER_ONLY=ON) 28 | set(DELFEM2_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../3rd_party/delfem2/include") 29 | 30 | ################################ 31 | 32 | include_directories( 33 | ${OPENGL_INCLUDE_DIR} 34 | ${GLFW_INCLUDE_DIR} 35 | ${DELFEM2_INCLUDE_DIR} 36 | ) 37 | 38 | add_executable(${PROJECT_NAME} 39 | main.cpp 40 | ) 41 | 42 | target_link_libraries(${PROJECT_NAME} 43 | ${OPENGL_LIBRARY} 44 | ${GLFW_LIBRARIES} 45 | ) -------------------------------------------------------------------------------- /task2/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.12) 2 | 3 | enable_language(CXX) 4 | set(CMAKE_CXX_STANDARD 11) 5 | set(CMAKE_CXX_STANDARD_REQUIRED TRUE) 6 | IF(MSVC) 7 | set(CMAKE_CXX_FLAGS "/W4 -O2 \ 8 | /wd4100 /wd4458 /wd4577 /wd4267 /wd4244 /wd4505 /wd4838 \ 9 | /wd4800 /wd4996 /wd4530 /wd4245 /wd4505 /wd4505 /wd4456 ") 10 | ELSE() 11 | set(CMAKE_CXX_FLAGS "-Wall -Wno-deprecated-declarations -g") 12 | ENDIF() 13 | 14 | project(task2) 15 | 16 | ################################ 17 | 18 | # glfw 19 | SET(GLFW_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/../3rd_party/GLFW_Lib) 20 | include(${CMAKE_CURRENT_SOURCE_DIR}/../3rd_party/FindGLFW.cmake) 21 | 22 | # opengl 23 | find_package(OpenGL REQUIRED) 24 | 25 | # delfem2 26 | # dfm2 27 | add_definitions(-DDFM2_HEADER_ONLY=ON) 28 | set(DELFEM2_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../3rd_party/delfem2/include") 29 | 30 | ################################ 31 | 32 | include_directories( 33 | ${OPENGL_INCLUDE_DIR} 34 | ${GLFW_INCLUDE_DIR} 35 | ${DELFEM2_INCLUDE_DIR} 36 | ) 37 | 38 | add_executable(${PROJECT_NAME} 39 | main.cpp 40 | ) 41 | 42 | target_link_libraries(${PROJECT_NAME} 43 | ${OPENGL_LIBRARY} 44 | ${GLFW_LIBRARIES} 45 | ) -------------------------------------------------------------------------------- /task4/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.12) 2 | 3 | enable_language(CXX) 4 | set(CMAKE_CXX_STANDARD 11) 5 | set(CMAKE_CXX_STANDARD_REQUIRED TRUE) 6 | IF(MSVC) 7 | set(CMAKE_CXX_FLAGS "/W4 -O2 \ 8 | /wd4100 /wd4458 /wd4577 /wd4267 /wd4244 /wd4505 /wd4838 \ 9 | /wd4800 /wd4996 /wd4530 /wd4245 /wd4505 /wd4505 /wd4456 ") 10 | ELSE() 11 | set(CMAKE_CXX_FLAGS "-Wall -Wno-deprecated-declarations -g") 12 | ENDIF() 13 | 14 | project(task4) 15 | 16 | ################################ 17 | 18 | # glfw 19 | SET(GLFW_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/../3rd_party/GLFW_Lib) 20 | include(${CMAKE_CURRENT_SOURCE_DIR}/../3rd_party/FindGLFW.cmake) 21 | 22 | # opengl 23 | find_package(OpenGL REQUIRED) 24 | 25 | # delfem2 26 | # dfm2 27 | add_definitions(-DDFM2_HEADER_ONLY=ON) 28 | set(DELFEM2_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../3rd_party/delfem2/include") 29 | 30 | ################################ 31 | 32 | include_directories( 33 | ${OPENGL_INCLUDE_DIR} 34 | ${GLFW_INCLUDE_DIR} 35 | ${DELFEM2_INCLUDE_DIR} 36 | ) 37 | 38 | add_executable(${PROJECT_NAME} 39 | main.cpp 40 | ) 41 | 42 | target_link_libraries(${PROJECT_NAME} 43 | ${OPENGL_LIBRARY} 44 | ${GLFW_LIBRARIES} 45 | ) -------------------------------------------------------------------------------- /.github/workflows/windows.yml: -------------------------------------------------------------------------------- 1 | name: BuildTasks 2 | 3 | on: 4 | push: 5 | branches: [ main ] 6 | pull_request: 7 | branches: [ main, task0, task1, task2, task3, task4, task5, task6, task7, task8, task9, task11] 8 | 9 | env: 10 | BUILD_TYPE: Debug 11 | 12 | jobs: 13 | build: 14 | runs-on: windows-latest 15 | 16 | steps: 17 | - uses: actions/checkout@v2 18 | 19 | - name: get_glfw 20 | run: | 21 | git submodule update --init -- 3rd_party/glfw 22 | cd 3rd_party/glfw 23 | cmake . -A x64 24 | cmake --build . --config Release 25 | mkdir ../GLFW_Lib 26 | cmake --install . --prefix ../GLFW_Lib 27 | 28 | - name: get_delfem2 29 | run: | 30 | git submodule update --init -- 3rd_party/delfem2 31 | 32 | - name: get_eigen 33 | run: | 34 | git submodule update --init 3rd_party/eigen 35 | # the following costs a lot of $ on GitHub Actions 36 | # cd 3rd_party/eigen 37 | # mkdir build 38 | # cd build 39 | # cmake .. 40 | # cmake --install . --prefix ../../Eigen_Lib 41 | 42 | - name: build 43 | run: | 44 | cmake . -A x64 45 | cmake --build . 46 | -------------------------------------------------------------------------------- /.github/workflows/ubuntu.yml: -------------------------------------------------------------------------------- 1 | name: BuildTasks 2 | 3 | on: 4 | push: 5 | branches: [ main ] 6 | pull_request: 7 | branches: [ main, task0, task1, task2, task3, task4, task5, task6, task7, task8, task9, task11] 8 | 9 | env: 10 | BUILD_TYPE: Debug 11 | 12 | jobs: 13 | build: 14 | runs-on: ubuntu-latest 15 | 16 | steps: 17 | - uses: actions/checkout@v2 18 | 19 | - name: get_glfw 20 | run: | 21 | sudo apt-get update 22 | sudo apt-get install \ 23 | xorg-dev libx11-dev \ 24 | libglu1-mesa libglu1-mesa-dev \ 25 | libgl1-mesa-glx libgl1-mesa-dev 26 | sudo apt-get install libglfw3 27 | sudo apt-get install libglfw3-dev 28 | 29 | # removed to save the cost for the Github Action 30 | # git submodule update --init -- 3rd_party/glfw 31 | # cd 3rd_party/glfw 32 | # cmake . 33 | # cmake --build . 34 | # cmake -E make_directory ../GLFW_Lib 35 | # cmake --install . --prefix ../GLFW_Lib 36 | 37 | - name: get_delfem2 38 | run: | 39 | git submodule update --init -- 3rd_party/delfem2 40 | 41 | - name: get_eigen 42 | run: | 43 | sudo apt-get install libeigen3-dev 44 | 45 | - name: build 46 | run: | 47 | cmake . 48 | cmake --build . 49 | -------------------------------------------------------------------------------- /task4/README.md: -------------------------------------------------------------------------------- 1 | # Task4: Sort & Sweep Collision Culling 2 | 3 | **Deadline: May 13th (Thu) at 15:00pm** 4 | 5 | ![task4_preview](task4_preview.png) 6 | 7 | ## Setting Up 8 | 9 | Pleae look at the following document for environment setup, creating branch, and making pull request. 10 | 11 | [How to Submit the Assignment](../doc/submit.md) 12 | 13 | Additionally, you need the library [DelFEM2](https://github.com/nobuyuki83/delfem2) in `pba-/3rd_party` 14 | 15 | ```bash 16 | $ cd pba- # go to the top of local repository 17 | $ git submodule update --init 3rd_party/delfem2 18 | ``` 19 | 20 | (DelFEM2 is a collection of useful C++ codes written by the instructer.) 21 | 22 | 23 | 24 | ## Problem1 25 | 26 | Compile the `main.cpp` using the `cmake` on the `CMakeLists.txt` . Run the program and take a screenshot image of the window appeared. Paste the screenshot image below. 27 | 28 | === paste screenshot here === 29 | 30 | 31 | 32 | ## Problem 2 33 | 34 | Using the **Sort & Sweep Method**, implement the fast collision detection between the circles. Make the color of the collided circles red. This can be done by setting `true` the `is_collided` member variable of the `CCircle` class. Implementation should be just adding 5 -10 lines of code around line #135 of `main.cpp`. Use the function `is_collide()` at line #102. Take a screenshot image and paste it below. 35 | 36 | === paste screenshot here === 37 | 38 | 39 | 40 | 41 | 42 | ---- 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /task2/README.md: -------------------------------------------------------------------------------- 1 | # Task2: Optimization 2 | 3 | **Deadline: May 20th (Thursday) at 15:00pm** 4 | 5 | ![preview](preview.png) 6 | 7 | ## Setting Up 8 | 9 | Pleae take a look at the following document for environment setup, creating branch, and making a pull request. 10 | 11 | [How to Submit the Assignment](../doc/submit.md) 12 | 13 | Additionally, you need the library [DelFEM2](https://github.com/nobuyuki83/delfem2) in `pba-/3rd_party` 14 | 15 | ```bash 16 | $ cd pba- # go to the top of local repository 17 | $ git submodule update --init 3rd_party/delfem2 18 | ``` 19 | 20 | (DelFEM2 is a collection of useful C++ codes written by the instructer.) 21 | 22 | 23 | 24 | ## Problem1 25 | 26 | Compile the code in this folder using `cmake`, use the **out-of-source build** too keep this directory clean. 27 | Run the program and take a screenshot image of the resulting window. 28 | Paste the screenshot below by editing this markdown document. 29 | 30 | === paset screenshot here === 31 | 32 | 33 | 34 | ## Problem 2 35 | 36 | Optimize the position of the blue point using the Newton-Raphson method such that it will **minimise the sum of the squared distance between black points**. 37 | The Newton-Raphson method requires gradient and hessian of the energy with respect to the position. 38 | Fill the code around line #90 to **analytically** compute the graiend and hessian of the squared distance. 39 | Paste the screenshot image of the result below. 40 | 41 | === paset screenshot here === 42 | 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /task1/README.md: -------------------------------------------------------------------------------- 1 | # Task1: Particle System 2 | 3 | **deadline: April 29th (Thu) at 15:00pm** 4 | 5 | ![task1_preview](task1_preview.png) 6 | 7 | 8 | ## Setting Up 9 | 10 | Pleae look at the following document for environment setup, creating branch, and making pull request. 11 | 12 | [How to Submit the Assignment](../doc/submit.md) 13 | 14 | - make sure you synchronized the `main ` branch of your local repository to that of remote repository. 15 | - make sure you created branc h `task1` from `main` branch. 16 | - make sure you are currently in the `task1` branch (use `git branch -a` command). 17 | 18 | 19 | Additionally, you need the library [DelFEM2](https://github.com/nobuyuki83/delfem2) in `pba-/3rd_party` 20 | 21 | ```bash 22 | $ cd pba- # go to the top of local repository 23 | $ git submodule update --init 3rd_party/delfem2 24 | ``` 25 | 26 | (DelFEM2 is a collection of useful C++ codes written by the instructer). 27 | 28 | 29 | 30 | ## Problem1 31 | 32 | 1. Build the code using cmake 33 | 2. Run the code 34 | 3. Take a screenshot image (looks like image at the top) 35 | 4. Paste the screenshot image below 36 | 37 | 38 | 39 | === Paste the screen shot here`![]()` === 40 | 41 | 42 | 43 | ## Problem 2 44 | 45 | Modify `main.cpp` to collide points with the circular obstacle in the middle (see around 92th line of the code). Just 4 or 5 lines of codes need to be modifiled. We assume that the **coefficient of restitution** is one. 46 | 47 | 48 | === Paste the screen shot here`![]()` === 49 | 50 | 51 | -------------------------------------------------------------------------------- /task6/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.12) 2 | 3 | enable_language(CXX) 4 | set(CMAKE_CXX_STANDARD 11) 5 | set(CMAKE_CXX_STANDARD_REQUIRED TRUE) 6 | IF(MSVC) 7 | set(CMAKE_CXX_FLAGS "/W4 -O2 \ 8 | /wd4100 /wd4458 /wd4577 /wd4267 /wd4244 /wd4505 /wd4838 \ 9 | /wd4800 /wd4996 /wd4530 /wd4245 /wd4505 /wd4505 /wd4456 ") 10 | ELSE() 11 | set(CMAKE_CXX_FLAGS "-Wall -Wno-deprecated-declarations -g") 12 | ENDIF() 13 | 14 | project(task6) 15 | 16 | ################################ 17 | 18 | # glfw 19 | SET(GLFW_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/../3rd_party/GLFW_Lib) 20 | include(${CMAKE_CURRENT_SOURCE_DIR}/../3rd_party/FindGLFW.cmake) 21 | 22 | # opengl 23 | find_package(OpenGL REQUIRED) 24 | 25 | # eigen 26 | FILE(GLOB EIGEN3_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/../3rd_party/eigen*) # find downloaded eigen directories in 3rd_party 27 | SET(EIGEN3_ROOT 28 | ${CMAKE_CURRENT_SOURCE_DIR}/../3rd_party/Eigen_Lib/include # installed eigen is higher priority 29 | ${EIGEN3_ROOT} ) # specify candidate for eigen location 30 | include(${CMAKE_CURRENT_SOURCE_DIR}/../3rd_party/FindEigen3.cmake) # call script to find eigen3 31 | #find_package(Eigen3 REQUIRED) # this works only for installation from package manager 32 | message(STATUS "eigen3 locatoin: ${EIGEN3_INCLUDE_DIR}") 33 | 34 | # delfem2 35 | add_definitions(-DDFM2_HEADER_ONLY=ON) 36 | set(DELFEM2_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../3rd_party/delfem2/include") 37 | 38 | ################################ 39 | 40 | include_directories( 41 | ${OPENGL_INCLUDE_DIR} 42 | ${GLFW_INCLUDE_DIR} 43 | ${DELFEM2_INCLUDE_DIR} 44 | ${EIGEN3_INCLUDE_DIR} 45 | ) 46 | 47 | add_executable(${PROJECT_NAME} 48 | main.cpp 49 | ) 50 | 51 | target_link_libraries(${PROJECT_NAME} 52 | ${OPENGL_LIBRARY} 53 | ${GLFW_LIBRARIES} 54 | ) -------------------------------------------------------------------------------- /task9/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.12) 2 | 3 | enable_language(CXX) 4 | set(CMAKE_CXX_STANDARD 11) 5 | set(CMAKE_CXX_STANDARD_REQUIRED TRUE) 6 | IF(MSVC) 7 | set(CMAKE_CXX_FLAGS "/W4 -O2 \ 8 | /wd4100 /wd4458 /wd4577 /wd4267 /wd4244 /wd4505 /wd4838 \ 9 | /wd4800 /wd4996 /wd4530 /wd4245 /wd4505 /wd4505 /wd4456 ") 10 | ELSE() 11 | set(CMAKE_CXX_FLAGS "-Wall -Wno-deprecated-declarations -g") 12 | ENDIF() 13 | 14 | project(task9) 15 | 16 | ################################ 17 | 18 | # glfw 19 | SET(GLFW_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/../3rd_party/GLFW_Lib) 20 | include(${CMAKE_CURRENT_SOURCE_DIR}/../3rd_party/FindGLFW.cmake) 21 | 22 | # opengl 23 | find_package(OpenGL REQUIRED) 24 | 25 | # delfem2 26 | add_definitions(-DDFM2_HEADER_ONLY=ON) 27 | set(DELFEM2_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../3rd_party/delfem2/include") 28 | 29 | # eigen 30 | FILE(GLOB EIGEN3_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/../3rd_party/eigen*) # find downloaded eigen directories in 3rd_party 31 | SET(EIGEN3_ROOT 32 | ${CMAKE_CURRENT_SOURCE_DIR}/../3rd_party/Eigen_Lib/include # installed eigen is higher priority 33 | ${EIGEN3_ROOT} ) # specify candidate for eigen location 34 | include(${CMAKE_CURRENT_SOURCE_DIR}/../3rd_party/FindEigen3.cmake) # call script to find eigen3 35 | #find_package(Eigen3 REQUIRED) # this works only for installation from package manager 36 | message(STATUS "eigen3 locatoin: ${EIGEN3_INCLUDE_DIR}") 37 | 38 | ################################ 39 | 40 | include_directories( 41 | ${OPENGL_INCLUDE_DIR} 42 | ${GLFW_INCLUDE_DIR} 43 | ${DELFEM2_INCLUDE_DIR} 44 | ${EIGEN3_INCLUDE_DIR} 45 | ) 46 | 47 | add_executable(${PROJECT_NAME} 48 | main.cpp 49 | ) 50 | 51 | target_link_libraries(${PROJECT_NAME} 52 | ${OPENGL_LIBRARY} 53 | ${GLFW_LIBRARIES} 54 | ) -------------------------------------------------------------------------------- /task3/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.12) 2 | 3 | enable_language(CXX) 4 | set(CMAKE_CXX_STANDARD 11) 5 | set(CMAKE_CXX_STANDARD_REQUIRED TRUE) 6 | IF(MSVC) 7 | set(CMAKE_CXX_FLAGS "/W4 -O2 \ 8 | /wd4100 /wd4458 /wd4577 /wd4267 /wd4244 /wd4505 /wd4838 \ 9 | /wd4800 /wd4996 /wd4530 /wd4245 /wd4505 /wd4505 /wd4456 ") 10 | ELSE() 11 | set(CMAKE_CXX_FLAGS "-Wall -Wno-deprecated-declarations -g") 12 | ENDIF() 13 | 14 | project(task3) 15 | 16 | ################################ 17 | 18 | # glfw 19 | SET(GLFW_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/../3rd_party/GLFW_Lib) # specify candidate for glfw location 20 | include(${CMAKE_CURRENT_SOURCE_DIR}/../3rd_party/FindGLFW.cmake) # call script to find glfw 21 | 22 | # opengl 23 | find_package(OpenGL REQUIRED) 24 | 25 | # eigen 26 | FILE(GLOB EIGEN3_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/../3rd_party/eigen*) # find downloaded eigen directories in 3rd_party 27 | SET(EIGEN3_ROOT 28 | ${CMAKE_CURRENT_SOURCE_DIR}/../3rd_party/Eigen_Lib/include # installed eigen is higher priority 29 | ${EIGEN3_ROOT} ) # specify candidate for eigen location 30 | include(${CMAKE_CURRENT_SOURCE_DIR}/../3rd_party/FindEigen3.cmake) # call script to find eigen3 31 | #find_package(Eigen3 REQUIRED) # this works only for installation from package manager 32 | message(STATUS "eigen3 locatoin: ${EIGEN3_INCLUDE_DIR}") 33 | 34 | # delfem2 35 | add_definitions(-DDFM2_HEADER_ONLY=ON) 36 | set(DELFEM2_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../3rd_party/delfem2/include") 37 | 38 | ################################ 39 | 40 | include_directories( 41 | ${OPENGL_INCLUDE_DIR} 42 | ${GLFW_INCLUDE_DIR} 43 | ${DELFEM2_INCLUDE_DIR} 44 | ${EIGEN3_INCLUDE_DIR} 45 | ) 46 | 47 | add_executable(${PROJECT_NAME} 48 | main.cpp 49 | ) 50 | 51 | target_link_libraries(${PROJECT_NAME} 52 | ${OPENGL_LIBRARY} 53 | ${GLFW_LIBRARIES} 54 | ) -------------------------------------------------------------------------------- /task8/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.12) 2 | 3 | enable_language(CXX) 4 | set(CMAKE_CXX_STANDARD 11) 5 | set(CMAKE_CXX_STANDARD_REQUIRED TRUE) 6 | IF(MSVC) 7 | set(CMAKE_CXX_FLAGS "/W4 -O2 \ 8 | /wd4100 /wd4458 /wd4577 /wd4267 /wd4244 /wd4505 /wd4838 \ 9 | /wd4800 /wd4996 /wd4530 /wd4245 /wd4505 /wd4505 /wd4456 ") 10 | ELSE() 11 | set(CMAKE_CXX_FLAGS "-Wall -Wno-deprecated-declarations -g") 12 | ENDIF() 13 | 14 | project(task8) 15 | 16 | ################################ 17 | 18 | # glfw 19 | SET(GLFW_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/../3rd_party/GLFW_Lib) # specify candidate for glfw location 20 | include(${CMAKE_CURRENT_SOURCE_DIR}/../3rd_party/FindGLFW.cmake) # call script to find glfw 21 | 22 | # opengl 23 | find_package(OpenGL REQUIRED) 24 | 25 | # eigen 26 | FILE(GLOB EIGEN3_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/../3rd_party/eigen*) # find downloaded eigen directories in 3rd_party 27 | SET(EIGEN3_ROOT 28 | ${CMAKE_CURRENT_SOURCE_DIR}/../3rd_party/Eigen_Lib/include # installed eigen is higher priority 29 | ${EIGEN3_ROOT} ) # specify candidate for eigen location 30 | include(${CMAKE_CURRENT_SOURCE_DIR}/../3rd_party/FindEigen3.cmake) # call script to find eigen3 31 | #find_package(Eigen3 REQUIRED) # this works only for installation from package manager 32 | message(STATUS "eigen3 locatoin: ${EIGEN3_INCLUDE_DIR}") 33 | 34 | # delfem2 35 | add_definitions(-DDFM2_HEADER_ONLY=ON) 36 | set(DELFEM2_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../3rd_party/delfem2/include") 37 | 38 | ################################ 39 | 40 | include_directories( 41 | ${OPENGL_INCLUDE_DIR} 42 | ${GLFW_INCLUDE_DIR} 43 | ${DELFEM2_INCLUDE_DIR} 44 | ${EIGEN3_INCLUDE_DIR} 45 | ) 46 | 47 | add_executable(${PROJECT_NAME} 48 | main.cpp 49 | ) 50 | 51 | target_link_libraries(${PROJECT_NAME} 52 | ${OPENGL_LIBRARY} 53 | ${GLFW_LIBRARIES} 54 | ) -------------------------------------------------------------------------------- /task11/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.12) 2 | 3 | enable_language(CXX) 4 | set(CMAKE_CXX_STANDARD 11) 5 | set(CMAKE_CXX_STANDARD_REQUIRED TRUE) 6 | IF(MSVC) 7 | set(CMAKE_CXX_FLAGS "/W4 -O2 \ 8 | /wd4100 /wd4458 /wd4577 /wd4267 /wd4244 /wd4505 /wd4838 \ 9 | /wd4800 /wd4996 /wd4530 /wd4245 /wd4505 /wd4505 /wd4456 ") 10 | ELSE() 11 | set(CMAKE_CXX_FLAGS "-Wall -Wno-deprecated-declarations -g") 12 | ENDIF() 13 | 14 | project(task11) 15 | 16 | ################################ 17 | 18 | add_definitions(-DPATH_SOURCE="${PROJECT_SOURCE_DIR}") 19 | 20 | # glfw 21 | SET(GLFW_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/../3rd_party/GLFW_Lib) 22 | include(${CMAKE_CURRENT_SOURCE_DIR}/../3rd_party/FindGLFW.cmake) 23 | 24 | # opengl 25 | find_package(OpenGL REQUIRED) 26 | 27 | # delfem2 28 | add_definitions(-DDFM2_HEADER_ONLY=ON) 29 | set(DELFEM2_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../3rd_party/delfem2/include") 30 | 31 | # eigen 32 | FILE(GLOB EIGEN3_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/../3rd_party/eigen*) # find downloaded eigen directories in 3rd_party 33 | SET(EIGEN3_ROOT 34 | ${CMAKE_CURRENT_SOURCE_DIR}/../3rd_party/Eigen_Lib/include # installed eigen is higher priority 35 | ${EIGEN3_ROOT} ) # specify candidate for eigen location 36 | include(${CMAKE_CURRENT_SOURCE_DIR}/../3rd_party/FindEigen3.cmake) # call script to find eigen3 37 | #find_package(Eigen3 REQUIRED) # this works only for installation from package manager 38 | message(STATUS "eigen3 locatoin: ${EIGEN3_INCLUDE_DIR}") 39 | 40 | ################################ 41 | 42 | include_directories( 43 | ${OPENGL_INCLUDE_DIR} 44 | ${GLFW_INCLUDE_DIR} 45 | ${DELFEM2_INCLUDE_DIR} 46 | ${EIGEN3_INCLUDE_DIR} 47 | ) 48 | 49 | add_executable(${PROJECT_NAME} 50 | main.cpp 51 | ) 52 | 53 | target_link_libraries(${PROJECT_NAME} 54 | ${OPENGL_LIBRARY} 55 | ${GLFW_LIBRARIES} 56 | ) -------------------------------------------------------------------------------- /task0/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | // print out error 6 | static void error_callback(int error, const char* description) 7 | { 8 | fputs(description, stderr); 9 | } 10 | 11 | int main() 12 | { 13 | ::glfwSetErrorCallback(error_callback); 14 | if ( !glfwInit() ) { exit(EXIT_FAILURE); } 15 | ::glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2); 16 | ::glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1); 17 | // make window 18 | GLFWwindow* window = ::glfwCreateWindow( 19 | 640, 480, "task0: Build C++ Program with CMake", 20 | nullptr, nullptr); 21 | if (!window) { // exit if failed to create window 22 | ::glfwTerminate(); 23 | exit(EXIT_FAILURE); 24 | } 25 | ::glfwMakeContextCurrent(window); // working on this window 26 | while ( !::glfwWindowShouldClose(window) ) 27 | { 28 | // get windowsize 29 | int width, height; 30 | ::glfwGetFramebufferSize(window, &width, &height); 31 | // get aspect ratio of the window 32 | const float ratio = (float)width / (float) height; 33 | ::glViewport(0, 0, width, height); 34 | ::glClear(GL_COLOR_BUFFER_BIT); 35 | ::glMatrixMode(GL_PROJECTION); 36 | ::glLoadIdentity(); 37 | ::glOrtho(-ratio, ratio, -1.f, 1.f, -1.f, +1.f); 38 | ::glMatrixMode(GL_MODELVIEW); 39 | ::glLoadIdentity(); 40 | ::glRotatef((float) ::glfwGetTime() * 50.f, 0.f, 0.f, 1.f); 41 | ::glBegin(GL_TRIANGLES); 42 | ::glColor3f(1.f, 0.f, 0.f); 43 | ::glVertex3f(-0.6f, -0.4f, 0.f); 44 | ::glColor3f(0.f, 1.f, 0.f); 45 | ::glVertex3f(0.6f, -0.4f, 0.f); 46 | ::glColor3f(0.f, 0.f, 1.f); 47 | ::glVertex3f(0.f, 0.6f, 0.f); 48 | ::glEnd(); 49 | ::glfwSwapBuffers(window); 50 | ::glfwPollEvents(); 51 | } 52 | ::glfwDestroyWindow(window); 53 | ::glfwTerminate(); 54 | exit(EXIT_SUCCESS); 55 | } 56 | -------------------------------------------------------------------------------- /task7/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.12) 2 | 3 | enable_language(CXX) 4 | set(CMAKE_CXX_STANDARD 11) 5 | set(CMAKE_CXX_STANDARD_REQUIRED TRUE) 6 | IF(MSVC) 7 | set(CMAKE_CXX_FLAGS "/W4 -O2 \ 8 | /wd4100 /wd4458 /wd4577 /wd4267 /wd4244 /wd4505 /wd4838 \ 9 | /wd4800 /wd4996 /wd4530 /wd4245 /wd4505 /wd4505 /wd4456 ") 10 | ELSE() 11 | set(CMAKE_CXX_FLAGS "-Wall -Wno-deprecated-declarations -g") 12 | ENDIF() 13 | 14 | project(task7) 15 | 16 | add_definitions(-DPATH_SOURCE_DIR="${PROJECT_SOURCE_DIR}") 17 | 18 | ################################ 19 | 20 | # glfw 21 | SET(GLFW_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/../3rd_party/GLFW_Lib) 22 | include(${CMAKE_CURRENT_SOURCE_DIR}/../3rd_party/FindGLFW.cmake) 23 | 24 | # opengl 25 | find_package(OpenGL REQUIRED) 26 | 27 | # eigen 28 | FILE(GLOB EIGEN3_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/../3rd_party/eigen*) # find downloaded eigen directories in 3rd_party 29 | SET(EIGEN3_ROOT 30 | ${CMAKE_CURRENT_SOURCE_DIR}/../3rd_party/Eigen_Lib/include # installed eigen is higher priority 31 | ${EIGEN3_ROOT} ) # specify candidate for eigen location 32 | include(${CMAKE_CURRENT_SOURCE_DIR}/../3rd_party/FindEigen3.cmake) # call script to find eigen3 33 | #find_package(Eigen3 REQUIRED) # this works only for installation from package manager 34 | message(STATUS "eigen3 locatoin: ${EIGEN3_INCLUDE_DIR}") 35 | 36 | # delfem2 37 | add_definitions(-DDFM2_HEADER_ONLY=ON) 38 | set(DELFEM2_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../3rd_party/delfem2/include") 39 | 40 | ################################ 41 | 42 | include_directories( 43 | ${OPENGL_INCLUDE_DIR} 44 | ${GLFW_INCLUDE_DIR} 45 | ${DELFEM2_INCLUDE_DIR} 46 | ${EIGEN3_INCLUDE_DIR} 47 | ) 48 | 49 | add_executable(${PROJECT_NAME} 50 | main.cpp 51 | ) 52 | 53 | target_link_libraries(${PROJECT_NAME} 54 | ${OPENGL_LIBRARY} 55 | ${GLFW_LIBRARIES} 56 | ) -------------------------------------------------------------------------------- /task8/README.md: -------------------------------------------------------------------------------- 1 | # Task8: Variational Time Integration 2 | 3 | **Deadline: June 24th (Thursday) at 15:00pm** 4 | 5 | ![preview](preview.png) 6 | 7 | ## Setting Up 8 | 9 | Please take a look at the following document for environment setup, creating branch, and making pull request. 10 | 11 | - [How to Submit the Assignment](../doc/submit.md) 12 | 13 | In this assignment, it is necessary to install [Eigen](https://eigen.tuxfamily.org/index.php?title=Main_Page) library. Please follow the following document for setting up. 14 | 15 | - [How to set up the Eigen Library](../doc/setup_eigen.md) 16 | 17 | 18 | Additionally, you need the newest version of the library [DelFEM2](https://github.com/nobuyuki83/delfem2) in `pba-/3rd_party` . Please keep this library installed and updated by. 19 | 20 | ```bash 21 | $ cd pba- # go to the top of local repository 22 | $ git submodule update --init 3rd_party/delfem2 23 | ``` 24 | 25 | (DelFEM2 is a collection of useful C++ codes written by the instructer.) 26 | 27 | 28 | 29 | ## Problem1 30 | 31 | Build the program using `cmake`. Run the program and take a screenshot image of the window. Paste the screenshot image below by editing this mark down document: 32 | 33 | === paste screenshot here === 34 | 35 | 36 | 37 | 38 | 39 | ## Problem 2 40 | 41 | Currently the problem minimize the energy of a mass-spring system (see [task3)](../task3). Use the **variational implicit Euler scheme** [[16]](http://www.nobuyuki-umetani.com/scribble/variational_integration.pdf) to -change the static optimization into dynamic animation. Edit the function `AnimationByEnergyMinimization` from line 104 to 169. 42 | 43 | The following slide may be useful : 44 | 45 | ![slide0](slide0.png) 46 | 47 | ![slide1](slide1.png) 48 | 49 | 50 | 51 | Paste the screenshot image of the animation below: 52 | 53 | == paste screenshot image here== 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /doc/setup_glfw.md: -------------------------------------------------------------------------------- 1 | # How to Set Up GLFW Library 2 | 3 | 4 | 5 | Namely, you can set up GLFW in three ways 6 | 7 | - download `glfw` using package manager (for Mac and Ubuntu) 8 | - download pre-build library (Mac and Windows) 9 | - compile the GLFW source code by yourself 10 | 11 | Below, we discuss these options in detail 12 | 13 | ---- 14 | 15 | 16 | 17 | ## From Package Manager 18 | 19 | for Mac, install `glfw` using package manager `brew` as 20 | 21 | ```bash 22 | $ brew install glfw 23 | ``` 24 | For ubuntu, install `glfw` using `apt-get` as 25 | 26 | ```bash 27 | $ sudo apt-get install -y libx11-dev xorg-dev \ 28 | libglu1-mesa libglu1-mesa-dev \ 29 | libgl1-mesa-glx libgl1-mesa-dev 30 | $ sudo apt install -y libglfw3 libglfw3-dev 31 | $ sudo apt install -y libglew-dev 32 | ``` 33 | Unfortunately, for windows, there is not a easyway to install `glfw` with commands. 34 | 35 | --- 36 | 37 | 38 | 39 | ## Pre-Build Binary Library 40 | 41 | You can download the prebuild library from here 42 | 43 | https://www.glfw.org/download.html 44 | 45 | Extract the compressed file and rename it as `GLFW_Lib` and put it under the `3rd_party/` folder of the reository. 46 | 47 | Make sure you have a header file `glfw3.h` at 48 | 49 | ``` 50 | pba-/3rd_party/GLFW_Lib/include/GLFW/glfw3.h 51 | ``` 52 | 53 | 54 | 55 | 56 | 57 | --- 58 | 59 | 60 | ## Build from Source Code 61 | 62 | Alternatively, you can build `glfw` from source code and put the library under `3rd_party/GLFW_Lib` with 63 | 64 | ```bash 65 | $ mkdir 3rd_party/GLFW_Lib 66 | $ git submodule update --init 3rd_party/glfw 67 | $ cd 3rd_party/glfw 68 | $ cmake . 69 | $ cmake --build . --config Release 70 | $ cmake --install . --prefix ../GLFW_Lib 71 | ``` 72 | 73 | Make sure you have a header file `glfw3.h` at 74 | 75 | ``` 76 | pba-/3rd_party/GLFW_Lib/include/GLFW/glfw3.h 77 | ``` 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /task9/README.md: -------------------------------------------------------------------------------- 1 | # Task9: Shape Matching Deformation 2 | 3 | **Deadline: July 8th (Thursday) at 15:00pm** 4 | 5 | ![preview](preview.png) 6 | 7 | 8 | ## Setting Up 9 | 10 | Please look at the following document for environment setup, creating branch, and making pull request. 11 | 12 | - [How to Submit the Assignment](../doc/submit.md) 13 | 14 | In this assignment, it is necessary to install [Eigen](https://eigen.tuxfamily.org/index.php?title=Main_Page) library. Please follow the following document for setting up. 15 | 16 | - [How to set up the Eigen Library](../doc/setup_eigen.md) 17 | 18 | Additionally, you need the library [DelFEM2](https://github.com/nobuyuki83/delfem2) in `pba-/3rd_party` 19 | 20 | ```bash 21 | $ cd pba- # go to the top of local repository 22 | $ git submodule update --init 3rd_party/delfem2 23 | ``` 24 | 25 | (DelFEM2 is a collection of useful C++ codes written by the instructor.) 26 | 27 | 28 | 29 | ## Problem1 30 | 31 | Compile the `main.cpp` using the `CMakeLists.txt`, run the program and take a screenshot image. 32 | Paste the image below. 33 | 34 | === paste screenshot here === 35 | 36 | 37 | 38 | ## Problem 2 39 | 40 | Edit `main.cpp` to implement the 2D shape matching deformation [1]. 41 | The rectangular shape is represented by a quad mesh, and the bottom part of the rectangle is shaken horizontally. 42 | In the shape matching deformation, we need to fit each quad in the rest shape into the corresponding quad in the tentative shape by optimal rigid transformation. 43 | The edits should be necessary only around line #123. 44 | Paste the screenshot image of the program once it is finished. 45 | 46 | === paste screenshot here === 47 | 48 | 49 | ## Material 50 | 51 | The following slides may be useful 52 | 53 | ![](slide2.png) 54 | 55 | ![](slide0.png) 56 | 57 | ![](slide1.png) 58 | 59 | - [JacobiSVD module in Eigen](https://eigen.tuxfamily.org/dox/classEigen_1_1JacobiSVD.html) 60 | 61 | - [1] Matthias Müller, Bruno Heidelberger, Matthias Teschner, and Markus Gross. 2005. Meshless deformations based on shape matching. In ACM SIGGRAPH 2005 Papers (SIGGRAPH '05). 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | -------------------------------------------------------------------------------- /task7/README.md: -------------------------------------------------------------------------------- 1 | # Task7: Optimization of Rotation 2 | 3 | - **Deadline: June 17th (Thursday) at 15:00** 4 | 5 | ![preview](preview.png) 6 | 7 | 8 | ## Setting Up 9 | 10 | Pleae look at the following document for environment setup, creating branch, and making pull request. 11 | 12 | - [How to Submit the Assignment](../doc/submit.md) 13 | 14 | In this assignment, it is necessary to install [Eigen](https://eigen.tuxfamily.org/index.php?title=Main_Page) library. Please follow the following document for setting up. 15 | 16 | - [How to set up the Eigen Library](../doc/setup_eigen.md) 17 | 18 | Additionally, you need the library [DelFEM2](https://github.com/nobuyuki83/delfem2) installed and updated in `pba-/3rd_party` 19 | 20 | ```bash 21 | $ cd pba- # go to the top of local repository 22 | $ git submodule update --init 3rd_party/delfem2 23 | ``` 24 | 25 | (DelFEM2 is a collection of useful C++ codes written by the instructer.) 26 | 27 | 28 | 29 | ## Problem1 30 | 31 | Build the `main.cpp` using `cmake`. Run the program and take a screenshot image of the window. Paste the screenshot image below by editing this mark down document: 32 | 33 | === paste screenshot here === 34 | 35 | 36 | 37 | 38 | ## Problem 2 39 | 40 | Optimize the rotation matrix `R` such that the sum of squared distances between the rotated source points and fixed target points are minimized. Use the Netwon's method for the energy minimization. Write some code around line #71 in the `main.cpp` to compute the gradient and hessian of the energy of one pair of source and target points. (The modifications are probably very little, just two lines of short codes). **Once the implementation is successful, the energy should steadly decrease.** 41 | 42 | The following slides **may be** useful for this assignments: 43 | 44 | ![](slide_rotation0.png) 45 | 46 | ![](slide_rotation1.png) 47 | 48 | ![](slide_rotation2.png) 49 | 50 | 51 | 52 | Report the energy after convergence: 53 | 54 | - converged energy = ????? 55 | 56 | 57 | 58 | Paste the resulting screenshot image below: 59 | 60 | === paste screenshot image here === 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | ---- 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /doc/setup_env.md: -------------------------------------------------------------------------------- 1 | # How to Set Up C++ Programming Environment 2 | 3 | 4 | 5 | To do the assignment, it is necessary to set up the C++ programming environment. Namely, you need **Git** , **C++ Compiler** (of course!) and **cmake** installed in your computer. This document targets **MacOS**, **Ubuntu** and **Windows**. Depending on the versions of the OS, you may encounter some problems, but I encourage you to sove it by yourself first. These toos are very poupular and there are tons of information on the internet. If you solve the problem, let the instructer know on the slack the problem and solution together with the version of your OS. 6 | 7 | 8 | 9 | ## Git 10 | 11 | Git is ncessary to download and upload the assignments. Let's see if the `git` is already installed in your computer. Type the following command and see if the version of the `git` is shown. 12 | 13 | ```bash 14 | $ git --version 15 | ``` 16 | 17 | If `git` is not installed on your computer, read the following document to install 18 | 19 | https://git-scm.com/book/en/v2/Getting-Started-Installing-Git 20 | 21 | 22 | 23 | 24 | 25 | ## C++ Compilar 26 | 27 | For linux, type 28 | 29 | ```bash 30 | $ sudo apt-get install build-essential 31 | ``` 32 | 33 | 34 | 35 | For mac, install `Xcode` first. The Xcode is currently available at 36 | 37 | https://developer.apple.com/xcode/ 38 | 39 | Then, install command line tool with the following command: 40 | 41 | ```bash 42 | $ xcode-select --install 43 | ``` 44 | 45 | If the install is successful, following command backs the version of the C++ compilar 46 | 47 | ```bash 48 | $ clang --version 49 | ``` 50 | 51 | 52 | 53 | For windows, downlod Visual Studio from there (it's free for students) 54 | 55 | https://visualstudio.microsoft.com/vs/features/cplusplus/ 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | ## CMake 64 | 65 | CMake is used to *configure* the project i.e., making a project file to build the code based on the setting written in `CMakeLists.txt`. 66 | 67 | Type following commands to check if you have `cmake` or not in your compuer. 68 | 69 | ```bash 70 | $ cmake --version 71 | ``` 72 | 73 | If not, download the `cmake` from the link below and instal in your computer. 74 | 75 | https://cmake.org/download/ 76 | 77 | Alternatively, you can install `cmake` using a package manager such as `apt-get` for Ubuntu and `brew` for MacOS. 78 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /task3/README.md: -------------------------------------------------------------------------------- 1 | # Task3: Mass-spring System 2 | 3 | **Deadline: May 27th (Thursday) at 15:00pm** 4 | 5 | ![preview](preview.png) 6 | 7 | ## Setting Up 8 | 9 | Please take a look at the following document for environment setup, creating branch, and making pull request. 10 | 11 | - [How to Submit the Assignment](../doc/submit.md) 12 | 13 | In this assignment, it is necessary to install [Eigen](https://eigen.tuxfamily.org/index.php?title=Main_Page) library. 14 | Please follow the following document for setting up. 15 | 16 | - [How to set up the Eigen Library](../doc/setup_eigen.md) 17 | 18 | 19 | Additionally, you need the newest versio of the library [DelFEM2](https://github.com/nobuyuki83/delfem2) in `pba-/3rd_party` . Please keep this library installed and updated by. 20 | 21 | ```bash 22 | $ cd pba- # go to the top of local repository 23 | $ git submodule update --init 3rd_party/delfem2 24 | ``` 25 | 26 | (DelFEM2 is a collection of useful C++ codes written by the instructer.) 27 | 28 | 29 | 30 | ## Problem1 31 | 32 | Build the program using `cmake`. Run the program and take a screenshot image of the window. (You will probably see some *undesirable* animation and that's OK). Paste the screenshot image below by editing this mark down document: 33 | 34 | === paste screenshot here === 35 | 36 | 37 | 38 | 39 | 40 | ## Problem 2 41 | 42 | This program tries to solve the deformation of static mass-spring system by energy minimization using Netwon's method. However, unfortunately, the current implementation does not converge because the computation of the hessian of the spring's enegy is incomplete. 43 | 44 | - The springs energy can be written as `W=1/2(len-Len)*(len-Len) = 1/2C*C`, where `len` is current and `Len` is rest length and `C=(len-Len)`. 45 | - Gradient can be written as `dW=C*dC` that is already implemented 46 | - Hessian can be written as `ddW=dC*dC+C*ddC`. In the current code, `ddC`is not computed yes (set to zero) and thus the Newton's iteration does not converge. 47 | 48 | Fill the code around line #56 to compute the correct hessian of the energy (about 6-8 lines of simple codes). If the optimization works well, the energy should steadily decrease and converges within 10 iterations. 49 | 50 | Paste the screenshot image of converged deformation below: 51 | 52 | == paste screenshot image here== 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /task5/README.md: -------------------------------------------------------------------------------- 1 | # Task5: Solving Large Linear System 2 | 3 | - Gauss-Seidel Relaxation for unstructured mesh 4 | - **Deadline: June 3rd (Thursday) at 15:00** 5 | 6 | ![preview](preview.png) 7 | 8 | ## Setting Up 9 | 10 | Pleae look at the following document for environment setup, creating branch, and making pull request. 11 | 12 | [How to Submit the Assignment](../doc/submit.md) 13 | 14 | Additionally, you need the library [DelFEM2](https://github.com/nobuyuki83/delfem2) installed and updated in `pba-/3rd_party` 15 | 16 | ```bash 17 | $ cd pba- # go to the top of local repository 18 | $ git submodule update --init 3rd_party/delfem2 19 | ``` 20 | 21 | (DelFEM2 is a collection of useful C++ codes written by the instructer). 22 | 23 | 24 | 25 | ## Problem1 26 | 27 | Build the `main.cpp` using `cmake`. Run the program and take a screenshot image of the window. You will probably see some **highly distorted** mesh and that's OK. Paste the screenshot image below by editing this mark down document: 28 | 29 | === paste screenshot here === 30 | 31 | 32 | 33 | 34 | ## Problem 2 35 | 36 | Consider each edge of the mesh is a spring with zero rest length. In other words the spring's elastic potential energy is `E_i=1/2l_i^2`, where `l_i` is the distance between two end points of `i`-th spring. Write a program to minimize the sum of elastic potential energy `E=∑E_i`. 37 | 38 | The optimization has to be done using the **Gauss-Seidel(GS) method**. The GS method updates the coordinate of the point one-by-one. Let us denote `ip` is the point to be moved, and `jp` is the point surrounding `ip`. For each updates of GS method, the coordinate of `ip` is optimized and coordinates for `jp` is fixed. Use the fact the sum of squared distance between `ip` and `jp` is minimized when the `ip` is moved to the **gravity center** of `jp`. 39 | 40 | The one-ring neighbourhood of vertices are stored inside `Psup_Ind` and `Psup` in the format of **jagged array**. See the slides below for the detail of the format. 41 | 42 | ![jagged_array](jagged_array0.png) 43 | 44 | ![jagged_array](jagged_array1.png) 45 | 46 | 47 | Write some code around line #31 in the `main.cpp`. **Once the implementation is successful, the energy should steadly decrease.** Paste the resulting screenshot image below. 48 | 49 | === paste screenshot image here === 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | ---- 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /task11/README.md: -------------------------------------------------------------------------------- 1 | # Task11: Inertia Tensor 2 | 3 | **Deadline: July 1st (Thursday) at 15:00pm** 4 | 5 | ![preview](preview.png) 6 | 7 | ## Setting Up 8 | 9 | Please look at the following document for environment setup, creating branch, and making pull request. 10 | 11 | - [How to Submit the Assignment](../doc/submit.md) 12 | 13 | In this assignment, it is necessary to install [Eigen](https://eigen.tuxfamily.org/index.php?title=Main_Page) library. Please follow the following document for setting up. 14 | 15 | - [How to set up the Eigen Library](../doc/setup_eigen.md) 16 | 17 | Additionally, the library [DelFEM2](https://github.com/nobuyuki83/delfem2) must be in `pba-/3rd_party`. 18 | Type following commands to install and update the library. 19 | 20 | ```bash 21 | $ cd pba- # go to the top of local repository 22 | $ git submodule update --init 3rd_party/delfem2 23 | ``` 24 | 25 | (DelFEM2 is a collection of useful C++ codes written by the instructor.) 26 | 27 | 28 | 29 | ## 3D View control 30 | 31 | - Alt + Left mouse drag = rotation 32 | - Shift + Left mouse drag = translation 33 | - Mouse wheel = zoom in/out 34 | 35 | 36 | 37 | ## Problem1 38 | 39 | Build the program using `cmake`. 40 | Run the program and take a screenshot image of the window. Paste the screenshot image below by editing this mark down document: 41 | 42 | === paste screenshot here === 43 | 44 | 45 | ## Problem 2 46 | 47 | Edit `main.cpp` to compute the 3x3 inertia tensor of a 3D mesh. 48 | Note that **the mass is distributed only on the surface of the mesh** (i.e., the shape is hollow inside the mesh). 49 | **The areal mass density of the surface is one**. 50 | The edit is probably only necessary around line #59 adding few lines of codes. 51 | 52 | The inertia tensor should computed for the **rotation around the origin of the coordinate**. 53 | (the mesh is already translated such that the center of the mass is located at the origin). 54 | The line in red, blue and green are the principal axes of the inertia tensor. 55 | 56 | Write down the eigenvalues of the inertia tensor below (they will be shown in the standard output): 57 | - 1st eigenvalue: 58 | - 2nd eigenvalue: 59 | - 3rd eigenvalue: 60 | 61 | 62 | Paste the screenshot image below: 63 | 64 | === paste screenshot here === 65 | 66 | 67 | 68 | The following slides may be useful: 69 | 70 | ![](slide0.png) 71 | 72 | ![](slide1.png) 73 | 74 | ![](slide2.png) 75 | 76 | ![](slide3.png) 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /task6/README.md: -------------------------------------------------------------------------------- 1 | # Task6: Optimization with Constraints 2 | 3 | - Optimize Mesh with Lagrange Multiplier 4 | - **Deadline: June 10th (Thursday) at 15:00pm** 5 | 6 | ![preview](preview.png) 7 | 8 | ## Setting Up 9 | 10 | Pleae look at the following document for environment setup, creating branch, and making pull request. 11 | 12 | - [How to Submit the Assignment](../doc/submit.md) 13 | 14 | In this assignment, it is necessary to install [Eigen](https://eigen.tuxfamily.org/index.php?title=Main_Page) library. 15 | Please follow the following document for setting up. 16 | 17 | - [How to set up the Eigen Library](../doc/setup_eigen.md) 18 | 19 | Additionally, you need the library [DelFEM2](https://github.com/nobuyuki83/delfem2) installed and updated in `pba-/3rd_party` 20 | 21 | ```bash 22 | $ cd pba- # go to the top of local repository 23 | $ git submodule update --init 3rd_party/delfem2 24 | ``` 25 | 26 | (DelFEM2 is a collection of useful C++ codes written by the instructer.) 27 | 28 | 29 | 30 | ## Problem1 31 | 32 | Build the `main.cpp` using `cmake`. Run the program and take a screenshot image of the window. Paste the screenshot image below by editing this mark down document. 33 | 34 | === paste screenshot here === 35 | 36 | You will probably see a **highly distorted polygon shrinking **, but that's OK. 37 | 38 | 39 | ## Problem 2 40 | 41 | Optimize the positions of the vertices of a 2D polygon such that its **area becomes one and the sum of the squred length of the edges (i.e., energy) is minimized**. The Lagrange multiplier method needs to be used. See the slide below for the overview of Lagrange multiplier method and its implementation. 42 | 43 | ![](lagrange0.png) 44 | 45 | ![](lagrange1.png) 46 | 47 | 48 | 49 | In the visualization, the black points and line represent the polygon, the red lines represents the constaint gradient w.r.t vertex position, the blue lines represents the energy gradient w.r.t. vertex position. **Observe that two gradients are parallel at the optimized configuration**. 50 | 51 | **There are already working codes for energy minimization** (that's why polygon is shrinking), but the codes for areal constraint is not there yet. Write some codes around line #105 to add constraint with Lagrange multiplier metod. 52 | 53 | If the code working well, you will see that **the enrgy steadly deceases to the convergence** and **the area converges to one**. Paste the screenshot image below by editing this mark down document. 54 | 55 | === paste screenshot here === 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /task11/LICENSE.txt: -------------------------------------------------------------------------------- 1 | This directory contains 3D shape models from the AIM@SHAPE Shape Repository. 2 | 3 | Specifically, the file "FE_final.ply" is licensed under the AIM@SHAPE General License for Shapes, reproduced below. 4 | The files "FE_10k.off" and "FE_20k.off" are derivations of that file made by running a mesh decimation algorithm on the original file "FE_final.ply". As such, those files also fall under the AIM@SHAPE General License for Shapes. 5 | 6 | 7 | 8 | AIM@SHAPE General License for Shapes 9 | Applicable terms 10 | ---------------- 11 | 12 | This is the general AIM@SHAPE license applicable to models in the 13 | Shape Repository. It should be noted that each model is a 14 | representation of, and is distinct from, a shape, whether physical or 15 | imaginary. While the shape may be subject to its own terms, the terms 16 | governing the model you are about to download are described herein. 17 | 18 | For some models, the owners have defined specific licenses. The terms 19 | and conditions laid down in these licenses are in addition to the 20 | terms prescribed here, and are to be adhered to strictly when using 21 | such models. 22 | 23 | Acknowledgements 24 | ---------------- 25 | 26 | When including models from the Shape Repository in your website or 27 | research work, or when using them for other purposes allowed by the 28 | terms described herein, the AIM@SHAPE project and the model owner must 29 | be acknowledged as the sources of the models, for example with the 30 | phrase, "... model is provided courtesy of by the 31 | AIM@SHAPE Shape Repository." 32 | 33 | Information on is present in the accompanying metadata 34 | files and, where present, owner licenses. 35 | 36 | Metadata 37 | -------- 38 | 39 | Each model is accompanied by its metadata file. Please keep this file 40 | with the model as it contains important information about the 41 | model. Please let us know if you find any errors in the metadata. 42 | 43 | (Im)proper use 44 | -------------- 45 | 46 | Some models in the Shape Repository represent artifacts of religious, 47 | cultural and/or historical significance, e.g. the Max Planck 48 | model. Such models have been entrusted to the Shape Repository under 49 | the hope that they will be used respectfully and 50 | conscientiously. Please refrain from conducting experiments on them 51 | that may be rash or insensitive to people's feelings. Such experiments 52 | include, but are not limited to, morphing, animation, boolean 53 | operations, simulations of burning, breaking, exploding and melting. 54 | 55 | Models in the Shape Repository are made freely available for research 56 | and non-commercial purposes only. Use of these models for commercial 57 | purposes is permitted only after the express approval of the Shape 58 | Repository and the onwner has been obtained. Please contact us using 59 | the webform on our site in this regard. 60 | -------------------------------------------------------------------------------- /doc/setup_eigen.md: -------------------------------------------------------------------------------- 1 | # How to Set Up Eigen Library 2 | 3 | Namely, you can set up `Eigen` in three ways: 4 | 5 | - download `eigen` using a package manager (for Mac and Ubuntu) 6 | - download the repository (and configure if you want to optimize eigen) 7 | - clone the repository (and configure if you want to optimize eigen) 8 | 9 | Below, we discuss these options in detail 10 | 11 | ---- 12 | 13 | 14 | 15 | ## Install using a Package Manager 16 | 17 | for Mac, install `eigen` using the package manager `brew` as 18 | 19 | ```bash 20 | $ brew install eigen 21 | ``` 22 | For ubuntu, install `eigen` using `apt-get` as 23 | 24 | ```bash 25 | $ sudo apt-get install libeigen3-dev 26 | ``` 27 | Unfortunately, for windows, there is not a easyway to install `eigen` with commands. 28 | 29 | --- 30 | 31 | 32 | 33 | ## Download & Configure 34 | 35 | Download the repository from here 36 | 37 | http://eigen.tuxfamily.org/index.php?title=Main_Page#Download 38 | 39 | 1. Download the compressed file (e.g.,` eigen-3.*.*.zip`) and extract it. This result in a directory `eigen-3.*.*` 40 | 2. Put the extracted file under the `3rd_party` directory as `pba-/3rd_party/eigen-3.*.*` . 41 | 42 | Basically, you can stop here, but the `eigen` is not optimized for your environment. 43 | To configure the `eigen` library, type the commands below 44 | 45 | ```bash 46 | cd pba-/3rd_party/eigen-3.*.* # move to the directory 47 | mkdir build # make a new directory for "out-of-source build" 48 | cd build # move to the new directory 49 | cmake .. # configure (this may take one or two minutes) 50 | cmake --install . --prefix ../../Eigen_Lib # install eigen into the "Eigen_Lib" folder 51 | ``` 52 | 53 | Make sure you have a header file `Dense` at 54 | 55 | ``` 56 | pba-/3rd_party/Eigen_Lib/include/eigen3/Eigen/Dense 57 | ``` 58 | 59 | 60 | 61 | ## Clone & Configure 62 | 63 | Basically it is similar to the "Download & Configure" approach. 64 | The only difference is that instead of download we use submodule to clone the `Eigen` repository. 65 | 66 | ```bash 67 | $ git submodule update --init 3rd_party/eigen # clone the "eigen" repository (this may take one or two mins) 68 | ``` 69 | 70 | You can stop here, but the `eigen` is not optimized for your environment. 71 | To configure the `eigen` library, type the commands below 72 | ```bash 73 | $ cd 3rd_party/eigen # move to the eigen repository 74 | $ mkdir build # make a directory for "out-of-source build" 75 | $ cd build # move to the new directory 76 | $ cmake .. # configure (this may take one or two mins) 77 | $ cmake --install . --prefix ../../Eigen_Lib # install eigen into the "Eigen_Lib" folder 78 | ``` 79 | 80 | Make sure you have a header file `Dense` at 81 | 82 | ``` 83 | pba-/3rd_party/Eigen_Lib/include/eigen3/Eigen/Dense 84 | ``` 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | -------------------------------------------------------------------------------- /task0/README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Task0: Build C++ Program with CMake 4 | 5 | **Deadline: Apr.22th(Thu) at15:00pm** 6 | 7 | 8 | 9 | 10 | 11 | ![preview](task0_preview.png) 12 | 13 | Follow the instruction below to build the attached C++ code. This code will display an OpenGL window showing a triangle. Take a screenshot of the window (it should look like the image above) and paste it below. By putting the imae under the directory `pba-/task0` and edit this markdown document. 14 | 15 | === (paste the screenshot image here`![](image file name)` ) === 16 | 17 | 18 | 19 | ---- 20 | 21 | 22 | 23 | 24 | ## Instruction 25 | 26 | ### Set Up Programming Environment 27 | 28 | You need to have **git**, **cmake**, and **C++ compiler** in your computer to complete this assignement. Read the following document to install these. 29 | 30 | [How to Set Up C++ Programming Environment](../doc/setup_env.md) 31 | 32 | 33 | 34 | ### Go to Local Repository 35 | 36 | if you don't have the local repository, clone it from the remote repository 37 | 38 | ```bash 39 | $ git clone https://github.com/PBA-2021S/pba-.git 40 | ``` 41 | 42 | Go to the top of the local repository 43 | 44 | ```bash 45 | $ cd pba- # go to the local repository 46 | ``` 47 | 48 | 49 | 50 | ### Update Local Repository 51 | 52 | Please updat the local repository on your computer 53 | 54 | ```bash 55 | $ git checkout main # set main branch as the current branch 56 | $ git fetch origin main # download the main branch from remote repository 57 | $ git reset --hard origin/main # reset the local main branch same as remote repository 58 | ``` 59 | 60 | 61 | 62 | ### Set Up GLFW Library 63 | 64 | `GLFW` library is necessary to compile the code. Read the following document to set up the library under `pba-/3rd_party/` 65 | 66 | [How to Set Up GLFW Library](../doc/setup_glfw.md) 67 | 68 | 69 | 70 | ### Creating a Branch 71 | 72 | To do this assignement, you need to be in the branch `task0`. You can always check your the current branch by 73 | 74 | ```bash 75 | $ git branch -a # list all branches, showing the current branch 76 | ``` 77 | 78 | You are probably in the `main` branch. Let's create the `task0` branch and set it as the current branch. 79 | 80 | ```bash 81 | $ git branch task0 # create task0 branch 82 | $ git checkout task0 # switch into the task0 branch 83 | $ git branch -a # make sure you are in the task0 branch 84 | ``` 85 | 86 | 87 | 88 | ### Compile the Code and Edit This Document 89 | 90 | After the environment is ready, let's build and compile the code. We do **out-of-source** build by making a new directory for build `task0/build` and compile inside that directory 91 | ```bash 92 | $ cd task0 93 | $ mkdir build 94 | $ cd build 95 | $ cmake .. 96 | $ cmake --build . 97 | ``` 98 | Update this markdown document by editing `pba-/task0/README.md` .Please learn the syntax of the markdown document by yourself. 99 | 100 | 101 | 102 | ### Submit 103 | 104 | Finally, you submit the document by pushing to the `task0` branch of the remote repository. 105 | 106 | ```bash 107 | cd pba- # go to the top of the repository 108 | git status # check the changes 109 | git add . # stage the changes 110 | git status # check the staged changes 111 | git commit -m "task0 finished" # the comment can be anything 112 | git push --set-upstream origin task0 # up date the task0 branch of the remote repository 113 | ``` 114 | 115 | got to the GitHub webpage `https://github.com/PBA-2021S/pba-` . If everything looks good on this page, make a pull request. 116 | 117 | ![](../doc/pullrequest.png) 118 | 119 | 120 | 121 | ---- 122 | 123 | 124 | 125 | 126 | ## Trouble Shooting 127 | 128 | - I mistakenly submit the assignement in the `main` branch 129 | - Make a branch `task0` and submit again 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | -------------------------------------------------------------------------------- /3rd_party/FindEigen3.cmake: -------------------------------------------------------------------------------- 1 | # - Try to find Eigen3 lib 2 | # 3 | # This module supports requiring a minimum version, e.g. you can do 4 | # find_package(Eigen3 3.1.2) 5 | # to require version 3.1.2 or newer of Eigen3. 6 | # 7 | # Once done this will define 8 | # 9 | # EIGEN3_FOUND - system has eigen lib with correct version 10 | # EIGEN3_INCLUDE_DIR - the eigen include directory 11 | # EIGEN3_VERSION - eigen version 12 | # 13 | # and the following imported target: 14 | # 15 | # Eigen3::Eigen - The header-only Eigen library 16 | # 17 | # This module reads hints about search locations from 18 | # the following environment variables: 19 | # 20 | # EIGEN3_ROOT 21 | # EIGEN3_ROOT_DIR 22 | 23 | # Copyright (c) 2006, 2007 Montel Laurent, 24 | # Copyright (c) 2008, 2009 Gael Guennebaud, 25 | # Copyright (c) 2009 Benoit Jacob 26 | # Redistribution and use is allowed according to the terms of the 2-clause BSD license. 27 | 28 | if(NOT Eigen3_FIND_VERSION) 29 | if(NOT Eigen3_FIND_VERSION_MAJOR) 30 | set(Eigen3_FIND_VERSION_MAJOR 2) 31 | endif() 32 | if(NOT Eigen3_FIND_VERSION_MINOR) 33 | set(Eigen3_FIND_VERSION_MINOR 91) 34 | endif() 35 | if(NOT Eigen3_FIND_VERSION_PATCH) 36 | set(Eigen3_FIND_VERSION_PATCH 0) 37 | endif() 38 | 39 | set(Eigen3_FIND_VERSION "${Eigen3_FIND_VERSION_MAJOR}.${Eigen3_FIND_VERSION_MINOR}.${Eigen3_FIND_VERSION_PATCH}") 40 | endif() 41 | 42 | macro(_eigen3_check_version) 43 | file(READ "${EIGEN3_INCLUDE_DIR}/Eigen/src/Core/util/Macros.h" _eigen3_version_header) 44 | 45 | string(REGEX MATCH "define[ \t]+EIGEN_WORLD_VERSION[ \t]+([0-9]+)" _eigen3_world_version_match "${_eigen3_version_header}") 46 | set(EIGEN3_WORLD_VERSION "${CMAKE_MATCH_1}") 47 | string(REGEX MATCH "define[ \t]+EIGEN_MAJOR_VERSION[ \t]+([0-9]+)" _eigen3_major_version_match "${_eigen3_version_header}") 48 | set(EIGEN3_MAJOR_VERSION "${CMAKE_MATCH_1}") 49 | string(REGEX MATCH "define[ \t]+EIGEN_MINOR_VERSION[ \t]+([0-9]+)" _eigen3_minor_version_match "${_eigen3_version_header}") 50 | set(EIGEN3_MINOR_VERSION "${CMAKE_MATCH_1}") 51 | 52 | set(EIGEN3_VERSION ${EIGEN3_WORLD_VERSION}.${EIGEN3_MAJOR_VERSION}.${EIGEN3_MINOR_VERSION}) 53 | if(${EIGEN3_VERSION} VERSION_LESS ${Eigen3_FIND_VERSION}) 54 | set(EIGEN3_VERSION_OK FALSE) 55 | else() 56 | set(EIGEN3_VERSION_OK TRUE) 57 | endif() 58 | 59 | if(NOT EIGEN3_VERSION_OK) 60 | 61 | message(STATUS "Eigen3 version ${EIGEN3_VERSION} found in ${EIGEN3_INCLUDE_DIR}, " 62 | "but at least version ${Eigen3_FIND_VERSION} is required") 63 | endif() 64 | endmacro() 65 | 66 | if (EIGEN3_INCLUDE_DIR) 67 | 68 | # in cache already 69 | _eigen3_check_version() 70 | set(EIGEN3_FOUND ${EIGEN3_VERSION_OK}) 71 | set(Eigen3_FOUND ${EIGEN3_VERSION_OK}) 72 | 73 | else () 74 | 75 | # search first if an Eigen3Config.cmake is available in the system, 76 | # if successful this would set EIGEN3_INCLUDE_DIR and the rest of 77 | # the script will work as usual 78 | find_package(Eigen3 ${Eigen3_FIND_VERSION} NO_MODULE QUIET) 79 | 80 | if(NOT EIGEN3_INCLUDE_DIR) 81 | find_path(EIGEN3_INCLUDE_DIR NAMES signature_of_eigen3_matrix_library 82 | HINTS 83 | ENV EIGEN3_ROOT 84 | ENV EIGEN3_ROOT_DIR 85 | PATHS 86 | ${CMAKE_INSTALL_PREFIX}/include 87 | ${KDE4_INCLUDE_DIR} 88 | ${EIGEN3_ROOT} 89 | PATH_SUFFIXES eigen3 eigen 90 | ) 91 | endif() 92 | 93 | if(EIGEN3_INCLUDE_DIR) 94 | _eigen3_check_version() 95 | endif() 96 | 97 | include(FindPackageHandleStandardArgs) 98 | find_package_handle_standard_args(Eigen3 DEFAULT_MSG EIGEN3_INCLUDE_DIR EIGEN3_VERSION_OK) 99 | 100 | mark_as_advanced(EIGEN3_INCLUDE_DIR) 101 | 102 | endif() 103 | 104 | if(EIGEN3_FOUND AND NOT TARGET Eigen3::Eigen) 105 | add_library(Eigen3::Eigen INTERFACE IMPORTED) 106 | set_target_properties(Eigen3::Eigen PROPERTIES 107 | INTERFACE_INCLUDE_DIRECTORIES "${EIGEN3_INCLUDE_DIR}") 108 | endif() 109 | -------------------------------------------------------------------------------- /task1/main.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include "delfem2/glfw/viewer2.h" 4 | #include "delfem2/color.h" 5 | #include 6 | #include 7 | #include 8 | 9 | #ifndef M_PI 10 | #define M_PI 3.14159265358979323846 11 | #endif 12 | 13 | // print out error 14 | static void error_callback(int error, const char* description){ 15 | fputs(description, stderr); 16 | } 17 | 18 | class CParticle{ 19 | public: 20 | float pos[2] = {0.f, 0.f}; 21 | float velo[2] = {0.f, 0.f}; 22 | float color[3] = {0.f, 0.f, 0.f}; 23 | }; 24 | 25 | void draw( 26 | const std::vector& aParticle) 27 | { 28 | ::glLineWidth(2); 29 | 30 | // draw boundary 31 | ::glBegin(GL_LINE_LOOP); 32 | ::glColor3f(0.f, 0.f, 0.f); 33 | ::glVertex2f(0.f, 0.f); 34 | ::glVertex2f(1.f, 0.f); 35 | ::glVertex2f(1.f, 1.f); 36 | ::glVertex2f(0.f, 1.f); 37 | ::glEnd(); 38 | 39 | { // draw obstacle circle (center=(0.5,0.5) radius=0.2 ) 40 | ::glBegin(GL_LINE_LOOP); 41 | ::glColor3f(0.f, 0.f, 0.f); 42 | const unsigned int ndiv = 64; 43 | const float dr = 2.f*M_PI/ndiv; 44 | for(unsigned int idiv=0;idiv& aParticle, 64 | float dt) 65 | { 66 | for(auto & p : aParticle) { // loop for all the particles 67 | // update positions 68 | p.pos[0] += dt*p.velo[0]; 69 | p.pos[1] += dt*p.velo[1]; 70 | // ------------------------ 71 | // solve collisions below 72 | if( p.pos[0] < 0 ){ // left wall 73 | p.pos[0] = -p.pos[0]; 74 | p.velo[0] = -p.velo[0]; 75 | } 76 | if( p.pos[1] < 0 ){ // bottom wall 77 | p.pos[1] = -p.pos[1]; 78 | p.velo[1] = -p.velo[1]; 79 | } 80 | if( p.pos[0] > 1 ){ // left wall 81 | p.pos[0] = 2-p.pos[0]; 82 | p.velo[0] = -p.velo[0]; 83 | } 84 | if( p.pos[1] > 1 ){ // top wall 85 | p.pos[1] = 2-p.pos[1]; 86 | p.velo[1] = -p.velo[1]; 87 | } 88 | { // solve collision between obstacle circle 89 | float dx = p.pos[0]-0.5f; // x-coord from center 90 | float dy = p.pos[1]-0.5f; // y-coord from center 91 | float dist_from_center = sqrt(dx*dx+dy*dy); 92 | if( dist_from_center < 0.2 ){ // collision with obstacle 93 | float norm[2] = {dx/dist_from_center, dy/dist_from_center }; // unit normal vector of the circle 94 | float vnorm = p.velo[0]*norm[0] + p.velo[1]*norm[1]; // normal component of the velocity 95 | //////////////////////////// 96 | // write something below ! 97 | // p.velo[0] = 98 | // p.velo[1] = 99 | // p.pos[0] = 100 | // p.pos[1] = 101 | } 102 | } 103 | } 104 | } 105 | 106 | int main() 107 | { 108 | const unsigned int N = 50; // number of points 109 | const float dt = 0.01; 110 | std::vector aParticle; 111 | { // initialize particle 112 | std::mt19937 rndeng(std::random_device{}()); 113 | std::uniform_real_distribution dist01(0,1); 114 | aParticle.resize(N); 115 | for(auto & p : aParticle){ 116 | // set position 117 | p.pos[0] = dist01(rndeng); 118 | p.pos[1] = dist01(rndeng); 119 | // set color 120 | delfem2::GetRGB_HSV( 121 | p.color[0], p.color[1], p.color[2], 122 | dist01(rndeng), 1.f, 1.f); 123 | // set velocity 124 | p.velo[0] = dist01(rndeng)*2.f-1.f; 125 | p.velo[1] = dist01(rndeng)*2.f-1.f; 126 | const float lenvelo = sqrt(p.velo[0]*p.velo[0]+p.velo[1]*p.velo[1]); 127 | p.velo[0] /= lenvelo; 128 | p.velo[1] /= lenvelo; 129 | } 130 | } 131 | delfem2::glfw::CViewer2 viewer; 132 | { // specify view 133 | viewer.view_height = 1.0; 134 | viewer.trans[0] = -0.5; 135 | viewer.trans[1] = -0.5; 136 | viewer.title = "task1"; 137 | } 138 | glfwSetErrorCallback(error_callback); 139 | // ----------------------------------- 140 | // below: opengl starts from here 141 | if ( !glfwInit() ) { exit(EXIT_FAILURE); } 142 | glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2); 143 | glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1); 144 | viewer.InitGL(); 145 | 146 | while (!glfwWindowShouldClose(viewer.window)) 147 | { 148 | viewer.DrawBegin_oldGL(); 149 | simulate(aParticle,dt); 150 | draw(aParticle); 151 | viewer.SwapBuffers(); 152 | glfwPollEvents(); 153 | } 154 | glfwDestroyWindow(viewer.window); 155 | glfwTerminate(); 156 | exit(EXIT_SUCCESS); 157 | } 158 | -------------------------------------------------------------------------------- /doc/submit.md: -------------------------------------------------------------------------------- 1 | # How to Submit the Assignment 2 | 3 | There are many small programming assignments. These assignements needs to be submitted using **pull request** functionality of the GitHub. 4 | 5 | 6 | 7 | ## Making Your Repository using GitHub Classroom 8 | 9 | ![](../doc/githubclassroom.png) 10 | 11 | The assignments need to be submitted using "pullrequest" functionality of the GitHub. Using the system called "GitHub Classroom", each student makes his/her own private repository that is a copy of "https://github.com/PBA-2021S/pba". If a student has a GitHub account named ``, the name of the repository will be `pba-`. The private repository is only visible from the student and the instructor. In the second class, It will be shown how to make your own class repository using GitHub classroom. 12 | 13 | 14 | 15 | ## Overview 16 | 17 | ![](../doc/branchstructure.png) 18 | 19 | Let's assume you are looking at the repository `pba-` (e.g., pba-nobuyuki83) and the `task` is the assignment (e.g., task2). The submission is made by 20 | 21 | 1. create a branch of the name `task` 22 | 23 | 2. follow the instruction written in `\pba-/task/README.md` 24 | 25 | 3. push the repository with the branch `task` 26 | 27 | 4. make a pull request on GitHub page 28 | 29 | 5. Instructor will close the pull request after grading. 30 | 31 | 32 | 33 | ## Setup C++ Programming Environment 34 | 35 | First of all, you need to setup C++ Probramming environment (git, cmake, c++ compilar) 36 | 37 | - [How to Set Up C++ Programming Environment](../doc/setup_env.md) 38 | 39 | 40 | 41 | ## Download the Repository 42 | 43 | If you don't have the local repository in your computer, clone it from the remote repository 44 | 45 | ```bash 46 | $ git clone https://github.com/PBA-2021S/pba-.git 47 | ``` 48 | 49 | **Before doing each assignment**, Sync the local repository to the remote repository. 50 | 51 | ```bash 52 | $ cd pba- # go to the local repository 53 | $ git checkout main # set main branch as the current branch 54 | $ git fetch origin main # download the main branch from remote repository 55 | $ git reset --hard origin/main # reset the local main branch same as remote repository 56 | ``` 57 | 58 | 59 | 60 | ## Setup Libraries 61 | 62 | For all the assignement, we use GLFW Library for OpenGL visualization. Please take a look at the following document 63 | 64 | - [How to Set Up GLFW Library](../doc/setup_glfw.md) 65 | 66 | Some assignement use [Eigen](https://eigen.tuxfamily.org/index.php?title=Main_Page) library for matrix operation. Please follow the following document for setting up. 67 | 68 | - [How to set up the Eigen Library](../doc/setup_eigen.md) 69 | 70 | Additionally, for some assignements, [DelFEM2](https://github.com/nobuyuki83/delfem2) needs to be installed in `pba-/3rd_party` . DelFEM2 is a collection of useful C++ codes written by the instructer. Please install and updte this library with the following command. 71 | 72 | ```bash 73 | $ cd pba- # go to the top of local repository 74 | $ git submodule update --init 3rd_party/delfem2 75 | ``` 76 | 77 | 78 | 79 | ## Make Branch for Each Assignment 80 | 81 | Create the `task` branch and set it as the current branch. For `task1` the commands look like 82 | 83 | ```bash 84 | $ git branch task1 # create task1 branch 85 | $ git checkout task1 # switch into the task1 branch 86 | $ git branch -a # make sure you are in the task1 branch 87 | ``` 88 | 89 | Now, you are ready to edit the code and do the assignment! 90 | 91 | 92 | 93 | ## Do the Assignment 94 | 95 | Edit the code and this mark down document. 96 | 97 | 98 | 99 | ## Upload the Change 100 | 101 | After you finish editing, you submit the updates pushing to the `task` branch of the remote repository. For `task1` the command look like 102 | 103 | ```bash 104 | cd pba- # go to the top of the repository 105 | git branch -a # make sure again you are in the task1 branch 106 | git status # check the changes (typically few files are shown to be "updated") 107 | git add . # stage the changes 108 | git status # check the staged changes (typically few files re shown to be "staged") 109 | git commit -m "task1 finished" # the comment can be anything 110 | git push --set-upstream origin task1 # update the task1 branch of the remote repository 111 | ``` 112 | 113 | 114 | 115 | ## Make a Pull Request 116 | 117 | Go to the GitHub webpage `https://github.com/PBA-2021S/pba-` . If everything looks good on this page, make a pull request. 118 | 119 | ![](../doc/pullrequest.png) 120 | 121 | 122 | 123 | ## Trouble Shooting 124 | 125 | - I mistakenly submit the assignement in the `main` branch 126 | - Make a branch `task` and submit again 127 | - Many library files are shown when I type `git status` 128 | - add `pba-/.gitignore` the directory/files need to be ignored 129 | 130 | -------------------------------------------------------------------------------- /3rd_party/FindGLFW.cmake: -------------------------------------------------------------------------------- 1 | # GLFW_FOUND 2 | # GLFW_INCLUDE_DIR 3 | # GLFW_LIBRARIES 4 | # 5 | 6 | find_path (GLFW_INCLUDE_DIR 7 | NAMES 8 | GLFW/glfw3.h 9 | PATHS 10 | "${GLFW_ROOT}/include" 11 | /usr/X11R6/include 12 | /usr/include/X11 13 | /opt/graphics/OpenGL/include 14 | /opt/graphics/OpenGL/contrib/libglfw 15 | /usr/local/include 16 | /usr/include/GL 17 | /usr/include 18 | DOC 19 | "The directory where GL/glfw.h resides" 20 | ) 21 | 22 | if (WIN32) 23 | if (MSVC11 OR (${MSVC_VERSION} EQUAL 1700)) 24 | find_library (GLFW_LIBRARIES 25 | NAMES 26 | glfw3 27 | PATHS 28 | "${GLFW_ROOT}/lib" 29 | "${GLFW_ROOT}/lib-vc2012" 30 | DOCS 31 | "The GLFW library" 32 | ) 33 | elseif (MSVC12 OR (${MSVC_VERSION} EQUAL 1800)) 34 | find_library (GLFW_LIBRARIES 35 | NAMES 36 | glfw3 37 | PATHS 38 | "${GLFW_ROOT}/lib" 39 | "${GLFW_ROOT}/lib-vc2013" 40 | DOCS 41 | "The GLFW library" 42 | ) 43 | elseif (MSVC14 OR (${MSVC_VERSION} EQUAL 1900)) 44 | find_library (GLFW_LIBRARIES 45 | NAMES 46 | glfw3 47 | PATHS 48 | "${GLFW_ROOT}/lib" 49 | "${GLFW_ROOT}/lib-vc2015" 50 | DOCS 51 | "The GLFW library" 52 | ) 53 | elseif (MINGW) 54 | if (CMAKE_CL_64) 55 | find_library (GLFW_LIBRARIES 56 | NAMES 57 | glfw3 58 | PATHS 59 | "${GLFW_ROOT}/lib" 60 | "${GLFW_ROOT}/lib-mingw-w64" 61 | DOCS 62 | "The GLFW library" 63 | ) 64 | else () 65 | find_library (GLFW_LIBRARIES 66 | NAMES 67 | glfw3 68 | PATHS 69 | "${GLFW_ROOT}/lib" 70 | "${GLFW_ROOT}/lib-mingw" 71 | DOCS 72 | "The GLFW library" 73 | ) 74 | endif () 75 | else() 76 | find_library (GLFW_LIBRARIES 77 | NAMES 78 | glfw3 79 | PATHS 80 | "${GLFW_ROOT}/lib" 81 | DOCS 82 | "The GLFW library" 83 | ) 84 | endif() 85 | else () 86 | find_library (GLFW_LIBRARIES 87 | NAMES 88 | glfw 89 | glfw3 90 | PATHS 91 | "${GLFW_ROOT}/lib" 92 | "${GLFW_ROOT}/lib/x11" 93 | /usr/lib64 94 | /usr/lib 95 | /usr/lib/${CMAKE_LIBRARY_ARCHITECTURE} 96 | /usr/local/lib64 97 | /usr/local/lib 98 | /usr/local/lib/${CMAKE_LIBRARY_ARCHITECTURE} 99 | /usr/X11R6/lib 100 | DOCS 101 | "The GLFW library" 102 | ) 103 | if (APPLE) 104 | list (APPEND GLFW_LIBRARIES 105 | "-framework Cocoa" 106 | "-framework CoreVideo" 107 | "-framework IOKit" 108 | ) 109 | else () 110 | find_package(Threads REQUIRED) 111 | 112 | find_package(X11 REQUIRED) 113 | 114 | # Set up library and include paths 115 | list(APPEND GLFW_INCLUDE_DIR "${X11_X11_INCLUDE_PATH}") 116 | list(APPEND GLFW_LIBRARIES "${X11_X11_LIB}" "${CMAKE_THREAD_LIBS_INIT}" "${CMAKE_DL_LIBS}") 117 | 118 | # Check for XRandR (modern resolution switching and gamma control) 119 | if (NOT X11_Xrandr_FOUND) 120 | message(FATAL_ERROR "The RandR library and headers were not found") 121 | endif() 122 | 123 | list(APPEND GLFW_INCLUDE_DIR "${X11_Xrandr_INCLUDE_PATH}") 124 | list(APPEND GLFW_LIBRARIES "${X11_Xrandr_LIB}") 125 | 126 | # Check for Xinerama (legacy multi-monitor support) 127 | if (NOT X11_Xinerama_FOUND) 128 | message(FATAL_ERROR "The Xinerama library and headers were not found") 129 | endif() 130 | 131 | list(APPEND GLFW_INCLUDE_DIR "${X11_Xinerama_INCLUDE_PATH}") 132 | list(APPEND GLFW_LIBRARIES "${X11_Xinerama_LIB}") 133 | 134 | # Check for Xkb (X keyboard extension) 135 | if (NOT X11_Xkb_FOUND) 136 | message(FATAL_ERROR "The X keyboard extension headers were not found") 137 | endif() 138 | 139 | list(APPEND GLFW_INCLUDE_DIR "${X11_Xkb_INCLUDE_PATH}") 140 | 141 | # Check for Xcursor 142 | if (NOT X11_Xcursor_FOUND) 143 | message(FATAL_ERROR "The Xcursor libraries and headers were not found") 144 | endif() 145 | 146 | list(APPEND GLFW_INCLUDE_DIR "${X11_Xcursor_INCLUDE_PATH}") 147 | list(APPEND GLFW_LIBRARIES "${X11_Xcursor_LIB}") 148 | 149 | # Check for Xrandr 150 | if(NOT X11_Xrandr_FOUND) 151 | message(FATAL_ERROR "Xrandr library not found - required for GLFW") 152 | endif() 153 | 154 | list(APPEND GLFW_LIBRARIES "${X11_Xrandr_LIB}") 155 | 156 | # Check for xf86vmode 157 | if(NOT X11_xf86vmode_FOUND) 158 | message(FATAL_ERROR "xf86vmode library not found - required for GLFW") 159 | endif() 160 | 161 | list(APPEND GLFW_LIBRARIES "${X11_Xxf86vm_LIB}") 162 | 163 | endif () 164 | endif() 165 | 166 | include(FindPackageHandleStandardArgs) 167 | find_package_handle_standard_args(GLFW DEFAULT_MSG GLFW_LIBRARIES GLFW_INCLUDE_DIR) 168 | 169 | mark_as_advanced(GLFW_INCLUDE_DIR GLFW_LIBRARIES) 170 | -------------------------------------------------------------------------------- /task9/main.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "delfem2/glfw/viewer2.h" 3 | #include "delfem2/mshprimitive.h" 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | //#include 10 | 11 | /** 12 | * making 2D regular grid with edge length 1 13 | * @tparam REAL float or double 14 | * @param aXYZ list of points (XYXYXY...) 15 | * @param aQuad vertex index for quad mesh 16 | * @param nx nubmer of quads in x direction 17 | * @param ny number of quads in y direction 18 | */ 19 | template 20 | void MeshQuad2_Grid( 21 | std::vector& aXYZ, 22 | std::vector& aQuad, 23 | unsigned int nx, 24 | unsigned int ny) 25 | { 26 | unsigned int np = (nx+1)*(ny+1); 27 | aXYZ.resize(np*2); 28 | for(unsigned int iy=0;iy aXY; // coordinates 55 | std::vector aQuad; // index of points 56 | std::vector aMass; // point mass 57 | { // initialize mesh and point masses 58 | const unsigned int nx = 3; 59 | const unsigned int ny = 10; 60 | const float scale = 0.1; 61 | // make grid 62 | MeshQuad2_Grid( 63 | aXY, aQuad, 64 | 3, 10); 65 | // set mass 66 | aMass.resize(aXY.size() / 2, 1.f); 67 | for (unsigned int ixy = 0; ixy < aXY.size() / 2; ++ixy){ 68 | if( aXY[ixy*2+1] > 0.001 ){ continue; } 69 | aMass[ixy] = 10000.0; // mass at the boundary is very large to prevent moving during shape matching operation 70 | } 71 | for(unsigned int ixy=0;ixy aXY0 = aXY; // rest shape 77 | std::vector aUV(aXY.size(),0.0); // velocity 78 | std::vector aXYt(aXY.size(),0.0); // tentative shape 79 | float dt = 0.03; 80 | // --------- 81 | delfem2::glfw::CViewer2 viewer; 82 | { 83 | viewer.view_height = 1.0; 84 | viewer.title = "task9: Shape Matching Deformation"; 85 | } 86 | glfwSetErrorCallback(error_callback); 87 | if ( !glfwInit() ) { exit(EXIT_FAILURE); } 88 | glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2); 89 | glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1); 90 | // ------ 91 | viewer.InitGL(); 92 | 93 | while (!glfwWindowShouldClose(viewer.window)) 94 | { 95 | { // animation using Shape Matching Deformation [Müller et al. 2005] 96 | for(unsigned int ixy=0;ixy(aXYt.data()+aQuad[iq*4+0]*2), 110 | Eigen::Map(aXYt.data()+aQuad[iq*4+1]*2), 111 | Eigen::Map(aXYt.data()+aQuad[iq*4+2]*2), 112 | Eigen::Map(aXYt.data()+aQuad[iq*4+3]*2) }; 113 | const Eigen::Vector2f aq[4] = { // coordinates of quads' corner points (rest shape) 114 | Eigen::Map(aXY0.data()+aQuad[iq*4+0]*2), 115 | Eigen::Map(aXY0.data()+aQuad[iq*4+1]*2), 116 | Eigen::Map(aXY0.data()+aQuad[iq*4+2]*2), 117 | Eigen::Map(aXY0.data()+aQuad[iq*4+3]*2) }; 118 | const float am[4] = { // masses of the points 119 | aMass[aQuad[iq*4+0]], 120 | aMass[aQuad[iq*4+1]], 121 | aMass[aQuad[iq*4+2]], 122 | aMass[aQuad[iq*4+3]] }; 123 | // write some code below to rigidly transform the points in the rest shape (`aq`) such that the 124 | // weighted sum of squared distances against the points in the tentative shape (`qp`) is minimized (`am` is the weight). 125 | 126 | 127 | // no edits further down 128 | } 129 | for(unsigned int ixy=0;ixy 6 | #include 7 | #include 8 | #include 9 | 10 | /** 11 | * Optimize the position of the mesh to reduce the energy 12 | * energy is defined as the sum of squared lengths of the edges of the mesh 13 | * @param[in,out] aXY array of coordinates 14 | * @param[in] aPsupInd array of index for jagged array 15 | * @param[in] aPsup array of neighbouring index for jagged array 16 | * @param[in] aBCFlag if BCFlag is not 0, that point needs to be fixed. 17 | */ 18 | void GaussSeidelRelaxation( 19 | std::vector& aXY, 20 | const std::vector& aPsupInd, 21 | const std::vector& aPsup, 22 | const std::vector& aBCFlag) 23 | { 24 | const auto np = aXY.size() / 2; 25 | for (auto ip = 0; ip < np; ++ip) { // loop over all the point 26 | if( aBCFlag[ip] != 0 ){ continue; } 27 | const unsigned int nneighbour = aPsupInd[ip + 1] - aPsupInd[ip]; // number of points neighbouring ip 28 | if( nneighbour == 0 ){ continue; } 29 | double pos_new[2] = {0., 0.}; // new coordinate. Put it at the center of gravity of the neighbouring points 30 | for (auto ipsup = aPsupInd[ip]; ipsup < aPsupInd[ip + 1]; ++ipsup) { 31 | const unsigned int jp = aPsup[ipsup]; // index of point neighbouring ip 32 | // write something here 33 | // write something here 34 | } 35 | // write something here 36 | // un-comment below 37 | // aXY[ip*2+0] = pos_new[0]; // update the x-coordinate of ip 38 | // aXY[ip*2+1] = pos_new[1]; // update the y-coordinate of ip 39 | } 40 | } 41 | 42 | /** 43 | * Compute the energy that is defined as the sum of squared lengths of the edges of the mesh 44 | * @param[in] aXY array of coordinates 45 | * @param[in] aPsupInd array of index for jagged array 46 | * @param[in] aPsup array of neighbouring index for jagged array 47 | * @return energy 48 | */ 49 | double Energy( 50 | const std::vector& aXY, 51 | const std::vector& aPsupInd, 52 | const std::vector& aPsup) 53 | { 54 | const auto np = aXY.size() / 2; 55 | double W = 0.0; 56 | for (auto ip = 0; ip < np; ++ip) { 57 | const double* p0 = aXY.data()+ip*2; 58 | for (auto ipsup = aPsupInd[ip]; ipsup < aPsupInd[ip + 1]; ++ipsup) { 59 | const unsigned int jp = aPsup[ipsup]; 60 | const double* p1 = aXY.data()+jp*2; 61 | W += (p0[0]-p1[0])*(p0[0]-p1[0]) + (p0[1]-p1[1])*(p0[1]-p1[1]); 62 | } 63 | } 64 | return W; 65 | } 66 | 67 | void SettingUpSimulation( 68 | std::vector& aXY, 69 | std::vector& aPsupInd, 70 | std::vector& aPsup, 71 | std::vector& aBCFlag) 72 | { 73 | // generating mesh inside input polygon (aLoop) 74 | double Lx = 1; 75 | double Ly = 1; 76 | const std::vector< std::vector > aLoop = { {-Lx,-Ly, +Lx,-Ly, +Lx,+Ly, -Lx,+Ly} }; 77 | std::vector aPo2D; 78 | std::vector aETri; 79 | std::vector aVec2; 80 | delfem2::GenMesh( 81 | aPo2D, aETri, aVec2, 82 | aLoop, 0.03, 0.03); 83 | std::vector aTri; 84 | delfem2::CMeshTri2D( 85 | aXY, aTri, 86 | aVec2, aETri); 87 | delfem2::JArray_PSuP_MeshElem( 88 | aPsupInd,aPsup, 89 | aTri.data(), aTri.size()/3, 3, aXY.size()/2); 90 | // setting up boundry condition (fixing the both ends of the rectangle) 91 | aBCFlag.resize(aXY.size()/2,0); 92 | for(unsigned int ip=0;ip +Lx*0.99 95 | // || aXY[ip*2+1] < -Ly*0.99 96 | || aXY[ip*2+1] > +Ly*0.99 ) { 97 | aBCFlag[ip] = 1; 98 | } 99 | } 100 | } 101 | 102 | // ============================================= 103 | 104 | // print out error 105 | static void error_callback(int error, const char* description){ 106 | fputs(description, stderr); 107 | } 108 | 109 | void DrawMesh2_Psup( 110 | const std::vector &aXY, 111 | const std::vector& aPsupInd, 112 | const std::vector& aPsup) 113 | { 114 | glBegin(GL_LINES); 115 | const auto np = aXY.size()/2; 116 | for(auto ip=0;ip aXY; 129 | std::vector aPsupInd; 130 | std::vector aPsup; 131 | std::vector aBCFlag; 132 | SettingUpSimulation(aXY,aPsupInd,aPsup,aBCFlag); 133 | { 134 | std::mt19937 rndeng(std::random_device{}()); 135 | std::uniform_real_distribution dist_m1p1(-1.,+1.); 136 | for(auto ip=0;ip 4 | #include 5 | #include 6 | #include // for initial randome position & velocity 7 | #include // for sort 8 | #include // for stack 9 | 10 | #ifndef M_PI 11 | #define M_PI 3.14159265358979323846 12 | #endif 13 | 14 | // print out error 15 | static void error_callback(int error, const char* description){ 16 | fputs(description, stderr); 17 | } 18 | 19 | class CCircle{ 20 | public: 21 | float pos[2] = {0.f, 0.f}; 22 | float velo[2] = {0.f, 0.f}; 23 | bool is_collided = false; 24 | }; 25 | 26 | void draw( 27 | const std::vector& aCircle, 28 | float rad) 29 | { 30 | ::glLineWidth(2); 31 | 32 | // draw boundary 33 | ::glBegin(GL_LINE_LOOP); 34 | ::glColor3f(0.f, 0.f, 0.f); 35 | ::glVertex2f(0.f, 0.f); 36 | ::glVertex2f(1.f, 0.f); 37 | ::glVertex2f(1.f, 1.f); 38 | ::glVertex2f(0.f, 1.f); 39 | ::glEnd(); 40 | 41 | // draw circles 42 | const int ndiv = 64; 43 | const float dr = 2.f*M_PI/ndiv; 44 | ::glPointSize(10); 45 | for(const auto & circle : aCircle){ 46 | if( circle.is_collided ){ // if it is collided, color is red 47 | ::glColor3f(1.f, 0.f, 0.f); 48 | } 49 | else { 50 | ::glColor3f(0.f, 0.f, 0.f); 51 | } 52 | ::glBegin(GL_TRIANGLE_FAN); 53 | for(int idiv=0;idiv& aCircle, 64 | float rad, 65 | float dt) 66 | { 67 | for(auto & circle : aCircle) { 68 | circle.pos[0] += dt * circle.velo[0]; 69 | circle.pos[1] += dt * circle.velo[1]; 70 | if(circle.pos[0] < rad ){ // left wall 71 | circle.pos[0] = 2 * rad - circle.pos[0]; 72 | circle.velo[0] = -circle.velo[0]; 73 | } 74 | if(circle.pos[1] < rad ){ // bottom wall 75 | circle.pos[1] = 2 * rad - circle.pos[1]; 76 | circle.velo[1] = -circle.velo[1]; 77 | } 78 | if(circle.pos[0] > 1 - rad ){ // right wall 79 | circle.pos[0] = (1 - rad) * 2 - circle.pos[0]; 80 | circle.velo[0] = -circle.velo[0]; 81 | } 82 | if(circle.pos[1] > 1 - rad ){ // top wall 83 | circle.pos[1] = (1 - rad) * 2 - circle.pos[1]; 84 | circle.velo[1] = -circle.velo[1]; 85 | } 86 | } 87 | } 88 | 89 | struct CPosIndex { 90 | //! definition of the order between to CPosIndex structures 91 | bool operator < (const CPosIndex& rhs) const { 92 | return p < rhs.p; 93 | } 94 | float p; //! projected position 95 | bool is_start; //! true: enter false: exit 96 | unsigned int icircle; //! index of the circle 97 | }; 98 | 99 | /** 100 | * @return true if two circles are collided 101 | */ 102 | bool is_collide( 103 | const CCircle& c0, 104 | const CCircle& c1, 105 | float rad) 106 | { 107 | const float dx = c0.pos[0]-c1.pos[0]; 108 | const float dy = c0.pos[1]-c1.pos[1]; 109 | return 4 * rad * rad > dx * dx + dy * dy; 110 | } 111 | 112 | /** 113 | * 114 | * @param[in,out] aCircle array of particle 115 | * @param[in] rad radius of the circles 116 | */ 117 | void collision_detection( 118 | std::vector& aCircle, 119 | float rad) 120 | { 121 | // reset all the circle as "not collided" 122 | for(auto& c : aCircle){ c.is_collided = false; } 123 | std::vector aPosIndex; 124 | aPosIndex.reserve(aCircle.size()); 125 | for(unsigned int ic=0; ic < aCircle.size(); ++ic){ 126 | aPosIndex.push_back({aCircle[ic].pos[0] - rad, true, ic}); // enter 127 | aPosIndex.push_back({aCircle[ic].pos[0] + rad, false, ic}); // exit 128 | } 129 | std::sort(aPosIndex.begin(),aPosIndex.end()); // sort array by quick sort 130 | std::set stack; 131 | for(auto& pi : aPosIndex){ 132 | // std::cout << pi.p << " " << pi.is_start << " " << pi.icircle << std::endl; 133 | if( pi.is_start ){ // enter the range of the circle 134 | unsigned int ic0 = pi.icircle; 135 | // ---------------------------------------------- 136 | // write some codes here (probably 5 - 10 lines) 137 | // use the function "is_collide()" at line #102 138 | // ---------------------------------------------- 139 | stack.insert(ic0); 140 | } 141 | else{ // exit the range of the circle 142 | stack.erase(pi.icircle); 143 | } 144 | } 145 | } 146 | 147 | int main() 148 | { 149 | const unsigned int N = 40; // number of points 150 | const float rad = 0.03f; // radius of the circles 151 | const float dt = 1.f/60.f; // frame rate 152 | 153 | std::vector aCircle; 154 | 155 | { // initialize particle 156 | std::mt19937 rndeng(std::random_device{}()); 157 | std::uniform_real_distribution dist01(0,1); 158 | aCircle.resize(N); 159 | for(auto & p : aCircle){ 160 | // set position 161 | p.pos[0] = dist01(rndeng); 162 | p.pos[1] = dist01(rndeng); 163 | // set velocity 164 | p.velo[0] = dist01(rndeng)*2.f-1.f; 165 | p.velo[1] = dist01(rndeng)*2.f-1.f; 166 | const float lenvelo = sqrt(p.velo[0]*p.velo[0]+p.velo[1]*p.velo[1]); 167 | p.velo[0] = p.velo[0]/lenvelo*0.2f; 168 | p.velo[1] = p.velo[1]/lenvelo*0.2f; 169 | } 170 | } 171 | delfem2::glfw::CViewer2 viewer; 172 | { // set up viewer 173 | viewer.view_height = 0.75; 174 | viewer.trans[0] = -0.5; 175 | viewer.trans[1] = -0.5; 176 | viewer.title = "task4: Sort & Seep method"; 177 | } 178 | glfwSetErrorCallback(error_callback); 179 | if ( !glfwInit() ) { exit(EXIT_FAILURE); } 180 | // set legacy version of OpenGL 181 | glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2); 182 | glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1); 183 | // ------ 184 | viewer.InitGL(); 185 | 186 | double time_last_update = 0.; 187 | while (!glfwWindowShouldClose(viewer.window)) 188 | { 189 | // control of the frame rate 190 | const double time_now = glfwGetTime(); 191 | if(time_now - time_last_update < dt ){ 192 | glfwPollEvents(); 193 | continue; 194 | } 195 | time_last_update = time_now; 196 | // simulation 197 | move_circles(aCircle, rad, dt); 198 | collision_detection(aCircle,rad); 199 | // draw circles on the window 200 | viewer.DrawBegin_oldGL(); 201 | draw(aCircle,rad); 202 | viewer.SwapBuffers(); 203 | glfwPollEvents(); 204 | } 205 | glfwDestroyWindow(viewer.window); 206 | glfwTerminate(); 207 | exit(EXIT_SUCCESS); 208 | } 209 | -------------------------------------------------------------------------------- /task7/main.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "delfem2/glfw/viewer3.h" 3 | #include "delfem2/opengl/old/mshuni.h" // point surrounding point array generation 4 | #include "delfem2/opengl/old/funcs.h" 5 | #include "delfem2/mshuni.h" 6 | #include "delfem2/points.h" 7 | #include "delfem2/mshio.h" 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #ifndef M_PI 16 | #define M_PI 3.14159265359 17 | #endif 18 | 19 | /** 20 | * generating random points 21 | * @param[out] aPosSrc source points to be rotated 22 | * @param[out] aPosTrg target points fixed 23 | */ 24 | void InitializeProblem( 25 | std::vector& aPosSrc, 26 | std::vector& aPosTrg) 27 | { 28 | std::mt19937 rndeng(std::random_device{}()); 29 | std::uniform_real_distribution dist_m1p1(-1,+1); 30 | for (int i = 0; i < 100; ++i) { // make random points on the unit sphere 31 | const double p[3] = { dist_m1p1(rndeng), dist_m1p1(rndeng), dist_m1p1(rndeng) }; 32 | const double li0 = 1.0/sqrt(p[0]*p[0]+p[1]*p[1]+p[2]*p[2]); 33 | aPosSrc.push_back(p[0]*li0); 34 | aPosSrc.push_back(p[1]*li0); 35 | aPosSrc.push_back(p[2]*li0); 36 | } 37 | Eigen::Matrix3d R0; 38 | { // random rotation matrix 39 | R0 = Eigen::AngleAxis(dist_m1p1(rndeng) * M_PI, Eigen::Vector3d::UnitX()); 40 | R0 = R0 * Eigen::AngleAxis(dist_m1p1(rndeng) * M_PI, Eigen::Vector3d::UnitY()); 41 | R0 = R0 * Eigen::AngleAxis(dist_m1p1(rndeng) * M_PI, Eigen::Vector3d::UnitZ()); 42 | } 43 | for(unsigned int ip=0;ip(aPosSrc.data()+ip*3); 45 | const Eigen::Vector3d y = 2*R0*x; 46 | aPosTrg.push_back(y(0)); 47 | aPosTrg.push_back(y(1)); 48 | aPosTrg.push_back(y(2)); 49 | } 50 | } 51 | 52 | /** 53 | * energy ||Rp-q||^2 and its gradient and hessian 54 | * @param[out] W energy 55 | * @param[out] dW gradient of energy 56 | * @param[out] ddW hessian of energy 57 | * @param[in] p source point before rotation 58 | * @param[in] q target point 59 | * @param[in] R rotation 60 | */ 61 | void WdWddW_Rotation( 62 | double& W, 63 | Eigen::Vector3d& dW, 64 | Eigen::Matrix3d& ddW, 65 | const Eigen::Vector3d& p, 66 | const Eigen::Vector3d& q, 67 | const Eigen::Matrix3d& R) 68 | { 69 | const Eigen::Vector3d Rp = R*p; 70 | W = (Rp-q).squaredNorm(); 71 | // compute gradient and hessian of the energy below. 72 | // dW = 73 | // ddW = 74 | } 75 | 76 | /** 77 | * optimize the rotation matrix such that the sum of squared distance 78 | * between rotated source points and target points are minimized 79 | * @param[out] R rotation matrix 80 | * @param[in] aPosSrc source points 81 | * @param[in] aPosTrg target points 82 | */ 83 | void OptimizeRotation( 84 | Eigen::Matrix3d& R, 85 | const std::vector& aPosSrc, 86 | const std::vector& aPosTrg) 87 | { 88 | assert( aPosSrc.size() == aPosTrg.size() ); // the number of points should be the same 89 | assert( aPosSrc.size() % 3 == 0 ); 90 | double W = 0.; // total energy 91 | Eigen::Vector3d dW = Eigen::Vector3d::Zero(); // gradient of total energy 92 | Eigen::Matrix3d ddW = Eigen::Matrix3d::Zero(); // hessian of total energy 93 | for(unsigned int ip=0;ip(aPosSrc.data()+ip*3); // source point 95 | const Eigen::Vector3d q = Eigen::Map(aPosTrg.data()+ip*3); // target point 96 | double w0; 97 | Eigen::Vector3d dw0; dw0.setZero(); 98 | Eigen::Matrix3d ddw0; ddw0.setZero(); 99 | WdWddW_Rotation( 100 | w0,dw0,ddw0, 101 | p,q,R); 102 | W += w0; 103 | dW += dw0; 104 | ddW += ddw0; 105 | } 106 | ddW += 5.e+3*Eigen::Matrix3d::Identity(); // damp for animation 107 | std::cout << "total energy: " << W << std::endl; 108 | Eigen::Vector3d dt = (-ddW.inverse())*dW; // rotation vector for update computed by Newton method 109 | Eigen::Matrix3d dR; 110 | dR = Eigen::AngleAxis(dt.norm(), dt.normalized()); 111 | R = dR*R; // update rotation matrix 112 | } 113 | 114 | // ============================================= 115 | 116 | // print out error 117 | static void error_callback(int error, const char* description){ 118 | fputs(description, stderr); 119 | } 120 | 121 | void DrawProblem( 122 | const std::vector& aPosSrc, 123 | const std::vector& aPosTrg, 124 | const Eigen::Matrix3d& R) 125 | { 126 | ::glDisable(GL_LIGHTING); 127 | ::glPointSize(5); 128 | ::glBegin(GL_POINTS); 129 | glColor3f(1.f, 0.f, 0.f); 130 | for(unsigned int ip=0;ip(aPosSrc.data()+ip*3); 132 | ::glVertex3d(Rp(0), Rp(1), Rp(2)); 133 | } 134 | glColor3f(0.f, 0.f, 1.f); 135 | for(unsigned int ip=0;ip(aPosSrc.data()+ip*3); 143 | ::glVertex3d(Rp(0), Rp(1), Rp(2)); 144 | ::glVertex3d(aPosTrg[ip*3+0], aPosTrg[ip*3+1], aPosTrg[ip*3+2]); 145 | } 146 | ::glEnd(); 147 | } 148 | 149 | int main() 150 | { 151 | std::vector aPosSrc, aPosTrg; // source position and target position 152 | InitializeProblem(aPosSrc,aPosTrg); 153 | 154 | // rotatation matrix to be optimized 155 | Eigen::Matrix3d R = Eigen::Matrix3d::Identity(); 156 | // 157 | delfem2::glfw::CViewer3 viewer; 158 | viewer.camera.view_height = 2.0; 159 | // 160 | glfwSetErrorCallback(error_callback); 161 | if ( !glfwInit() ) { exit(EXIT_FAILURE); } 162 | glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2); // legacy OpenGL 163 | glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1); 164 | // ------ 165 | viewer.InitGL(); 166 | 167 | double time_last_update = 0.0; 168 | const double dt = 1.0/60.0; 169 | while (!glfwWindowShouldClose(viewer.window)) { 170 | { // frame rate control 171 | const double time_now = glfwGetTime(); 172 | if (time_now - time_last_update < dt) { 173 | glfwPollEvents(); 174 | continue; 175 | } 176 | time_last_update = time_now; 177 | } 178 | // 179 | OptimizeRotation( 180 | R, 181 | aPosSrc,aPosTrg); 182 | // 183 | viewer.DrawBegin_oldGL(); 184 | DrawProblem( 185 | aPosSrc,aPosTrg,R); 186 | viewer.SwapBuffers(); 187 | glfwPollEvents(); 188 | } 189 | glfwDestroyWindow(viewer.window); 190 | glfwTerminate(); 191 | exit(EXIT_SUCCESS); 192 | } 193 | -------------------------------------------------------------------------------- /task11/main.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "delfem2/glfw/viewer3.h" 3 | #include "delfem2/mshprimitive.h" 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | /** 12 | * mass and the center of gravity for 3D triangle mesh 13 | * @param[out] cg the center of gravity 14 | * @param[in] aXYZ 3D coordinates 15 | * @param[in] aTri triangle indexes 16 | * @return mass 17 | */ 18 | double MassCenterofgravity_MeshTri3( 19 | double cg[3], 20 | std::vector& aXYZ, 21 | std::vector& aTri) 22 | { // offset the center of the gravity 23 | Eigen::Vector3d ecg = Eigen::Vector3d::Zero(); 24 | double M = 0.; 25 | for(unsigned int it=0;it(aXYZ.data()+aTri[it*3+0]*3); 27 | const Eigen::Vector3d& p1 = Eigen::Map(aXYZ.data()+aTri[it*3+1]*3); 28 | const Eigen::Vector3d& p2 = Eigen::Map(aXYZ.data()+aTri[it*3+2]*3); 29 | double area = (p1-p0).cross(p2-p0).norm()/2; 30 | ecg += area*(p0+p1+p2)/3; 31 | M += area; 32 | } 33 | cg[0] = ecg(0) / M; 34 | cg[1] = ecg(1) / M; 35 | cg[2] = ecg(2) / M; 36 | return M; 37 | } 38 | 39 | /** 40 | * compute inertia tensor 41 | * @param[out] Imat 3x3 inertia tensor 42 | * @param[in] aXYZ 3D coordinates 43 | * @param[in] aTri triangle indices 44 | */ 45 | void InertiaTensor( 46 | Eigen::Matrix3d& Imat, 47 | std::vector& aXYZ, 48 | std::vector& aTri) 49 | { 50 | // zero clear Imat 51 | Imat = 1.0e-5*Eigen::Matrix3d::Identity(); // zero clear the tensor 52 | for(unsigned int it=0;it(aXYZ.data()+aTri[it*3+0]*3), 55 | Eigen::Map(aXYZ.data()+aTri[it*3+1]*3), 56 | Eigen::Map(aXYZ.data()+aTri[it*3+2]*3) 57 | }; 58 | const double area = (ap[1]-ap[0]).cross(ap[2]-ap[0]).norm()/2; // area of triangle 59 | // write some code below to compute inertia tensor 60 | } 61 | } 62 | 63 | /** 64 | * Read 3D mesh file in Alias *.Obj format 65 | * @tparam REAL float or double 66 | * @param[in] path_file path 67 | * @param[out] aXYZ 3D coordinates 68 | * @param[out] aTri triangle indices 69 | */ 70 | template 71 | void Read_Obj( 72 | const std::string& path_file, 73 | std::vector& aXYZ, 74 | std::vector& aTri) 75 | { 76 | std::ifstream fin; 77 | fin.open(path_file.c_str()); 78 | if (fin.fail()){ 79 | std::cout<<"File Read Fail"<> str >> x >> y >> z; 95 | } 96 | aXYZ.push_back(x); 97 | aXYZ.push_back(y); 98 | aXYZ.push_back(z); 99 | } 100 | if (buff[0]=='f'){ 101 | char str[256]; int i0, i1, i2; 102 | { 103 | std::istringstream is(buff); 104 | is >> str >> i0 >> i1 >> i2; 105 | } 106 | aTri.push_back(i0-1); 107 | aTri.push_back(i1-1); 108 | aTri.push_back(i2-1); 109 | } 110 | } 111 | } 112 | 113 | // print out error 114 | static void error_callback(int error, const char* description){ 115 | fputs(description, stderr); 116 | } 117 | 118 | int main() 119 | { 120 | std::vector aTri; 121 | std::vector aXYZ; 122 | Read_Obj( 123 | std::string(PATH_SOURCE)+"/fertility.obj", 124 | aXYZ,aTri); 125 | { // offset the center of gravity to the origin of the coordinate 126 | double cg[3]; 127 | double M = MassCenterofgravity_MeshTri3(cg,aXYZ,aTri); 128 | std::cout << "total mass: " << M << std::endl; 129 | std::cout << "center of gravity before offset: " << cg[0] << " " << cg[1] << " " << cg[2] << std::endl; 130 | for(unsigned int ip=0;ip es(Imat); 152 | std::cout << "eivenvalues of inertia tensor: " << es.eigenvalues().transpose() << std::endl; 153 | const Eigen::Vector3d ev0 = es.eigenvectors().col(0); 154 | const Eigen::Vector3d ev1 = es.eigenvectors().col(1); 155 | const Eigen::Vector3d ev2 = es.eigenvectors().col(2); 156 | 157 | delfem2::glfw::CViewer3 viewer; 158 | { 159 | viewer.camera.view_height = 100.0; 160 | viewer.camera.trans[0] = -0.5; 161 | viewer.camera.trans[1] = -0.5; 162 | } 163 | glfwSetErrorCallback(error_callback); 164 | if ( !glfwInit() ) { exit(EXIT_FAILURE); } 165 | glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2); 166 | glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1); 167 | // ------ 168 | viewer.InitGL(); 169 | 170 | while (!glfwWindowShouldClose(viewer.window)) 171 | { 172 | viewer.DrawBegin_oldGL(); 173 | ::glDisable(GL_LIGHTING); 174 | { 175 | ::glLineWidth(1); 176 | ::glColor3d(0, 0, 0); 177 | ::glBegin(GL_LINES); 178 | for (unsigned int itri = 0; itri < aTri.size() / 3; ++itri) { 179 | unsigned int i0 = aTri[itri * 3 + 0]; 180 | unsigned int i1 = aTri[itri * 3 + 1]; 181 | unsigned int i2 = aTri[itri * 3 + 2]; 182 | ::glVertex3dv(aXYZ.data() + i0 * 3); 183 | ::glVertex3dv(aXYZ.data() + i1 * 3); 184 | ::glVertex3dv(aXYZ.data() + i1 * 3); 185 | ::glVertex3dv(aXYZ.data() + i2 * 3); 186 | ::glVertex3dv(aXYZ.data() + i2 * 3); 187 | ::glVertex3dv(aXYZ.data() + i0 * 3); 188 | } 189 | ::glEnd(); 190 | // 191 | ::glLineWidth(3); 192 | const double len = 100; 193 | ::glBegin(GL_LINES); 194 | ::glColor3d(1, 0, 0); 195 | ::glVertex3d(+len*ev0.x(), +len*ev0.y(), +len*ev0.z()); 196 | ::glVertex3d(-len*ev0.x(), -len*ev0.y(), -len*ev0.z()); 197 | ::glColor3d(0, 1, 0); 198 | ::glVertex3d(+len*ev1.x(), +len*ev1.y(), +len*ev1.z()); 199 | ::glVertex3d(-len*ev1.x(), -len*ev1.y(), -len*ev1.z()); 200 | ::glColor3d(0, 0, 1); 201 | ::glVertex3d(+len*ev2.x(), +len*ev2.y(), +len*ev2.z()); 202 | ::glVertex3d(-len*ev2.x(), -len*ev2.y(), -len*ev2.z()); 203 | ::glEnd(); 204 | 205 | } 206 | viewer.SwapBuffers(); 207 | glfwPollEvents(); 208 | } 209 | glfwDestroyWindow(viewer.window); 210 | glfwTerminate(); 211 | exit(EXIT_SUCCESS); 212 | } 213 | -------------------------------------------------------------------------------- /task2/main.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "delfem2/glfw/viewer2.h" 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | // print out error 9 | static void error_callback(int error, const char* description){ 10 | fputs(description, stderr); 11 | } 12 | 13 | /** 14 | * compute inverse of 2x2 matrix 15 | * @tparam T floating point number (e.g, double or float) 16 | * @param[out] a_inv 2x2 invesed matrix 17 | * @param[in] a 2x2 matrix to be inversed 18 | */ 19 | template 20 | void inverse_matrix2( 21 | T a_inv[2][2], 22 | const T a[2][2]) 23 | { 24 | const T det_inv = 1/(a[0][0]*a[1][1] - a[0][1]*a[1][0]); 25 | a_inv[0][0] = +a[1][1]*det_inv; 26 | a_inv[0][1] = -a[0][1]*det_inv; 27 | a_inv[1][0] = -a[1][0]*det_inv; 28 | a_inv[1][1] = +a[0][0]*det_inv; 29 | } 30 | 31 | /** 32 | * compute matrix-vector product 33 | * @tparam nrow number of rows 34 | * @tparam ncol number of columns 35 | * @tparam T floating point number (e.g., float or double) 36 | * @param y left hand side vector 37 | * @param A matrix 38 | * @param x right hand side vector 39 | */ 40 | template 41 | void matrix_vector_product( 42 | T y[nrow], 43 | const T A[nrow][ncol], 44 | const T x[ncol]) 45 | { 46 | for(int i=0;i& aXY) 63 | { 64 | float W = 0.f; 65 | for(unsigned int ixy=0;ixy& aXY) 81 | { 82 | float gradW[2] = {0.f, 0.f}; // gradient of energy 83 | float hessW[2][2] = {{0.f, 0.f}, {0.f, 0.f}}; // hessian of energy 84 | // adding small value to diagonal for stabilization 85 | hessW[0][0] += 1.0e-10; 86 | hessW[1][1] += 1.0e-10; 87 | for(unsigned int ixy=0;ixy(upd,hessW_inv,gradW); 103 | // update positions 104 | pos[0] -= upd[0]; 105 | pos[1] -= upd[1]; 106 | } 107 | 108 | 109 | /** 110 | * optimize the location of input point based on stochastic optimization 111 | * @param[in,out] input point 112 | * @param[in] aXY XY-coordinates of sample points 113 | * @param dist distribution of the update to the next optimized point 114 | * @param randeng random number generator 115 | */ 116 | void optimization_random( 117 | float pos[2], 118 | const std::vector& aXY, 119 | std::normal_distribution& dist, 120 | std::mt19937& randeng) 121 | { 122 | const float W0 = energy(pos, aXY); // current energy 123 | const float pos_new[2] = { // suggestion for new position 124 | pos[0] + dist(randeng), 125 | pos[1] + dist(randeng), 126 | }; 127 | const float W1 = energy(pos_new, aXY); // new energy 128 | if( W1 < W0 ){ // take the suggestion to update position if it decrease the energy 129 | pos[0] = pos_new[0]; 130 | pos[1] = pos_new[1]; 131 | } 132 | } 133 | 134 | /** 135 | * draw input point and edges between sample points 136 | * @param[in] aXY sample points 137 | * @param[in] pos optimized point 138 | */ 139 | void draw_optimized_point( 140 | const std::vector& aXY, 141 | const float pos[2]) 142 | { 143 | ::glBegin(GL_POINTS); 144 | ::glPointSize(1); 145 | ::glVertex2fv(pos); 146 | ::glEnd(); 147 | // 148 | ::glBegin(GL_LINES); 149 | for(unsigned int ixy=0;ixy aXY; // sample points 161 | { // initialize positions 162 | const unsigned int N = 100; 163 | std::uniform_real_distribution dist01(0,1); 164 | aXY.resize(N*2); 165 | for(unsigned int ixy=0;ixy distN(0, 0.005); 202 | optimization_random( 203 | pos_optrand, 204 | aXY, 205 | distN, 206 | rndeng); 207 | } 208 | optimization_newton(pos_optnewton,aXY); 209 | // start draw 210 | viewer.DrawBegin_oldGL(); 211 | { // draw black sample points 212 | ::glColor3f(0.f, 0.f, 0.f); 213 | ::glPointSize(5); 214 | ::glBegin(GL_POINTS); 215 | for (unsigned int ixy = 0; ixy < aXY.size() / 2; ++ixy) { 216 | ::glVertex2fv(aXY.data() + ixy * 2); 217 | } 218 | ::glEnd(); 219 | } 220 | // draw point for random optimization (red) 221 | ::glLineWidth(1); 222 | ::glColor3f(1.f, 0.f, 0.f); // red color 223 | draw_optimized_point(aXY,pos_optrand); 224 | // draw point for Newton-Raphson optimization (blue) 225 | ::glLineWidth(2); 226 | ::glColor3f(0.f, 0.f, 1.f); 227 | draw_optimized_point(aXY,pos_optnewton); 228 | // end draw 229 | viewer.SwapBuffers(); 230 | glfwPollEvents(); 231 | } 232 | glfwDestroyWindow(viewer.window); 233 | glfwTerminate(); 234 | exit(EXIT_SUCCESS); 235 | } 236 | -------------------------------------------------------------------------------- /task3/main.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "delfem2/glfw/viewer2.h" 3 | #include "delfem2/dtri2_v2dtri.h" // triangle mesh generation 4 | #include "delfem2/mshuni.h" // line mesh from triangle mesh 5 | #include 6 | #include 7 | #include 8 | 9 | #include 10 | #include 11 | 12 | /** 13 | * compute distance between two points in 2D space 14 | * @tparam T 15 | * @param p0 16 | * @param p1 17 | * @return distancee 18 | */ 19 | template 20 | double distance2(const T* p0, const T* p1) 21 | { 22 | return sqrt( (p0[0]-p1[0])*(p0[0]-p1[0]) + (p0[1]-p1[1])*(p0[1]-p1[1]) ); 23 | } 24 | 25 | /** 26 | * Elastic potential energy of a spring and its gradient & hessian 27 | * @param[out] W elastic energy of a 2D spring 28 | * @param[out] dW differentiation of energy w.r.t. positions 29 | * @param[out] ddW 2nd-order differentiation of energy w.r.t. positions 30 | * @param[in] ap positions of the end points of an edge 31 | * @param[in] Len initial length of the spring 32 | * @param[in] stiffness stiffness of the spring 33 | */ 34 | DFM2_INLINE void WdWddW_Spring2( 35 | double& W, 36 | double dW[2][2], 37 | double ddW[2][2][2][2], 38 | const double ap[2][2], 39 | const double Len, 40 | double stiffness) 41 | { 42 | constexpr unsigned nnode = 2; 43 | constexpr unsigned ndim = 2; 44 | const double len = distance2(ap[0],ap[1]); // distance between p0 and p1 45 | const double u01[ndim] = { // unit direction vector from p0 to p1 46 | (ap[1][0] - ap[0][0]) / len, 47 | (ap[1][1] - ap[0][1]) / len }; 48 | const double C = (len-Len); // the length difference. 49 | const double dC[nnode][ndim] = { // gradient of C 50 | {-u01[0], -u01[1]}, 51 | {+u01[0], +u01[1]} }; 52 | double ddC[nnode][nnode][ndim][ndim]; // hessian of C 53 | std::fill_n(&ddC[0][0][0][0], nnode*nnode*ndim*ndim, 0.0); // currently ddC is zet to zero. 54 | for(unsigned int idim=0;idim& aXY, 98 | const std::vector& aXY0, 99 | const std::vector& aLine, 100 | double stiffness, 101 | double mass_point, 102 | const double gravity[2], 103 | const std::vector& aBCFlag) 104 | { // simulation 105 | const unsigned int np = aXY.size()/2; // number of points 106 | const unsigned int nDof = aXY.size(); // total degree of freedom 107 | Eigen::MatrixXd hessW(nDof,nDof); // hessian matrix 108 | Eigen::VectorXd gradW(nDof); // gradient vector 109 | hessW.setZero(); 110 | gradW.setZero(); 111 | double W = 0.0; 112 | for(int il=0;il lu(hessW); // LU decomposition 159 | Eigen::VectorXd update = lu.solve(gradW); // solve matrix 160 | // update position 161 | for(unsigned int ip=0;ip& aXY, 169 | std::vector& aLine, 170 | std::vector& aBCFlag) 171 | { 172 | // generating mesh inside input polygon (aLoop) 173 | const std::vector< std::vector > aLoop = { {-1,0, +1,0, +1,+0.3, -1,+0.3} }; 174 | std::vector aPo2D; 175 | std::vector aETri; 176 | std::vector aVec2; 177 | delfem2::GenMesh( 178 | aPo2D, aETri, aVec2, 179 | aLoop, 0.07, 0.07); 180 | std::vector aTri; 181 | delfem2::CMeshTri2D( 182 | aXY, aTri, 183 | aVec2, aETri); 184 | // convert triangle elements to line elements 185 | delfem2::MeshLine_MeshElem( 186 | aLine, 187 | aTri.data(),aTri.size()/3,delfem2::MESHELEM_TRI,aXY.size()/2); 188 | // setting up boundry condition (fixing the both ends of the rectangle) 189 | aBCFlag.resize(aXY.size(),0); 190 | for(unsigned int ip=0;ip +0.99 ){ // fix the both ends of rectangle 192 | aBCFlag[ip*2+0] = 1; 193 | aBCFlag[ip*2+1] = 1; 194 | } 195 | } 196 | } 197 | 198 | // ============================================= 199 | 200 | // print out error 201 | static void error_callback(int error, const char* description){ 202 | fputs(description, stderr); 203 | } 204 | 205 | void DrawMeshLine2( 206 | const std::vector& aXY, 207 | const std::vector& aLine) 208 | { 209 | glBegin(GL_LINES); 210 | for(unsigned int it=0;it aXY; 220 | std::vector aLine; 221 | std::vector aBCFlag; 222 | SettingUpSimulation(aXY,aLine,aBCFlag); 223 | const std::vector aXY0 = aXY; // initial position 224 | const double gravity[2] = {0., -10.0}; 225 | const double stiffness = 1.0e+4; 226 | const double mass_point = 1.0; 227 | // 228 | delfem2::glfw::CViewer2 viewer; 229 | { 230 | viewer.view_height = 1.0; 231 | viewer.title = "task3: Mass-spring System"; 232 | } 233 | glfwSetErrorCallback(error_callback); 234 | if ( !glfwInit() ) { exit(EXIT_FAILURE); } 235 | glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2); 236 | glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1); 237 | // ------ 238 | viewer.InitGL(); 239 | 240 | while (!glfwWindowShouldClose(viewer.window)) { 241 | EnergyMinimization( 242 | aXY, 243 | aXY0, aLine, stiffness, mass_point, gravity, aBCFlag); 244 | // 245 | viewer.DrawBegin_oldGL(); 246 | // initial configuration (red) 247 | glColor3f(1.f, 0.f, 0.f); 248 | DrawMeshLine2(aXY0,aLine); 249 | // deformed configuration (black) 250 | glColor3f(0.f, 0.f, 0.f); 251 | DrawMeshLine2(aXY,aLine); 252 | viewer.SwapBuffers(); 253 | glfwPollEvents(); 254 | } 255 | glfwDestroyWindow(viewer.window); 256 | glfwTerminate(); 257 | exit(EXIT_SUCCESS); 258 | } 259 | -------------------------------------------------------------------------------- /task8/main.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "delfem2/glfw/viewer2.h" 3 | #include "delfem2/dtri2_v2dtri.h" // triangle mesh generation 4 | #include "delfem2/mshuni.h" // line mesh from triangle mesh 5 | #include 6 | #include 7 | #include 8 | 9 | #include 10 | #include 11 | 12 | /** 13 | * compute distance between two points in 2D space 14 | * @tparam T 15 | * @param p0 16 | * @param p1 17 | * @return distancee 18 | */ 19 | template 20 | double distance2(const T* p0, const T* p1) 21 | { 22 | return sqrt( (p0[0]-p1[0])*(p0[0]-p1[0]) + (p0[1]-p1[1])*(p0[1]-p1[1]) ); 23 | } 24 | 25 | /** 26 | * Elastic potential energy of a spring and its gradient & hessian 27 | * @param[out] W elastic energy of a 2D spring 28 | * @param[out] dW differentiation of energy w.r.t. positions 29 | * @param[out] ddW 2nd-order differentiation of energy w.r.t. positions 30 | * @param[in] ap positions of the end points of an edge 31 | * @param[in] Len initial length of the spring 32 | * @param[in] stiffness stiffness of the spring 33 | */ 34 | DFM2_INLINE void WdWddW_Spring2( 35 | double& W, 36 | double dW[2][2], 37 | double ddW[2][2][2][2], 38 | const double ap[2][2], 39 | const double Len, 40 | double stiffness) 41 | { 42 | constexpr unsigned nnode = 2; 43 | constexpr unsigned ndim = 2; 44 | const double len = distance2(ap[0],ap[1]); // distance between p0 and p1 45 | const double u01[ndim] = { // unit direction vector from p0 to p1 46 | (ap[1][0] - ap[0][0]) / len, 47 | (ap[1][1] - ap[0][1]) / len }; 48 | const double C = (len-Len); // the length difference. 49 | const double dC[nnode][ndim] = { // gradient of C 50 | {-u01[0], -u01[1]}, 51 | {+u01[0], +u01[1]} }; 52 | double ddC[nnode][nnode][ndim][ndim]; // hessian of C 53 | std::fill_n(&ddC[0][0][0][0], nnode*nnode*ndim*ndim, 0.0); // currently ddC is zet to zero. 54 | for(unsigned int idim=0;idim& aXY, 96 | std::vector& aUV, 97 | const std::vector& aXY0, 98 | const std::vector& aLine, 99 | double dt, 100 | double stiffness, 101 | double mass_point, 102 | const double gravity[2], 103 | const std::vector& aBCFlag) 104 | { // simulation 105 | const unsigned int nDof = aXY.size(); // total degree of freedom 106 | const unsigned int np = nDof/2; // number of points 107 | // make tentative position aXYt = aXY + dt*aUV 108 | std::vector aXYt = aXY; 109 | for(unsigned int i=0;i lu(hessW); // LU decomposition 164 | Eigen::VectorXd update = lu.solve(gradW); // solve matrix 165 | // modify velocity and position update below. 166 | for(unsigned int i=0;i& aXY, 175 | std::vector& aLine, 176 | std::vector& aBCFlag) 177 | { 178 | // generating mesh inside input polygon (aLoop) 179 | const std::vector< std::vector > aLoop = { {-1,0, +1,0, +1,+0.3, -1,+0.3} }; 180 | std::vector aPo2D; 181 | std::vector aETri; 182 | std::vector aVec2; 183 | delfem2::GenMesh( 184 | aPo2D, aETri, aVec2, 185 | aLoop, 0.07, 0.07); 186 | std::vector aTri; 187 | delfem2::CMeshTri2D( 188 | aXY, aTri, 189 | aVec2, aETri); 190 | // convert triangle elements to line elements 191 | delfem2::MeshLine_MeshElem( 192 | aLine, 193 | aTri.data(),aTri.size()/3,delfem2::MESHELEM_TRI,aXY.size()/2); 194 | // setting up boundry condition (fixing the both ends of the rectangle) 195 | aBCFlag.resize(aXY.size(),0); 196 | for(unsigned int ip=0;ip +0.99 ){ // fix the both ends of rectangle 198 | aBCFlag[ip*2+0] = 1; 199 | aBCFlag[ip*2+1] = 1; 200 | } 201 | } 202 | } 203 | 204 | // ============================================= 205 | 206 | // print out error 207 | static void error_callback(int error, const char* description){ 208 | fputs(description, stderr); 209 | } 210 | 211 | void DrawMeshLine2( 212 | const std::vector& aXY, 213 | const std::vector& aLine) 214 | { 215 | glBegin(GL_LINES); 216 | for(unsigned int it=0;it aXY; 226 | std::vector aLine; 227 | std::vector aBCFlag; 228 | SettingUpSimulation(aXY,aLine,aBCFlag); 229 | const std::vector aXY0 = aXY; // initial position 230 | const double dt = 0.05; 231 | const double gravity[2] = {0., -1.0}; 232 | const double stiffness = 3.0e+3; 233 | const double mass_point = 10.0; 234 | std::vector aUV(aXY.size(),0.0); // velocity; 235 | // 236 | delfem2::glfw::CViewer2 viewer; 237 | { 238 | viewer.view_height = 1.0; 239 | viewer.title = "task8: variational implicit Euler integration"; 240 | } 241 | glfwSetErrorCallback(error_callback); 242 | if ( !glfwInit() ) { exit(EXIT_FAILURE); } 243 | glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2); 244 | glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1); 245 | // ------ 246 | viewer.InitGL(); 247 | 248 | while (!glfwWindowShouldClose(viewer.window)) { 249 | AnimationByEnergyMinimization( 250 | aXY,aUV, 251 | aXY0, aLine, 252 | dt, stiffness, mass_point, gravity, aBCFlag); 253 | // 254 | viewer.DrawBegin_oldGL(); 255 | // initial configuration (red) 256 | glColor3f(1.f, 0.f, 0.f); 257 | DrawMeshLine2(aXY0,aLine); 258 | // deformed configuration (black) 259 | glColor3f(0.f, 0.f, 0.f); 260 | DrawMeshLine2(aXY,aLine); 261 | viewer.SwapBuffers(); 262 | glfwPollEvents(); 263 | } 264 | glfwDestroyWindow(viewer.window); 265 | glfwTerminate(); 266 | exit(EXIT_SUCCESS); 267 | } 268 | -------------------------------------------------------------------------------- /task6/main.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "delfem2/glfw/viewer2.h" 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | /** 11 | * Area of the triangle connecting given two points and the origin, together with gradient and hessian of area. 12 | * @param[out] W area 13 | * @param[out] dW gradient of W. dW[inode][idim]: differentiation of W w.r.t. aP[inode][idim] 14 | * @param[out] ddW hessian of W. ddW[inode][jnode][idim][jdim]: differentiation of W w.r.t. aP[inode][idim] and aP[jnode][jdim] 15 | * @param[in] aP coordinates of two points. aP[inode][idim]: idim-th coordinate of inode-th point 16 | */ 17 | void WdWddW_Area2( 18 | double& W, 19 | double dW[2][2], 20 | double ddW[2][2][2][2], 21 | const double aP[2][2]) 22 | { 23 | W = 0.5*(aP[0][0] * aP[1][1] - aP[0][1] * aP[1][0]); 24 | dW[0][0] = +0.5 * aP[1][1]; 25 | dW[0][1] = -0.5 * aP[1][0]; 26 | dW[1][0] = -0.5 * aP[0][1]; 27 | dW[1][1] = +0.5 * aP[0][0]; 28 | std::fill_n(&ddW[0][0][0][0],2*2*2*2,0.0); 29 | ddW[0][1][0][1] = +0.5; 30 | ddW[0][1][1][0] = -0.5; 31 | ddW[1][0][0][1] = -0.5; 32 | ddW[1][0][1][0] = +0.5; 33 | } 34 | 35 | /** 36 | * Squared distance of the two points and its gradient and hessian 37 | * @param[out] W squared distance 38 | * @param[out] dW gradient of W. dW[inode][idim]: differentiation of W w.r.t. aP[inode][idim] 39 | * @param[out] ddW hessian of W. ddW[inode][jnode][idim][jdim]: differentiation of W w.r.t. aP[inode][idim] and aP[jnode][jdim] 40 | * @param[in] aP coordinates of two points. aP[inode][idim]: idim-th coordinate of inode-th point 41 | */ 42 | void WdWddW_SquaredDistance2( 43 | double& W, 44 | double dW[2][2], 45 | double ddW[2][2][2][2], 46 | const double aP[2][2]) 47 | { 48 | const double dx = aP[1][0] - aP[0][0]; 49 | const double dy = aP[1][1] - aP[0][1]; 50 | W = dx*dx+dy*dy; 51 | dW[0][0] = -dx; 52 | dW[0][1] = -dy; 53 | dW[1][0] = +dx; 54 | dW[1][1] = +dy; 55 | std::fill_n(&ddW[0][0][0][0],2*2*2*2,0.0); 56 | ddW[0][0][0][0] = +1; 57 | ddW[0][0][1][1] = +1; 58 | ddW[0][1][0][0] = -1; 59 | ddW[0][1][1][1] = -1; 60 | ddW[1][0][0][0] = -1; 61 | ddW[1][0][1][1] = -1; 62 | ddW[1][1][0][0] = +1; 63 | ddW[1][1][1][1] = +1; 64 | } 65 | 66 | 67 | /** 68 | * Optimize points to minimize the sum of squared distance of polygon edges while keeping the area of polygon 1 69 | * @param[in,out] aXY Coordinates of points of the polygon 70 | * @param[in,out] lambda lagrange multiplier 71 | * @param[in] damping damping factor to make animation slow enough to see 72 | */ 73 | void Optimize( 74 | std::vector& aXY, 75 | double& lambda, 76 | double damping) 77 | { 78 | const unsigned int np = aXY.size()/2; // number of points 79 | Eigen::MatrixXd matA(np*2+1,np*2+1); // coeff. matrix for coordinates and lagrange multiplier 80 | Eigen::VectorXd vecB(np*2+1); 81 | matA.setZero(); 82 | vecB.setZero(); 83 | double W_sum = 0.0; // sum of squared distance of edges 84 | double G_sum = 0.0; // area of polygon (sum of triangle areas) 85 | for(auto ie=0;ie lu(matA); 131 | Eigen::VectorXd vecX = lu.solve(vecB); 132 | 133 | std::cout << "square sum of distance: " << W_sum << " area of polygon: " << G_sum << std::endl; 134 | for(unsigned int ip=0;ip& aXY) 157 | { 158 | const unsigned int np = aXY.size()/2; 159 | ::glLineWidth(1); 160 | ::glBegin(GL_LINE_LOOP); 161 | ::glColor3f(0.f, 0.f, 0.f); 162 | for (int ixy = 0; ixy dWsum(np*2,0.0); 177 | for(auto ie=0;ie dGsum(np*2,0.0); 204 | for(auto ie=0;ie aXY; 234 | { // make random points 235 | std::mt19937 rndeng( std::random_device{}() ); 236 | std::uniform_real_distribution dist01(0,1); 237 | const unsigned int N = 20; 238 | aXY.resize(N*2); 239 | for(int i=0;i Apr. 5 | **Introduction**
| | | [[1]](http://www.nobuyuki-umetani.com/pba2021s/introduction.pdf), [[2]](http://www.nobuyuki-umetani.com/pba2021s/data_structure.pdf) | 51 | | (2)
Apr. 19 | **Data Structure**
data structure for simulation
Implicit surface | [task0](task0)
deadline: Apr.22th| | [[2]](http://www.nobuyuki-umetani.com/pba2021s/data_structure.pdf) | 52 | | (3)
Apr. 26 | **Time Integration**
Newtonian-mechanics
backward & forward Euler method,
particle system | [task1](task1)
deadline: Apr. 29th | | [[14]](http://www.nobuyuki-umetani.com/pba2021s/newtonian_mechanics.pdf), [[3]](http://www.nobuyuki-umetani.com/pba2021s/time_integration.pdf) | 53 | | (4)
Mar. 10 | **Broad-phase Collision Detection**
princepal component analysis
sort & sweep method
bounding volume hierarchy | [task4](task4)
deadline: May. 13th | | [[18]](http://www.nobuyuki-umetani.com/pba2021s/pca.pdf), [[5]](http://www.nobuyuki-umetani.com/pba2021s/collision_detection_broad.pdf) | 54 | | (5)
May. 17 | **Numerical Optimization**
Hessian & Jacobian,
Newton-Raphson method | [task2](task2)
deadline: May 20th | | [[19]](http://www.nobuyuki-umetani.com/pba2021s/optimization.pdf) | 55 | | (6)
May. 24 | **Simple Deformation Energy**
mass-spring system | [task3](task3)
deadline: May 27th | [[1]](http://www.nobuyuki-umetani.com/pba2021s/linsol_cg.pdf), [[2]](http://www.nobuyuki-umetani.com/pba2021s/linsol_cgprecond.pdf), [[3]](http://www.nobuyuki-umetani.com/pba2021s/linsol_ludecomp.pdf) | [[6]](http://www.nobuyuki-umetani.com/pba2021s/mass_spring_system.pdf) | 56 | | (7)
May. 31 | **Solving Large Linear System**
Sparse matrix data structure
Conjugate gradient method | [task5](task5)
deadline: June 3rd | | [[8]](http://www.nobuyuki-umetani.com/pba2021s/linear_system_solver.pdf),[[20]](http://www.nobuyuki-umetani.com/pba2021s/matrix_data_structure.pdf) | 57 | | (8)
Jun. 7 | **Optimization with Constraint**
Lagrange multiplier method
**Rigid Body Dynamics**
Rotation representation | [task6](task6)
deadline: June 10th | [[4]](http://www.nobuyuki-umetani.com/pba2021s/mech_rotation.pdf), [[5]](http://www.nobuyuki-umetani.com/pba2021s/mech_rigidbody.pdf) | [[9]](http://www.nobuyuki-umetani.com/pba2021s/optimization_with_constraints.pdf),[[21]](http://www.nobuyuki-umetani.com/pba2021s/rotation.pdf) | 58 | | (9)
Jun. 14 | **Rigid Body Dynamics2**
inertia tensor,
angular velocity
impulse based method | [task7](task7)
deadline: June 17th | | [[10]](http://www.nobuyuki-umetani.com/pba2021s/rigid_body_dynamics.pdf) | 59 | | (10)
Jun. 21 | Lagrangian mechanics
Variational time integration
**Continuum Mechanics**
tensor | [task8](task8)
deadline: June 24th | [[6]](http://www.nobuyuki-umetani.com/pba2021s/mech_fluidcontinuum.pdf), [[7]](http://www.nobuyuki-umetani.com/pba2021s/mech_fluidgoverning.pdf) | [[17]](http://www.nobuyuki-umetani.com/pba2021s/lagrangian_mechanics.pdf), [[16] ](http://www.nobuyuki-umetani.com/pba2021s/variational_integration.pdf) | 60 | | (11)
Jun. 28 | **Continuum Mechanics2**
Mesh interpolation
Tensor | [task11](task11)
deadline: July 1st | [[8]](http://www.nobuyuki-umetani.com/pba2021s/fem_outline.pdf), [[9]](http://www.nobuyuki-umetani.com/pba2021s/fem_linearsolid.pdf), [[10]](http://www.nobuyuki-umetani.com/pba2021s/fem_mitc3.pdf) | [[4]](http://www.nobuyuki-umetani.com/pba2021s/grid_mesh_interpolation.pdf), [[12]](http://www.nobuyuki-umetani.com/pba2021s/tensor.pdf) | 61 | | (12)
Jul. 5 | **Geometric Deformation**
singular value decomposition,
shape matching method,
linear blend skinning,
as-rigid-as possible deformation | [task9](task9)
deadline: July 8th | | [[22]](http://www.nobuyuki-umetani.com/pba2021s/geometric_deformation.pdf) | 62 | | (13)
Jul. 12 | **Advanced Interpolation**
mean value coordinate,
radial based function | | [[11]](http://www.nobuyuki-umetani.com/pba2021s/bem_laplace.pdf), [[12]](http://www.nobuyuki-umetani.com/pba2021s/bem_helmholtz.pdf) | [[23]](http://www.nobuyuki-umetani.com/pba2021s/advanced_interpolation.pdf) | 63 | 64 | 65 | ## Grading 66 | 67 | - 20% lecture attendance 68 | - Counted by attending the lecture, asking question, and making comments ...etc 69 | - Number of question counts: maximum 1 count for 1 lecture, ~~5~~ **2** counts for entire course 70 | - Attendance is counted based on writing a secret keyword on LMS. The keyword is announced for each lecture. 71 | - 80% small assignemnts 72 | - see below 73 | 74 | ## Assignemnts 75 | 76 | There are many small programming assignments. To do the assignments, you need to create your own copy of this repository through **GitHub Classroom**. These assignements needs to be submitted using **pull request** functionality of the GitHub. Look at the following document. 77 | 78 | [How to Submit the Assignments](doc/submit.md) 79 | 80 | ### Policy 81 | 82 | - Do the assignment by yourself. Don't share the assignments with others. 83 | - Don't post the answers of the assignment on Slack 84 | - Late submission of an assignment is subject to grade deduction 85 | - Score each assignemnt will not be open soon (instructer needs to adjust weight of the score later) 86 | 87 | ### Tasks 88 | 89 | - [task0](task0): Make C++ Program with CMake 90 | - [task1](task1): Particle System 91 | - [task2](task2): Optimization 92 | - [task3](task3): Mass-spring system 93 | - [task4](task4): Sort & Sweep Method 94 | - [task5](task5): Solving Large Linear System 95 | - [task6](task6): Optimization with Constraints 96 | - [task7](task7): Optimization of Rotation 97 | - [task8](task8): Variational Implicit Euler 98 | - [task9](task9): Shape Matching Method 99 | - [task11](task11): Inertia Tensor 100 | 101 | 102 | 103 | ## Slides 104 | 105 | - [[1] introduction](http://www.nobuyuki-umetani.com/pba2021s/introduction.pdf) 106 | - [[2] data_structure](http://www.nobuyuki-umetani.com/pba2021s/data_structure.pdf) 107 | - [[3] time_integration](http://www.nobuyuki-umetani.com/pba2021s/time_integration.pdf) 108 | - [[4] grid_mesh_interpolation](http://www.nobuyuki-umetani.com/pba2021s/grid_mesh_interpolation.pdf) 109 | - [[5] collision_detection_broad](http://www.nobuyuki-umetani.com/pba2021s/collision_detection_broad.pdf) 110 | - [[6] mass_spring_system](http://www.nobuyuki-umetani.com/pba2021s/mass_spring_system.pdf) 111 | - [[8] linear_system_solver](http://www.nobuyuki-umetani.com/pba2021s/linear_system_solver.pdf) 112 | - [[9] optimization with constraints](http://www.nobuyuki-umetani.com/pba2021s/optimization_with_constraints.pdf) 113 | - [[10] rigid_body_dynamics](http://www.nobuyuki-umetani.com/pba2021s/rigid_body_dynamics.pdf) 114 | - [[12] tensor](http://www.nobuyuki-umetani.com/pba2021s/tensor.pdf) 115 | - [[13] cpp language](http://www.nobuyuki-umetani.com/pba2021s/cpp.pdf) 116 | - [[14] newtonian mechanics](http://www.nobuyuki-umetani.com/pba2021s/newtonian_mechanics.pdf) 117 | - [[15] git+github](http://www.nobuyuki-umetani.com/pba2021s/git.pdf) 118 | - [[16] variational_integration](http://www.nobuyuki-umetani.com/pba2021s/variational_integration.pdf) 119 | - [[17] lagrangian_mechanics](http://www.nobuyuki-umetani.com/pba2021s/lagrangian_mechanics.pdf) 120 | - [[18] pca](http://www.nobuyuki-umetani.com/pba2021s/pca.pdf) 121 | - [[19] optimization](http://www.nobuyuki-umetani.com/pba2021s/optimization.pdf) 122 | - [[20] matrix_data_structure](http://www.nobuyuki-umetani.com/pba2021s/matrix_data_structure.pdf) 123 | - [[21] rotation representation](http://www.nobuyuki-umetani.com/pba2021s/rotation.pdf) 124 | - [[22]geometric_defmormation](http://www.nobuyuki-umetani.com/pba2021s/geometric_deformation.pdf) 125 | - [[23]advanced_interpolation](http://www.nobuyuki-umetani.com/pba2021s/advanced_interpolation.pdf) 126 | 127 | 128 | 129 | 130 | ## Reading Material 131 | 132 | - [Physically Based Modeling: Principles and Practice, Siggraph '97 Course notes by Dr. Baraff](http://www.cs.cmu.edu/~baraff/sigcourse/index.html) 133 | - [Physics-Based Animation by Kenny Erleben et al. (free textobook about rigid body dynamics)](https://iphys.wordpress.com/2020/01/12/free-textbook-physics-based-animation/) 134 | - [Dynamic Deformables: Implementation and Production Practicalities, SIGGRAPH 2020 Courses](http://www.tkim.graphics/DYNAMIC_DEFORMABLES/) 135 | - [Awesome Computer Graphics (GitHub)](https://github.com/luisnts/awesome-computer-graphics) 136 | - [Skinning: Real-time Shape Deformation SIGGRAPH 2014 Course](https://skinning.org/) 137 | 138 | --------------------------------------------------------------------------------