ぬの部屋(仮)
nu-no-he-ya
  • 1234567
    891011121314
    15161718192021
    22232425262728
    2930     
           
        123
    45678910
    11121314151617
    18192021222324
    25262728293031
           
       1234
    567891011
    12131415161718
    19202122232425
    26272829   
           
    1234567
    891011121314
    15161718192021
    22232425262728
    293031    
           
        123
    45678910
    11121314151617
    18192021222324
    25262728293031
           
      12345
    6789101112
    13141516171819
    20212223242526
    27282930   
           
          1
    2345678
    9101112131415
    16171819202122
    23242526272829
    3031     
        123
    45678910
    11121314151617
    18192021222324
    252627282930 
           
     123456
    78910111213
    14151617181920
    21222324252627
    28293031   
           
         12
    3456789
    10111213141516
    17181920212223
    24252627282930
    31      
       1234
    567891011
    12131415161718
    19202122232425
    2627282930  
           
    1234567
    891011121314
    15161718192021
    22232425262728
    293031    
           
         12
    3456789
    10111213141516
    17181920212223
    24252627282930
           
      12345
    6789101112
    13141516171819
    20212223242526
    2728293031  
           
      12345
    6789101112
    13141516171819
    20212223242526
    2728     
           
          1
    2345678
    9101112131415
    16171819202122
    23242526272829
    3031     
       1234
    567891011
    12131415161718
    19202122232425
    262728293031 
           
     123456
    78910111213
    14151617181920
    21222324252627
    282930    
           
         12
    3456789
    10111213141516
    17181920212223
    24252627282930
    31      
       1234
    567891011
    12131415161718
    19202122232425
    2627282930  
           
    1234567
    891011121314
    15161718192021
    22232425262728
    293031    
           
        123
    45678910
    11121314151617
    18192021222324
    25262728293031
           
      12345
    6789101112
    13141516171819
    20212223242526
    27282930   
           
          1
    2345678
    9101112131415
    16171819202122
    23242526272829
    3031     
        123
    45678910
    11121314151617
    18192021222324
    252627282930 
           
     123456
    78910111213
    14151617181920
    21222324252627
    28293031   
           
     123456
    78910111213
    14151617181920
    21222324252627
    28      
           
         12
    3456789
    10111213141516
    17181920212223
    24252627282930
    31      
      12345
    6789101112
    13141516171819
    20212223242526
    2728293031  
           
    1234567
    891011121314
    15161718192021
    22232425262728
    2930     
           
        123
    45678910
    11121314151617
    18192021222324
    25262728293031
           
      12345
    6789101112
    13141516171819
    20212223242526
    27282930   
           
          1
    2345678
    9101112131415
    16171819202122
    23242526272829
    3031     
       1234
    567891011
    12131415161718
    19202122232425
    262728293031 
           
     123456
    78910111213
    14151617181920
    21222324252627
    282930    
           
         12
    3456789
    10111213141516
    17181920212223
    24252627282930
    31      
       1234
    567891011
    12131415161718
    19202122232425
    2627282930  
           
    1234567
    891011121314
    15161718192021
    22232425262728
    293031    
           
    1234567
    891011121314
    15161718192021
    22232425262728
           
           
        123
    45678910
    11121314151617
    18192021222324
    25262728293031
           
     123456
    78910111213
    14151617181920
    21222324252627
    28293031   
           
          1
    2345678
    9101112131415
    16171819202122
    23242526272829
    30      
       1234
    567891011
    12131415161718
    19202122232425
    262728293031 
           
     123456
    78910111213
    14151617181920
    21222324252627
    282930    
           
         12
    3456789
    10111213141516
    17181920212223
    24252627282930
    31      
      12345
    6789101112
    13141516171819
    20212223242526
    2728293031  
           
    1234567
    891011121314
    15161718192021
    22232425262728
    2930     
           
        123
    45678910
    11121314151617
    18192021222324
    25262728293031
           
      12345
    6789101112
    13141516171819
    20212223242526
    27282930   
           
          1
    2345678
    9101112131415
    16171819202122
    23242526272829
    3031     
         12
    3456789
    10111213141516
    17181920212223
    242526272829 
           
      12345
    6789101112
    13141516171819
    20212223242526
    2728293031  
           
          1
    2345678
    9101112131415
    16171819202122
    23242526272829
    3031     
        123
    45678910
    11121314151617
    18192021222324
    252627282930 
           
     123456
    78910111213
    14151617181920
    21222324252627
    28293031   
           
          1
    2345678
    9101112131415
    16171819202122
    23242526272829
    30      
       1234
    567891011
    12131415161718
    19202122232425
    262728293031 
           
    1234567
    891011121314
    15161718192021
    22232425262728
    293031    
           
         12
    3456789
    10111213141516
    17181920212223
    24252627282930
           
      12345
    6789101112
    13141516171819
    20212223242526
    2728293031  
           
    1234567
    891011121314
    15161718192021
    22232425262728
    2930     
           
        123
    45678910
    11121314151617
    18192021222324
    25262728293031
           
        123
    45678910
    11121314151617
    18192021222324
    25262728   
           
     123456
    78910111213
    14151617181920
    21222324252627
    28293031   
           
         12
    3456789
    10111213141516
    17181920212223
    24252627282930
    31      
       1234
    567891011
    12131415161718
    19202122232425
    2627282930  
           
    1234567
    15161718192021
    293031    
           
         12
    3456789
    10111213141516
           
      12345
    6789101112
    13141516171819
    20212223242526
    2728293031  
           
          1
    2345678
    9101112131415
    16171819202122
    23242526272829
    3031     
        123
    45678910
    11121314151617
    18192021222324
    252627282930 
           
     123456
    78910111213
    14151617181920
    21222324252627
    28293031   
           
          1
    2345678
    9101112131415
    16171819202122
    23242526272829
    30      
       1234
    567891011
    12131415161718
    19202122232425
    262728293031 
           
    1234567
    891011121314
    15161718192021
    22232425262728
    293031    
           
        123
    45678910
    11121314151617
    18192021222324
    25262728293031
           
      12345
    6789101112
    13141516171819
    20212223242526
    27282930   
           
        123
    45678910
    11121314151617
    18192021222324
    252627282930 
           
     123456
    78910111213
    14151617181920
    21222324252627
    28293031   
           
       1234
    567891011
    12131415161718
    19202122232425
    2627282930  
           
    1234567
    891011121314
    15161718192021
    22232425262728
    293031    
           
         12
    3456789
    10111213141516
    17181920212223
    24252627282930
           
      12345
    6789101112
    13141516171819
    20212223242526
    2728293031  
           
      12345
    6789101112
    13141516171819
    20212223242526
    2728     
           
          1
    2345678
    9101112131415
    16171819202122
    23242526272829
    3031     
     123456
    78910111213
    14151617181920
    21222324252627
    282930    
           
         12
    3456789
    10111213141516
    17181920212223
    24252627282930
    31      
    1234567
    891011121314
    15161718192021
    22232425262728
    293031    
           
        123
    45678910
    11121314151617
    18192021222324
    252627282930 
           
     123456
    78910111213
    14151617181920
    21222324252627
    28293031   
           
     123456
    78910111213
    14151617181920
    21222324252627
    28293031   
           
       1234
    567891011
    12131415161718
    19202122232425
    262728293031 
           
     123456
    78910111213
    14151617181920
    21222324252627
    282930    
           
         12
    3456789
    10111213141516
    17181920212223
    24252627282930
    31      
      12345
    6789101112
    13141516171819
    20212223242526
    2728293031  
           
    1234567
    891011121314
    15161718192021
    22232425262728
    2930     
           
        123
    45678910
    11121314151617
    18192021222324
    25262728293031
           
      12345
    6789101112
    13141516171819
    20212223242526
    27282930   
           
          1
    2345678
    9101112131415
    16171819202122
    23242526272829
    3031     
          1
    2345678
    9101112131415
    16171819202122
    232425262728 
           
       1234
    567891011
    12131415161718
    19202122232425
    262728293031 
           
    1234567
    891011121314
    15161718192021
    22232425262728
    293031    
           
         12
    3456789
    10111213141516
    17181920212223
    24252627282930
           
      12345
    6789101112
    13141516171819
    20212223242526
    2728293031  
           
    1234567
    891011121314
    15161718192021
    22232425262728
    2930     
           
        123
    45678910
    11121314151617
    18192021222324
    25262728293031
           
  • Rustで乱数

    Rustの乱数の使い方。

    サンプルコード

    Cargo.toml

    乱数を使用するためにはrandクレートを使用する。

    [dependencies]
    # 乱数を使用 https://crates.io/crates/rand
    rand = "0.8.5"

    最も基本的なコード

    fn main() {
    
        use rand::Rng; // 乱数を使うためにrand::Rngを使用
    
        let mut rng = rand::thread_rng();
    
        let min:i32 = 0;
        let max:i32 = 20;
        
        // 50回ループ
        (0..50).for_each(|_|{
    
            let randint:i32 = rng.gen_range(min..max); // 最大・最小を指定して乱数を生成
    
            println!("{}",randint);
    
        });
    
    }
    

    分布を指定して乱数生成

    rand_distrクレートを使用すると分布を変えられる。rand_distr::Normalは正規分布。

     

    [dependencies]
    # 乱数を使用 https://crates.io/crates/rand
    rand = "0.8.5"

    # 乱数の分布を指定 https://crates.io/crates/rand_distr
    rand_distr = "0.4.3"

     

    fn main() {
        use rand::prelude::{Distribution, thread_rng};    
        use rand_distr::Normal;
    
        let mut rng = rand::thread_rng();
    
        let mean:f32 = 10.0;
        let stddev:f32 = 8.0;
        
        // 平均値と標準偏差を用いた乱数生成器を作成
        let normal = Normal::new(
            mean,  // 平均        
            stddev // 標準偏差
       ).unwrap();
    
    
        // 50回ループ
        (0..100).for_each(|_|{
    
            let randint:i32 = normal.sample(&mut rng) as i32; // 乱数を生成
    
            println!("{}",randint);
    
        });
    
    }
    

    win32apiで二次元にランダムな点をプロット

    これだけではさすがにつまらないので、win32apiを使ってSetPixelで点を散布してみる。

    以前作ったメモリデバイスコンテキストのコードで乱数のプロットを表示する。

    Rust+windows-rsでDIBを使う

    winmain.rs

    #[path="./win32dib.rs"]
    mod win32dib;
    use win32dib::Win32DIBCanvas;
    
    
    
    use windows::{
        core::*, 
        Win32::Foundation::*,
        Win32::Graphics::Gdi::*,
        Win32::UI::WindowsAndMessaging::*,
    };
    
    use once_cell::sync::Lazy;
    use std::sync::Mutex;
    
    // ■ Mutex ... std::sync::Mutex
    // ■ Lazy  ... once_cell::sync::Lazy
    static mydib:Lazy<Mutex<Win32DIBCanvas>> = 
            Lazy::new(|| 
                Mutex::new(
                    Win32DIBCanvas::new()
                )
            );
    
    ///////////////////////////////////////////////
    /// MemDCの背景をクリア  //////////////////////
    fn clear_mydib_background(rmdib : &mut Win32DIBCanvas){
        // super::super::Foundation::COLORREF
        // let refmydib = &mut mydib.lock().unwrap();
        let width:i32 = rmdib.bitmapInfo.bmiHeader.biWidth;
        let height:i32 = -rmdib.bitmapInfo.bmiHeader.biHeight;
    
        let rect:RECT = RECT{
            left:0,
            top:0,
            right:width,
            bottom:height,
        };
    
        unsafe {
            
            let whitebrush = CreateSolidBrush(COLORREF(0x00FFFFFF));
            FillRect(rmdib.hMemDC,&rect,whitebrush);        
            DeleteObject(whitebrush);
            
        }
    
    }
    
    
    ///////////////////////////////////////////////
    /// count個の乱数を生成
    fn  get_random(count:i32, min:i32,max:i32) -> Vec<i32>{
    
        use rand::Rng; // 乱数を使うためにrand::Rngを使用
    
        let mut rng = rand::thread_rng();
    
    
        let mut rlist:Vec<i32> = Vec::new();
    
        for i in 0..count{
    
            let randint:i32 = rng.gen_range(min..max);
    
            rlist.push(randint);
    
        }
    
        return rlist;
    
    }
    

    ///////////////////////////////////////////////
    // ■ HWND ... windows::Win32::Foundation::HWND // ■ WPARAM ... windows::Win32::Foundation::WPARAM // ■ LPARAM ... windows::Win32::Foundation::LPARAM // ■ LRESULT ... windows::Win32::Foundation::LRESULT extern "system" fn wndproc(window: HWND, message: u32, wparam: WPARAM, lparam: LPARAM) -> LRESULT { unsafe { // ■ RECT ... windows::Win32::Foundation::RECT let rectnullptr: Option<*const RECT> = None; match message as u32 { WM_CREATE => { // mydib.lock().unwrap() への可変な参照をrefmydibに束縛 let refmydib = &mut mydib.lock().unwrap(); refmydib.create(640,480); clear_mydib_background(refmydib);
                    ///////////////////////////////////////
                    /// 乱数で座標を作成 //////////////////
                    let count = 50000;
                    let xlist:Vec<i32> = get_random(count,0,640);
                    let ylist:Vec<i32> = get_random(count,0,480);
    
                    // 点をプロット
                    for pindex in 0..count as usize{
                        SetPixel(
                            refmydib.hMemDC,
                            xlist[pindex],
                            ylist[pindex],
                            COLORREF(0x00000000));
                    }
                    ///////////////////////////////////////
    
                    // ■ LRESULT ... windows::Win32::Foundation::LRESULT
                    LRESULT(0)
                }
                WM_PAINT => {
    
    
                    // ■ PAINTSTRUCT ... windows::Win32::Graphics::Gdi::PAINTSTRUCT
                    // ■ BeginPaint  ... windows::Win32::Graphics::Gdi::BeginPaint
                    let mut ps = PAINTSTRUCT::default();
                    let hdc = BeginPaint(window, &mut ps);
                    let refmydib = &mut mydib.lock().unwrap();
    
    
                    //////////////////////////////////////////////////////////
                    // 背景をクリア ///////////////////////////////////////////
                    let mut clientrect:RECT = RECT::default();
                    GetClientRect(window, &mut clientrect);
                    let whitebrush = CreateSolidBrush(COLORREF(0x00FFFFFF));
                    FillRect(hdc,&clientrect,whitebrush);
                    DeleteObject(whitebrush);
                    //////////////////////////////////////////////////////////
    
    
                    // ■ BitBlt  ... windows::Win32::Graphics::Gdi
                    // ■ SRCCOPY ... windows::Win32::Graphics::Gdi::SRCCOPY
                    BitBlt(
                        hdc,
                        0,
                        0,
                        640,
                        480,
                        refmydib.hMemDC,
                        0,
                        0,
                        SRCCOPY
                    );
    
                    // ■ EndPaint ... windows::Win32::Graphics::Gdi::EndPaint
                    EndPaint(window, &ps);
    
                    // ■ LRESULT ... windows::Win32::Foundation::LRESULT
                    LRESULT(0)
                }
                WM_DESTROY => {
                    println!("WM_DESTROY");
    
                    // ■ windows::Win32::UI::WindowsAndMessaging::PostQuitMessage
                    PostQuitMessage(0);
    
                    // ■ LRESULT ... windows::Win32::Foundation::LRESULT
                    LRESULT(0)
                }
                // ■ windows::Win32::UI::WindowsAndMessaging::DefWindowProcA
                _ => DefWindowProcA(window, message, wparam, lparam),
            }
        }
    }
    
    
    
    // ■ HINSTANCE ... windows::Win32::Foundation::HINSTANCE
    /// 自作 WinMain
    pub fn WinMain(
            hInstance : HINSTANCE, 
            hPrevInstance : HINSTANCE, 
            lpCmdLine:Vec<String>, 
            nCmdShow:i32
        )->i32{
    
        unsafe{
    
            // ■ PCSTR ... windows::core::PCSTR
            // ■ windows::Win32::UI::WindowsAndMessaging::LoadCursorW
            // ■ windows::Win32::UI::WindowsAndMessaging::IDC_ARROW
            // ■ windows::Win32::UI::WindowsAndMessaging::CS_HREDRAW
            // ■ windows::Win32::UI::WindowsAndMessaging::CS_VREDRAW
            let _hCursor = LoadCursorW(None,IDC_ARROW).unwrap();
            let _hInstance = hInstance;
            let _lpszClassName = PCSTR::from_raw("MY_NEW_WINDOW\0".as_ptr());
            let _style = CS_HREDRAW | CS_VREDRAW;
    
            // https://microsoft.github.io/windows-docs-rs/doc/windows/Win32/UI/WindowsAndMessaging/struct.WNDCLASSA.html
            // ■ WNDCLASSA ... windows::Win32::UI::WindowsAndMessaging::WNDCLASSA
            let wc=WNDCLASSA{
                hCursor :_hCursor,
                hInstance: _hInstance,
                lpszClassName: _lpszClassName,
                style: _style,
                lpfnWndProc: Some(wndproc),
                ..Default::default()
            };
    
            // ■ windows::Win32::UI::WindowsAndMessaging::RegisterClassA
            let atom = RegisterClassA(&wc);
            debug_assert!(atom != 0);
    
    
            let nullptr: Option<*const ::core::ffi::c_void> = None;
    
            // ■ windows::Win32::UI::WindowsAndMessaging::CreateWindowExA
            // ■ PCSTR ... windows::core::PCSTR
            // ■ windows::Win32::UI::WindowsAndMessaging::WS_OVERLAPPEDWINDOW
            // ■ windows::Win32::UI::WindowsAndMessaging::WS_VISIBLE
            // ■ windows::Win32::UI::WindowsAndMessaging::CW_USEDEFAULT
            CreateWindowExA(
                Default::default(),
                _lpszClassName,
                PCSTR::from_raw("This is a sample window\0".as_ptr()),
                WS_OVERLAPPEDWINDOW | WS_VISIBLE,
                CW_USEDEFAULT,
                CW_USEDEFAULT,
                700,
                600,
                None,
                None,
                _hInstance,
                nullptr,
            );
    
            // ■ windows::Win32::UI::WindowsAndMessaging::MSG
            let mut message = MSG::default();
    
            // ■ windows::Win32::UI::WindowsAndMessaging::GetMessageA
            // ■ windows::Win32::UI::WindowsAndMessaging::DispatchMessageA
            // ■ HWND ... windows::Win32::Foundation::HWND
            while GetMessageA(&mut message, HWND(0), 0, 0).into() {
                DispatchMessageA(&mut message);
            }
        }
        return 0;
    
    
    }
    

    正規分布の乱数

    先のプログラムのget_randomを以下のように変える(minは使わないことにした)と、乱数の分布が変わったのがわかる。

    ///////////////////////////////////////////////
    /// 正規分布の乱数を生成する ///////////////////
    fn get_random(count:i32, max:i32) -> Vec<i32>{
        
        use rand::prelude::{Distribution, thread_rng};    
        use rand_distr::Normal;
    
    
        let mut rng = rand::thread_rng();
    
        // 平均値と標準偏差を用いた乱数生成器を作成
        let normal = Normal::new(
             (max as f32) / 2.0,  // 平均
             (max as f32) / 8.0  // 標準偏差
        ).unwrap();
    
        let mut rlist:Vec<i32> = Vec::new();
    
        for i in 0..count{
    
            let randint:i32 = normal.sample(&mut rng) as i32;// 平均値と標準偏差で乱数生成
    
            rlist.push(randint);
    
        }
    
        return rlist;
    
    }
    

    シードを指定して乱数生成

    シードを指定する場合、以下のように[u8;32]の配列をシードとして与える。シードだけで32byteも与えなければならない。なお[0;32]の配列指定で要素の型がu8に定まるのは、文脈的にseedがfrom_seedで与えられていることからデータ型を推論しているかららしい。

    fn main() {
    
        use rand::Rng; // 乱数を使うためにrand::Rngを使用
        use rand::SeedableRng; // シードの指定に必要
        use rand::rngs::StdRng; // シードの指定に必要
    
        let seed = [0; 32];// 全要素0、要素数32,u8型の配列を作成
        let mut rng:StdRng = SeedableRng::from_seed(seed); // シードを固定した乱数生成器を初期化
        //let mut rng = rand::thread_rng(); // シード未指定の場合
    
    
    
        let min:i32 = 0;
        let max:i32 = 20;
        
        // 50回ループ
        (0..50).for_each(|_|{
    
            let randint:i32 = rng.gen_range(min..max);// 最大・最小を指定して乱数を生成
    
            println!("{}",randint);
    
        });
    }