Spiga

分类为读书笔记的文章

WPF学习笔记2:3D绘图

2022-08-22 12:37:23

摘要:一、基本对象 1. WPF 3D WPF 中 3D 功能的设计初衷并非提供功能齐全的游戏开发平台。 WPF 中的 3D 图形内容封装在 Viewport3D 元素中,该元素可以参与二维元素结构。 该图形系统将 Viewport3D 视为一个二维视觉元素,就像 WPF 中的许多其他元素一样。 Viewport3D 充当三维场景中的窗口(即视区)。 更准确地说,它是 3D 场景所投影到的图面。 2. 模型3D场景 3D视口 坐标系 点、线、面、三角顶点网格 材质 光源 相机 3. 3D对象模型结构 MeshGemetry3D Positions TraiangleIndices TextureCoordinates:如何对应? 4. 相机 OrthographicCamera:正交 PerspectiveCamera:透视 基本属性: Position:相机的空间坐标(X,Y,Z) LookDirection:观察方向,向量,相机观察口朝向 FieldOfView(透视相机属性) / Width(正交相机属性):视野范围(焦距),一个值 UpDirection:相机上方方向,控制相机观察口旋转 FarPlaneDistance:远景距离,大于这个距离的场景不渲染 NearPlaneDistance:近景距离,小于这个距离的场景不渲染 5. 3D对象模型材质 DiffuseMaterial:漫反射,反射场景光效果 EmissiveMaterial:自发光,类似于电灯 SpecularMaterial:全反射,可以映射场景 贴图(平面贴图、曲面贴图-地球) 背面材质 6. 3D对象模型光源 AmbientLight:环境光 DirectionalLight:平行光 PointLight:点光源 SpotLight:聚光灯 相关属性 Color:灯光颜色 Direction:光线方向(平行光、聚光灯) Position:光源坐标(点光源、聚光灯) Range:灯光范围(点光源) InnerConeAngle:内光柱照射角度(聚光灯) OuterConeAngle:外光柱照射角度(聚光灯) 7. 3D对象的变换 Transform3D:平移 xyz ScaleTransform3D:缩放 RotateTransform3D:旋转 M…… 阅读全文

WPF学习笔记1:基础控件

2022-08-21 22:56:30

摘要:一、基础控件汇总 控件类型 主要控件 按钮控件 Button、RepeatButton、RadioButton 数据显示控件 TextBlock、Label、Image、ItemsControl**、ListView、ListBox、**DataGrid、DocumentViwer 输入控件 TextBox、RichTextBox、CheckBox、ComboBox、DatePicker、PasswordBox、Slider、ProgressBar 菜单导航控件 MenuItem、ContextMenu、ToolBar、TreeView、TabControl、Expander 信息提示控件 Popup、Window、PrintDialog、ToolTip 布局控件 Grid**、StackPanel、WrapPanel、DockPanel、UniformGrid、Canvas、InkCanvas、**Border 图形控件 Line、Rectangle、Ellipse、Polyline、Polygon、Path 其他控件 ScrollViwer、GroupBox、ViewBox 1. 常用属性 尺寸(宽高)、定位(Margin,HorizontalAlignment、VerticalAlignment)、颜色(Background、Foreground)、信息显示(Text、Content、ListViewItem、ListBoxItem、DataGridTextColumn…..) 鼠标事件、键盘事件 特别属性 RadioButton:GroupName 集合控件:AlternationCount ComboBox:SelectedItem、SelectedValue、SelectedValuePath、DisplayMemberPath、SelectedIndex DatePicker:SelectedDate、DisplayDateStart、DisplayDateEnd PasswordBox:Password(普通属性) Silder、ProgressBar:最小值、最大值、当前值 Popup:IsOpen、Placement、PlacementTarget、StaysOpen Window:无边…… 阅读全文

[推荐] Kubernates学习思路导图笔记

2021-04-25 23:46:47

摘要: 阅读全文

[推荐] kubectl 常用命令总结

2021-01-25 11:40:01

摘要:# 查看所有 pod 列表, -n 后跟 namespace, 查看指定的命名空间 kubectl get pod kubectl get pod -n kube kubectl get pod -o wide # 查看 RC 和 service 列表, -o wide 查看详细信息 kubectl get rc,svc kubectl get pod,svc -o wide kubectl get pod pod-name -o yaml # 显示 Node 的详细信息 kubectl describe node 192.168.0.212 # 显示 Pod 的详细信息, 特别是查看 pod 无法创建的时候的日志 kubectl describe pod pod-name eg: kubectl describe pod redis-master-tqds9 # 根据 yaml 创建资源, apply 可以重复执行,create 不行 kubectl create -f pod.yaml kubectl apply -f pod.yaml # 基于 pod.yaml 定义的名称删除 pod kubectl delete -f pod.yaml # 删除所有包含某个 label 的pod 和 service kubectl delete pod,svc -l name=label-name # 删除所有 Pod kubectl delete pod --all # 查看 endpoint 列表 kubectl get endpoints # 执行 pod 的 date 命令 kubectl exec pod-name -- date kubectl exec pod-name -- bash kubectl exec pod-name -- ping 10.24.51.9 # 通过bash获得 pod 中某个容器的TTY,相当于登录容器 kubectl exec -it pod-name -c container-name -- bash eg: kubectl exec -it redis-master-cln81 -- bash # 查看容器的日志 kubectl logs pod-name kube…… 阅读全文

Go学习笔记(十一):编写⾼性能的Go程序

2020-05-13 13:11:55

摘要:别让性能被“锁”住 我们来看一段代码 var cache map[string]string const NUM_OF_READER int = 40 const READ_TIMES = 100000 func init() { cache = make(map[string]string) cache[a] = aa cache[b] = bb } func lockFreeAccess() { var wg sync.WaitGroup wg.Add(NUM_OF_READER) for i := 0; i NUM_OF_READER; i++ { go func() { for j := 0; j READ_TIMES; j++ { _, err := cache[a] if !err { fmt.Println(Nothing) } } wg.Done() }() } wg.Wait() } func lockAccess() { var wg sync.WaitGroup wg.Add(NUM_OF_READER) m := new(sync.RWMutex) for i := 0; i NUM_OF_READER; i++ { go func() { for j := 0; j READ_TIMES; j++ { m.RLock() _, err := cache[a] if !err { fmt.Println(Nothing) } m.RUnlock() } wg.Done() }() } wg.Wait() } 这段程序一个没有锁,一个有锁。我们看一下测试结果 func BenchmarkLockFree(b *testing.B) { b.ResetTimer() for i := 0; i b.N; i++ { lockFreeAccess() } } //169 6618595 ns/op 77 B/op 1 allocs/op func BenchmarkLock(b *testing.B) { b.R…… 阅读全文

Go学习笔记(十):构建Restful服务

2020-05-09 17:30:49

摘要:json解析 内置json解析 利⽤反射实现,通过FeildTag来标识对应的json 值 type BasicInfo struct { Name string `json:name` Age int `json:age` } type JobInfo struct { Skills []string `json:skills` } type Employee struct { BasicInfo BasicInfo `json:basic_info` JobInfo JobInfo `json:job_info` } var jsonStr = `{ basic_info:{ name:Mike, age:30 }, job_info:{ skills:[Java,Go,C] } } ` func TestEmbeddedJson(t *testing.T) { e := new(Employee) err := json.Unmarshal([]byte(jsonStr), e) if err != nil { t.Error(err) } fmt.Println(*e) if v, err := json.Marshal(e); err == nil { fmt.Println(string(v)) } else { t.Error(err) } } 更快的JSON解析 EasyJSON 采用代码生成而非反射 安装:go get -u github.com/mailru/easyjson/... (后面的...需要带上) 使⽤:easyjson -all 结构定义.go (会生成一些代码) 1.比如我们有结构文件 struct_def.go type BasicInfo struct { Name string Age int } type JobInfo struct { Skills []string } type Employee struct { BasicInfo BasicInfo JobInfo JobInfo } 2.执行 easyjson -all struct_def.go会生成 struct_def_easyjs…… 阅读全文

Go学习笔记(九):实现Micro-Kernel(微内核模式)

2020-05-01 20:44:02

摘要:什么是微内核架构 微内核架构(Microkernel Architecture),也被称为插件化架构(Plugin-in Architecture),是一种面向功能进行拆分的可扩展架构。例如 VS Code、Eclipse 这一类 IDE 软件、UNIX 操作系统等等,都是参照微内核架构设计实现的。 微内核架构的两个核心组件 微内核架构包含两类核心的组件:核心系统(Core System)和插件模块(Plug-in modules)。核心系统负责与具体功能无关的通用功能,例如应用生命周期的管理、插件模块的管理(包括:插件模块的注册、载入、卸载等等);插件模块负责实现具体的功能,例如一个 Web 框架基本上会按照功能模块拆分成如下的插件模块:路由模块、安全模块、HTTP 编解码模块等等,每个模块都通过插件实现,每一个插件都只做一件事情。 微内核基本架构示意图如下所示: 核心系统功能尽量保持稳定,不要因为插件模块的扩展而不断修改,插件模块可以根据功能需求进行不断扩展。 特点与要点 特点 易于扩展 错误隔离 保持架构⼀致性 要点 内核包含公共流程或通⽤逻辑 将可变或可扩展部分规划为扩展点 抽象扩展点⾏为,定义接⼝ 利⽤插件进⾏扩展 实例 如下图,我们希望实现Agent在系统主机上,这个Agent可以手机文件信息、进程信息、应用信息,以及提供一个扩展点,可以扩展未来其他要收集的信息,因此我们需要提供一个Extension Point。 1.接口Collector定义 type Collector interface { Init(evtReceiver EventReceiver) error Start(agtCtx context.Context) error Stop() error Destory() error } type Event struct { Source string Content string } type EventReceiver interface { OnEvent(evt Event) } 2.定义Agent结构体 type Agent struct { collectors map[string]Collector evtBuf chan Event cancel c…… 阅读全文

Go学习笔记(八):实现Pipe-Filter(管道过滤器)

2020-04-27 22:50:03

摘要:Pipe-Filter 模式,即管道过滤器模式,这是一种非常经典的架构模式,这种模式与工业制造生产流水线非常类似,就像薯片的生产过程,从土豆的清洗、去皮、切片、烘干、油炸,到最后打包完成,整个生产过程被拆分成了多个环节,每个环节处理完成之后,通过传送带传送到下一个环节的机器。整个生产过程每个环节都是独立的,但又环环相扣,只要有一个环节出问题了,生产出来的薯片就会有质量问题。 适用的场景 ⾮常适合与数据处理及数据分析系统 Filter封装数据处理的功能 Pipe⽤于连接Filter传递数据或者在异步处理过程中缓冲数据流 进程内同步调⽤时,pipe演变为数据在⽅法调⽤间传递 松耦合:Filter只跟数据(格式)耦合 Filter 和组合模式 23 个经典设计模式里面有一个设计模式叫组合模式,当 Pipe-Filter 遇上组合模式时,多个 Filter 又可以再组合成一个新的 Filter,如下图所示,组合出来的 Filter 接收的数据与第一个 Filter 保持一致,返回的数据与最后一个 Filter 保持一致。通过组合,就可以将多个简单的 Filter 可以组合成一个更复杂的 Filter。应用这一套理论去实践,我们会发现,Filter 既可以做的很轻便,也可以做得很强大。 实例 接下来我们用Go语言实现上图实例: 1.定义filter接口 // Package pipefilter is to define the interfaces and the structures for pipe-filter style implementation package pipefilter // Request is the input of the filter type Request interface{} // Response is the output of the filter type Response interface{} // Filter interface is the definition of the data processing components // Pipe-Filter structure type Filter interface { Process(data Request) (Respons…… 阅读全文

Go学习笔记(七):“不安全”编程

2020-04-23 12:31:09

摘要:“不完全”行为的危险性,go语言中是不支持类型转换的,但我们使用“不安全“编程可以将类型的指针转换成任意其他类型,如下: func TestUnsafe(t *testing.T) { i := 10 f := *(*float64)(unsafe.Pointer(i)) t.Log(unsafe.Pointer(i)) t.Log(f) //5e-323, 并不能得到理想的结果 } 也有能转换成功的例子,比如我们对类型起的别名: type MyInt int //合理的类型转换 func TestConvert(t *testing.T) { a := []int{1, 2, 3, 4} b := *(*[]MyInt)(unsafe.Pointer(a)) t.Log(b) //[1 2 3 4] } 原子类型操作 func TestAtomic(t *testing.T) { var shareBufPtr unsafe.Pointer writeDataFn := func() { data := []int{} for i := 0; i 100; i++ { data = append(data, i) } //写完后再通过原子操作,将指针重新指向 atomic.StorePointer(shareBufPtr, unsafe.Pointer(data)) } readDataFn := func() { data := atomic.LoadPointer(shareBufPtr) fmt.Println(data, *(*[]int)(data)) } var wg sync.WaitGroup writeDataFn() for i := 0; i 10; i++ { wg.Add(1) go func() { for i := 0; i 10; i++ { writeDataFn() time.Sleep(time.Microsecond * 100) } wg.Done() }() wg.Add(1) go func() { for i := 0; i 10; i++ { readDataFn(…… 阅读全文

Go学习笔记(六):反射

2020-04-21 21:39:42

摘要:reflect.TypeOf vs. reflect.ValueOf reflect.TypeOf 返回类型 (reflect.Type) reflect.ValueOf 返回值 (reflect.Value) 可以从 reflect.Value 获得类型 通过 kind 的来判断类型 func CheckType(v interface{}) { t := reflect.TypeOf(v) switch t.Kind() { case reflect.Float32, reflect.Float64: fmt.Println(Float) case reflect.Int, reflect.Int32, reflect.Int64: fmt.Println(Integer) default: fmt.Println(Unknown, t) } } func TestBasicType(t *testing.T) { var f float64 = 12 CheckType(f) //Float CheckType(f) //Unknown *float64 } func TestTypeAndValue(t *testing.T) { var f int64 = 10 t.Log(reflect.TypeOf(f), reflect.ValueOf(f)) //int64 10 t.Log(reflect.ValueOf(f).Type()) //int64 } 利用反射编写灵活的代码 按名字访问结构的成员 reflect.ValueOf(*e).FieldByName(Name) 按名字访问结构的方法 reflect.ValueOf(e).MethodByName(UpdateAge).Call([]reflect.Value{reflect.ValueOf(1)}) 实例 type Employee struct { EmployeeID string Name string `format:normal` Age int } …… 阅读全文