Mercurial > gemma
comparison pkg/mesh/vertex.go @ 5710:37c8feeecb4d
Merged branch sr-v2 into default.
author | Sascha L. Teichmann <sascha.teichmann@intevation.de> |
---|---|
date | Tue, 20 Feb 2024 21:28:56 +0100 |
parents | 148abae1fcd0 |
children | 61eff98a40ae |
comparison
equal
deleted
inserted
replaced
5672:b1a10654bf0f | 5710:37c8feeecb4d |
---|---|
86 // the three points of the triangles are in. | 86 // the three points of the triangles are in. |
87 func (t *Triangle) Plane3D() Plane3D { | 87 func (t *Triangle) Plane3D() Plane3D { |
88 | 88 |
89 v0 := t[1].Sub(t[0]) | 89 v0 := t[1].Sub(t[0]) |
90 v1 := t[2].Sub(t[0]) | 90 v1 := t[2].Sub(t[0]) |
91 n := v0.Cross(v1).Normalize() | 91 n := v0.Cross(v1) |
92 | |
93 // If the length of normal is near zero assume we have | |
94 // a plane constant in z with an average z value of | |
95 // the three vertices. | |
96 // This should protect us from the effects of collinear | |
97 // geometries. | |
98 l := n.Length() | |
99 if l < 1e-7 { | |
100 sum := t[0].Z + t[1].Z + t[2].Z | |
101 return Plane3D{ | |
102 A: 0, | |
103 B: 0, | |
104 C: 1, | |
105 D: -sum / 3, | |
106 } | |
107 } | |
108 n = n.Scale(1 / l) | |
92 | 109 |
93 // x*nx+ y*ny+ z*nz + d = 0 | 110 // x*nx+ y*ny+ z*nz + d = 0 |
94 // d = - (x*nx+ y*ny + z*nz) | 111 // d = - (x*nx+ y*ny + z*nz) |
95 d := -t[0].Dot(n) | 112 d := -t[0].Dot(n) |
96 return Plane3D{ | 113 return Plane3D{ |
1142 } | 1159 } |
1143 | 1160 |
1144 return out | 1161 return out |
1145 } | 1162 } |
1146 | 1163 |
1164 // QuantizeXY quantize the X/Y values to scale and | |
1165 // removes duplicates in place. The z value of | |
1166 // duplicates will be averaged pairwise. | |
1167 func (mpz MultiPointZ) QuantizeXY(scale float64) MultiPointZ { | |
1168 type qpoint struct { | |
1169 x int64 | |
1170 y int64 | |
1171 } | |
1172 m := make(map[qpoint]float64, len(mpz)) | |
1173 for _, p := range mpz { | |
1174 k := qpoint{ | |
1175 x: int64(math.Round(p.X * scale)), | |
1176 y: int64(math.Round(p.Y * scale)), | |
1177 } | |
1178 if z, ok := m[k]; ok { | |
1179 m[k] = (z + p.Z) * 0.5 | |
1180 } else { | |
1181 m[k] = p.Z | |
1182 } | |
1183 } | |
1184 i := 0 | |
1185 invScale := 1 / scale | |
1186 for k, z := range m { | |
1187 mpz[i] = Vertex{ | |
1188 X: float64(k.x) * invScale, | |
1189 Y: float64(k.y) * invScale, | |
1190 Z: z, | |
1191 } | |
1192 i++ | |
1193 } | |
1194 return mpz[:i] | |
1195 } | |
1196 | |
1147 // Filter returns a copy removed the vertices which | 1197 // Filter returns a copy removed the vertices which |
1148 // don't pass the filter test. | 1198 // don't pass the filter test. |
1149 func (mpz MultiPointZ) Filter(filter func(Vertex) bool) MultiPointZ { | 1199 func (mpz MultiPointZ) Filter(filter func(Vertex) bool) MultiPointZ { |
1150 n := make(MultiPointZ, 0, len(mpz)) | 1200 n := make(MultiPointZ, 0, len(mpz)) |
1151 for _, v := range mpz { | 1201 for _, v := range mpz { |