0:22~
1.デフォルトのキューブを削除する
2.[Shift+A]→[Mesh]→[UV Sphere]で球を作成する
3.Propotional Editing modeをonにして、UVSphereの上の頂点を下へ0.482(目分量)移動する。

0:50~
4.UVSphereの下の頂点を選択し、Ctrl+[Num +]で選択範囲を拡大し、Z=0.0以下の頂点を全て削除する

5.スムーズシェーディングに設定する

01:20~
1.[Shift+A]→[Mesh]→[Plane]でPlaneを追加
2.Editモードへ行き、X方向に0.253(目分量)まで縮小する
3.Editモードで2頂点選択し、Y方向に0.833 (目分量) 移動する
4.先の2頂点を今度はX方向に0.519 (目分量) 縮小する
5.反対側の2頂点を選択し、[E]で複製、[Y]でY方向に0.896(目分量)移動する
6.先の2頂点を0.813(目分量)縮小する
7.先の2頂点を[E]で複製し、Y方向に0.318移動する
8.先の2点を[S]でX方向に0.675縮小する。ただしこの時Proportional Editingをonにしているため、その手前の2点も若干縮小する
9. Proportional Editing をRootに設定し、先の2頂点をZ方向に約-0.404ぐらい移動する
10.中央の一番長いエッジを選択し、Z方向に約-0.066ぐらい移動する
03:00
11.Object Modeへ移動し、Solidifyモディファイアを追加する
12.続けて、そのすぐ下のSubdivision Surfaceを追加する
13.各モディファイアを以下のように設定
13.作った花弁を[D]でコピーする
14.太い方からエッジ三本を選択し、Y方向に-0.810移動する
15.同じ場所を[S]で0.734だけ縮小する。この時、 Proportional Editing がonかつRootのままなので、先頭のほうにも影響が出る。
16.中央の四角形部分だけを選択し、[S][X]でX方向だけに1.266だけ拡大する

17.一番右側のエッジを選択し、 [S]で0.339に縮小する(0.444倍→0.764 倍 なので0.444×0.764)
18. [Ctrl+E]→Edge Slideを選択し、Factor=-0.361だけ左にスライドする

19.上記エッジを[S]で1.511拡大する

20.上記エッジを[G]でY方向に0.099移動する

21.上記、小さい方の花弁のSubdivide SurfaceモディファイアのRenderとViewのパラメータを2に落とす
続く
Blender – Detailed Flower のチュートリアルを試す(1)
Blender – Detailed Flower のチュートリアルを試す(2)
Blender – Detailed Flower のチュートリアルを試す(3)
この二つは行列が単純すぎて別記事にする気にならないのでまとめてやる。
namespace nu { typedef float real_t; inline real_t to_radian(real_t degree) { return degree * (real_t)3.14159265358979 / (real_t)180.0; } void mytranslate( real_t* m, real_t x, real_t y, real_t z ) { m[0] = 1.0; m[1] = 0.0; m[2] = 0.0; m[3] = 0.0; m[4] = 0.0; m[5] = 1.0; m[6] = 0.0; m[7] = 0.0; m[8] = 0.0; m[9] = 0.0; m[10] = 1.0; m[11] = 0.0; m[12] = x; m[13] = y; m[14] = z; m[15] = 1.0; } void myscale( real_t* m, real_t sx, real_t sy, real_t sz ) { m[0] = sx; m[1] = 0.0; m[2] = 0.0; m[3] = 0.0; m[4] = 0.0; m[5] = sy; m[6] = 0.0; m[7] = 0.0; m[8] = 0.0; m[9] = 0.0; m[10] = sz; m[11] = 0.0; m[12] = 0.0; m[13] = 0.0; m[14] = 0.0; m[15] = 1.0; } }
#include <windows.h> #include <gl/GLU.h> #include <gl/freeglut.h> #include <cstdio> #include <cmath> //検証用 #include <cassert> //自前実装版glTranslate* / glScale* #include "mytranslatescale.h" #pragma comment(lib,"opengl32.lib") #pragma comment(lib,"glu32.lib") #pragma comment(lib,"freeglut.lib") void display(void) { GLfloat glmat[16]; //gl関数で生成 GLfloat mymat[16]; //自分関数で生成 //gltranslate,mytranslateへの入力の値を色々変える static int i = 0; i++; GLfloat x = 1.0+i; GLfloat y = 1.0 * (i * 0.1); GLfloat z = 1.0 * (i / 0.2); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); //openglで計算 glTranslatef( x, y, z); glGetFloatv(GL_MODELVIEW_MATRIX, glmat); //自前計算 nu::mytranslate(mymat,x,y,z); puts("----------------------------------------------"); printf("** %d :: %lf %lf %lf\n", i,x,y,z); for (int k = 0; k < 16; k++) { //比較 printf("m[%2d] %+5.10lf %+5.10lf \n", k, glmat[k], mymat[k]); //自前計算とgltranslate計算の値があまりにかけ離れていたらassertで落ちる assert(std::abs(glmat[k] - mymat[k]) < 0.0001); } puts("----------------------------------------------"); } void mouse(int button, int state, int x, int y) { display(); } int main(int argc, char* argv[]) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_RGBA); glutCreateWindow(argv[0]); glutInitWindowPosition(0, 0); glutInitWindowSize(100,100); glutDisplayFunc(display); glutMouseFunc(mouse); glutMainLoop(); return 0; }
#include <windows.h> #include <gl/GLU.h> #include <gl/freeglut.h> #include <cstdio> #include <cmath> //検証用 #include <cassert> //自前実装版glTranslate* / glScale* #include "mytranslatescale.h" #pragma comment(lib,"opengl32.lib") #pragma comment(lib,"glu32.lib") #pragma comment(lib,"freeglut.lib") void display(void) { GLfloat glmat[16]; //gl関数で生成 GLfloat mymat[16]; //自分関数で生成 //glscalef,myscaleへの入力の値を色々変える static int i = 0; i++; GLfloat x = 1.0+i; GLfloat y = 1.0 * (i * 0.1); GLfloat z = 1.0 * (i / 0.2); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); //openglで計算 glScalef( x, y, z); glGetFloatv(GL_MODELVIEW_MATRIX, glmat); //自前計算 nu::myscale(mymat,x,y,z); puts("----------------------------------------------"); printf("** %d :: %lf %lf %lf\n", i,x,y,z); for (int k = 0; k < 16; k++) { //比較 printf("m[%2d] %+5.10lf %+5.10lf \n", k, glmat[k], mymat[k]); //自前計算とglScalef計算の値があまりにかけ離れていたらassertで落ちる assert(std::abs(glmat[k] - mymat[k]) < 0.0001); } puts("----------------------------------------------"); } void mouse(int button, int state, int x, int y) { display(); } int main(int argc, char* argv[]) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_RGBA); glutCreateWindow(argv[0]); glutInitWindowPosition(0, 0); glutInitWindowSize(100,100); glutDisplayFunc(display); glutMouseFunc(mouse); glutMainLoop(); return 0; }


#include <cmath> namespace nu { typedef float real_t; inline real_t to_radian(real_t degree) { return degree * (real_t)3.14159265358979 / (real_t)180.0; } //! @brief 回転行列作成 //! @param [out] m 結果を格納する要素数16の配列 //! @param [in] angle_degree 回転角を度で指定 //! @param [in] x 回転軸のX成分 //! @param [in] y 回転軸のY成分 //! @param [in] z 回転軸のZ成分 //! @return なし void myrotate( real_t* m, real_t angle_degree, real_t x, real_t y, real_t z) { //len(x y z) != 0ならnormalizeする real_t len = sqrt(x * x + y * y + z * z); if (abs(1.0 - len) > 0.000001) { x = x / len; y = y / len; z = z / len; } real_t angle_rad = to_radian(angle_degree); real_t c = std::cos(angle_rad); real_t s = std::sin(angle_rad); m[0] = x * x * (1 - c) + c; m[1] = y * x * (1 - c) + z * s; m[2] = x * z * (1 - c) - y * s; m[3] = 0.0; m[4] = x * y * (1 - c) - z * s; m[5] = y * y * (1 - c) + c; m[6] = y * z * (1 - c) + x * s; m[7] = 0.0; m[8] = x * z * (1 - c) + y * s; m[9] = y * z * (1 - c) - x * s; m[10] = z * z * (1 - c) + c; m[11] = 0.0; m[12] = 0.0; m[13] = 0.0; m[14] = 0.0; m[15] = 1.0; } }
#include <windows.h> #include <gl/GLU.h> #include <gl/freeglut.h> #include <cstdio> //検証用 #include <cassert> //自前実装版glRotate #include "myrotate.h" #pragma comment(lib,"opengl32.lib") #pragma comment(lib,"glu32.lib") #pragma comment(lib,"freeglut.lib") void display(void) { GLfloat glrmat[16]; //gl関数で生成 GLfloat myrmat[16]; //自分関数で生成 //glRotate,myrotateへの入力の値を色々変える static int i = 0; i++; GLfloat x = 1.0+i; GLfloat y = 1.0 * (i * 0.1); GLfloat z = 1.0 * (i / 0.2); GLfloat angle=i+25; glMatrixMode(GL_MODELVIEW); glLoadIdentity(); //openglで計算 glRotatef(angle, x, y, z); glGetFloatv(GL_MODELVIEW_MATRIX, glrmat); //自前計算 nu::myrotate(myrmat,angle,x,y,z); puts("----------------------------------------------"); printf("** %d :: %lf %lf %lf %lf\n", i,angle,x,y,z); for (int k = 0; k < 16; k++) { //比較 printf("m[%2d] %+5.10lf %+5.10lf \n", k, glrmat[k], myrmat[k]); //自前計算とglRotate計算の値があまりにかけ離れていたらassertで落ちる assert(abs(glrmat[k] - myrmat[k]) < 0.0001); } puts("----------------------------------------------"); } void mouse(int button, int state, int x, int y) { display(); } int main(int argc, char* argv[]) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_RGBA); glutCreateWindow(argv[0]); glutInitWindowPosition(0, 0); glutInitWindowSize(100,100); glutDisplayFunc(display); glutMouseFunc(mouse); glutMainLoop(); return 0; }

#include <cmath> namespace nu { typedef float real_t; //! @brief 平行投影行列を作成する //! @param [out] m 作成した行列を格納する要素数16の配列 //! @return なし inline void myortho( real_t* m, real_t left, real_t right, real_t bottom, real_t top, real_t znear, real_t zfar) { real_t tx = -(right + left) / (right - left); real_t ty = -(top + bottom) / (top - bottom); real_t tz = -(zfar + znear) / (zfar - znear); //infが出たときは単位行列を返す模様 if (std::isinf(tx) || std::isinf(ty) || std::isinf(tz)) { m[0] = m[5] = m[10] = m[15] = (real_t)1.0; m[1] = m[2] = m[3] = m[4] = m[6] = m[7] = m[8] = m[9] = m[11] = (real_t)0.0; m[12] = m[13] = m[14] = (real_t)0.0; return; } m[0] = (real_t)2.0 / (right - left); m[1] = 0.0; m[2] = 0.0; m[3] = 0.0; m[4] = 0.0; m[5] = (real_t)2.0 / (top - bottom); m[6] = 0.0; m[7] = 0.0; m[8] = 0.0; m[9] = 0.0; m[10] = (real_t)-2.0/(zfar-znear); m[11] = 0.0; m[12] = tx; m[13] = ty; m[14] = tz; m[15] = 1.0; } }
//検証用 #include <cassert> //自前実装版glortho #include "myortho.h" #pragma comment(lib,"opengl32.lib") #pragma comment(lib,"glu32.lib") #pragma comment(lib,"freeglut.lib") void display(void) { GLfloat glomat[16]; //glu関数で生成 GLfloat myomat[16]; //自分関数で生成 //glOrtho,myorthoへの入力の値を色々変える static int i = 0; static float j = 0.0f; GLdouble left=-10+i; GLdouble right=+23 + i*1.5; GLdouble bottom=-10 - i / 2.0; GLdouble top=10 - i; GLdouble znear=5+j; GLdouble zfar=30+j*2; i++; j += 0.01; glMatrixMode(GL_PROJECTION); glLoadIdentity(); //openglで計算 glOrtho(left, right, bottom, top, znear, zfar); glGetFloatv(GL_PROJECTION_MATRIX, glomat); //自前計算 nu::myortho(myomat,left, right, bottom, top, znear, zfar); puts("----------------------------------------------"); printf("** %d \n", i); for (int k = 0; k < 16; k++) { //比較 printf("m[%2d] %+5.10lf %+5.10lf \n", k,glomat[k], myomat[k]); //自前計算とglOrtho計算の値があまりにかけ離れていたらassertで落ちる assert(abs(glomat[k] - myomat[k]) < 0.00001); } puts("----------------------------------------------"); } void mouse(int button, int state, int x, int y) { display(); } int main(int argc, char* argv[]) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_RGBA); glutCreateWindow(argv[0]); glutInitWindowPosition(0, 0); glutInitWindowSize(100,100); glutDisplayFunc(display); glutMouseFunc(mouse); glutMainLoop(); return 0; }
参考:https://manpag.es/RHEL5/3+gluPerspective
#include <cmath> namespace nu { typedef float real_t; inline real_t cot(real_t theta) { return (real_t)1.0 / tan(theta); } inline real_t to_radian(real_t degree) { return degree * (real_t)3.14159265358979 / (real_t)180.0; } //! @brief 透視投影行列の作成 (視野角で指定) //! @param [out] m 結果の4x4行列 //! @param [in] fovy_degree 視野角 //! @param [in] aspect アスペクト比 //! @param [in] zNear 一番近いz位置 //! @param [in] zFar 一番遠いz位置 //! @return なし inline void myPerspective( real_t* m, real_t fovy_degree, real_t aspect, real_t zNear, real_t zFar) { real_t fovy_rad = to_radian(fovy_degree); real_t f = cot(fovy_rad / (real_t)2.0); m[0] = f / aspect; m[1] = 0.0; m[2] = 0.0; m[3] = 0.0; m[4] = 0.0; m[5] = f; m[6] = 0.0; m[7] = 0.0; m[8] = 0.0; m[9] = 0.0; m[10] = (zFar + zNear) / (zNear - zFar); m[11] = -1.0; m[12] = 0.0; m[13] = 0.0; m[14] = (2 * zFar * zNear) / (zNear - zFar); m[15] = 0.0; } }
gluPerspectiveの結果はgluPerspectiveを呼び出した後でglGetFloatvで取得する。
#include <windows.h> #include <gl/GLU.h> #include <gl/freeglut.h> #include <cstdio> //検証用 #include <cassert> //自前実装版gluPerspective #include "myperspective.h" #pragma comment(lib,"opengl32.lib") #pragma comment(lib,"glu32.lib") #pragma comment(lib,"freeglut.lib") void display(void) { GLfloat glumat[16]; //glu関数で生成 GLfloat mypmat[16]; //自分関数で生成 //gluPerpsective,myPerspectiveへの入力の値を色々変える static int i = 0; static float j = 0.0f; GLfloat fovy=45.0f + i; GLfloat aspect=0.2f + j; GLfloat zNear=0.1f + j; GLfloat zFar=10.0f + j*2; i++; j += 0.01; glMatrixMode(GL_PROJECTION); glLoadIdentity(); //gluで計算 gluPerspective(fovy, aspect, zNear, zFar); glGetFloatv(GL_PROJECTION_MATRIX, glumat); //自前計算 nu::myPerspective(mypmat, fovy, aspect, zNear, zFar); puts("----------------------------------------------"); for (int k = 0; k < 16; k++) { //自前計算 printf("m[%2d] %+5.5lf %+5.5lf \n", k,glumat[k], mypmat[k]); //自前計算とgluPerspective計算の値があまりにかけ離れていたらassertで落ちる assert(abs(glumat[k] - mypmat[k]) < 0.00001); } puts("----------------------------------------------"); } void mouse(int button, int state, int x, int y) { display(); } int main(int argc, char* argv[]) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_RGBA); glutCreateWindow(argv[0]); glutInitWindowPosition(0, 0); glutInitWindowSize(100,100); glutDisplayFunc(display); glutMouseFunc(mouse); glutMainLoop(); return 0; }
template<int I, typename Head, typename... T> struct Tget { using type_t = typename Tget<I - 1, T...> ::type_t; }; template<typename Head, typename... T> struct Tget<0, Head, T...> { using type_t = Head; }; int main() { using t1 = Tget<2, char, int, double>::type_t; std::cout << "sizeof " << sizeof( t1 ) << std::endl; int i; std::cin >> i; return 0; }
*注意 originをオブジェクトの根元にする
*注意 originをオブジェクトの根元にする
[Shift]+右クリックで head,bodyの順に選択し、[Ctrl+P]→"Object"でheadをbodyの子に設定する


書籍 C++テンプレートテクニック 第2版 (επιστημη, 高橋 晶 著)
P130、is_assignable関数の挙動。文章だけだとわかりづらいので図にしてみた。
書籍 C++テンプレートテクニック 第2版 (επιστημη, 高橋 晶 著)
P125、has_iterator関数の挙動(C++11版)。文章だけだとわかりづらいので図にしてみた。
前回は書き出す方をやったので、今回は読み込む方をやる。
#include "pch.h" using namespace System; int main(array<::System::String ^> ^args) { Microsoft::Office::Interop::Word::Application^ word = gcnew Microsoft::Office::Interop::Word::Application(); word->Visible = false; Object^ oMissing = ::System::Reflection::Missing::Value; Object^ oTrue = true; Object^ oFalse = false; // Word文書を開く System::String^ fname = "C:\\test\\out.docx"; Microsoft::Office::Interop::Word::Document^ document = word->Documents->Open(fname, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing); for each(Microsoft::Office::Interop::Word::Paragraph^ par in document->Paragraphs) { Microsoft::Office::Interop::Word::Range^ ran = par->Range; System::String^ str = ran->Text; System::Console::WriteLine(str); } // 文書を閉じる ((Microsoft::Office::Interop::Word::_Document^)(document))->Close(oFalse, oMissing, oMissing); ((Microsoft::Office::Interop::Word::_Application^)word)->Quit(oMissing, oMissing, oMissing); return 0; }

