def mainImage(iMouse: ti.Vector, iTime: ti.f32, i: ti.i32, j: ti.i32) -> ti.Vector: fragCoord = ti.Vector([i, j]) p = -1.0 + 2.0 * fragCoord / iResolution m = -1.0 + 2.0 * iMouse # iMouse 已经归一化 a1 = ti.atan2(p[1] - m[1], p[0] - m[0]) a2 = ti.atan2(p[1] + m[1], p[0] + m[0]) r1 = ti.sqrt((p - m).dot(p - m)) r2 = ti.sqrt((p + m).dot(p + m)) uv = ti.Vector( [0.2 * iTime + (r1 - r2) * 0.25, ti.asin(ti.sin(a1 - a2)) / 3.1416]) w = ti.exp(-15.0 * r1 * r1) + ti.exp(-15.0 * r2 * r2) w += 0.25 * smoothstep(0.93, 1.0, ti.sin(128.0 * uv[0])) w += 0.25 * smoothstep(0.93, 1.0, ti.sin(128.0 * uv[1])) # 可以使用纹理 # vec3 col = texture( iChannel0, 0.125*uv ).zyx; col = ti.Vector([0.0, 0.0, 0.0]) fragColor = col + w return fragColor
def test_atan2_f64(): grad_test(lambda x: ti.atan2(0.4, x), lambda x: np.arctan2(0.4, x), default_fp=ti.f64) grad_test(lambda y: ti.atan2(y, 0.4), lambda y: np.arctan2(y, 0.4), default_fp=ti.f64)
def computeDstToRefTransform(dst_mean_x, dst_mean_y): """ Compute the rotation matrix and translation vectors to move dst p.c. into ref p.c Beased on https://lucidar.me/en/mathematics/singular-value-decomposition-of-a-2x2-matrix/ """ a = A[0, 0] b = A[1, 0] c = A[0, 1] d = A[1, 1] teta = 0.5 * ti.atan2(2 * a * c + 2 * b * d, a * a + b * b - c * c - d * d) U[0, 0] = ti.cos(teta) U[1, 0] = -ti.sin(teta) U[0, 1] = ti.sin(teta) U[1, 1] = ti.cos(teta) # We don't need the Sigma matrix for ICP # s1 = a*a + b*b + c*c + d*d # s2 = ti.sqrt((a*a + b*b - c*c - d*d) * (a*a + b*b - c*c - d*d) + 4 * (a*c + b*d) * (a*c + b*d)) # sigma1 = ti.sqrt((s1 + s2) * 0.5) # sigma2 = ti.sqrt((s1 - s2) * 0.5) # S[0,0] = sigma1 # S[1,0] = 0 # S[0,1] = 0 # S[1,1] = sigma2 phi = 0.5 * ti.atan2(2 * a * b + 2 * c * d, a * a - b * b + c * c - d * d) s11 = (a * ti.cos(teta) + c * ti.sin(teta)) * ti.cos(phi) + ( b * ti.cos(teta) + d * ti.sin(teta)) * ti.sin(phi) if s11 != 0: s11 = s11 / ti.abs(s11) s22 = (a * ti.sin(teta) - c * ti.cos(teta)) * ti.sin(phi) + ( -b * ti.sin(teta) + d * ti.cos(teta)) * ti.cos(phi) if s22 != 0: s22 = s22 / ti.abs(s22) V[0, 0] = s11 * ti.cos(phi) V[1, 0] = -s22 * ti.sin(phi) V[0, 1] = s11 * ti.sin(phi) V[1, 1] = s22 * ti.cos(phi) Rot[0, 0] = V[0, 0] * U[0, 0] + V[1, 0] * U[1, 0] Rot[1, 0] = V[0, 0] * U[0, 1] + V[1, 0] * U[1, 1] Rot[0, 1] = V[0, 1] * U[0, 0] + V[1, 1] * U[1, 0] Rot[1, 1] = V[0, 1] * U[0, 1] + V[1, 1] * U[1, 1] Trans[0] = ref_mean[0] - Rot[0, 0] * dst_mean_x - Rot[1, 0] * dst_mean_y Trans[1] = ref_mean[1] - Rot[0, 1] * dst_mean_x - Rot[1, 1] * dst_mean_y
def atan(y, x=1): ''' Return the arc-tangent of the parameters `atan(y, x)` or `atan(y_over_x)`: `atan` returns the angle whose trigonometric arctangent is y / x or y_over_x, depending on which overload is invoked. In the first overload, the signs of y and x are used to determine the quadrant that the angle lies in. The values returned by atan in this case are in the range [−pi, pi]. Results are undefined if x is zero. For the second overload, atan returns the angle whose tangent is y_over_x. Values returned in this case are in the range [−pi/2, pi/2]. :parameter y: The numerator of the fraction whose arctangent to return. :parameter x: The denominator of the fraction whose arctangent to return. :return: The return value is `arctan(x / y)`. ''' return ti.atan2(y, x)
def paint(t:ti.f32) : for i, j in pixels: p = ti.Vector([2*i-Width, 2*j-Height])/min(Width,Height) #background-color bcol = ti.Vector([1.0,0.8,0.7-0.07*p[1]]) * (1.0-0.25*p.norm()) #animate tt = mod(t, 1.5)/1.5 ss = pow(tt, 0.2)*0.5+0.5 ss = 1.0 + ss*0.5*ti.sin(tt*6.2831*3.0+p[1]*0.5)*ti.exp(-4.0*tt) p *= ti.Vector([0.5, 1.5]) + ss*ti.Vector([0.5, -0.5]) #shape p[1] -= 0.25 a = ti.atan2(p[0], p[1]) / 3.141593 r = p.norm() h = abs(a) d = (13.0*h - 22.0*h*h + 10.0*h*h*h)/(6.0-5.0*h) #color s = 0.75 + 0.75*p[0] s *= 1.0 - 0.4*r s = 0.3 + 0.7*s s *= 0.5 + 0.5*pow(1.0-clamp(r/d, 0.0, 1.0), 1.0) hcol = ti.Vector([1.0, 0.5*r, 0.3])*s pixels[i,j] = mix(bcol , hcol ,smoothstep(-0.01, 0.01, d-r))
def skewsin(x, t): """ skewsin-функция :param x: радианы :param t: значение :return: значение skewsin-функции """ return ti.atan2(t * ti.sin(x), (1. - t * ti.cos(x))) / t
def getBoundaryValue(x_index, y_index): dx = sdf[x_index+1, y_index-1][0] - sdf[x_index-1, y_index-1][0] \ + sdf[x_index+1, y_index][0] - sdf[x_index-1, y_index][0] \ + sdf[x_index+1, y_index+1][0] - sdf[x_index-1, y_index+1][0] dy = sdf[x_index-1, y_index+1][0] - sdf[x_index-1, y_index-1][0] \ + sdf[x_index, y_index+1][0] - sdf[x_index, y_index-1][0] \ + sdf[x_index+1, y_index+1][0] - sdf[x_index+1, y_index-1][0] return ti.abs(ti.atan2(dy, dx) / 3.14159)
def _ΔΦ(i: ti.i32, z: ti.i32) -> ti.f32: s = 0.0 t = 0.0 for r in range(Rf, Nr): Δ = (ti.atan2(_J[i, r], _I[i, r]) - _Φ[i, z, r]) % (2 * π) if (Δ > π): Δ -= 2 * π w = ti.sqrt(_I[i, r]**2 + _J[i, r]**2) * _A[i, z, r] t += w s += w * Δ return s / t
def random_point_in_unit_polygon(self, sides, angle): point = ti.Vector.zero(ti.f32, 2) central_angle = 2 * math.pi / sides while True: point = ti.Vector([ti.random(), ti.random()]) * 2 - 1 point_angle = ti.atan2(point.y, point.x) theta = (point_angle - angle) % central_angle # polygon angle is from +X axis phi = central_angle / 2 dist = ti.sqrt((point**2).sum()) if dist < ti.cos(phi) / ti.cos(phi - theta): break return point
def sampleEquiAngular( u: ti.f32, maxDistance: ti.f32, rayOrigin: ti.Vector, # vec3 rayDir: ti.Vector, # vec3 lightPos: ti.Vector # vec3 ): # get coord of closest point to light along(infinite) ray delta = dot(lightPos - rayOrigin, rayDir) # get distance this point is from light D = length(rayOrigin + delta * rayDir - lightPos) # get angle of endpoints thetaA = ti.atan2(0.0 - delta, D) thetaB = ti.atan2(maxDistance - delta, D) # take sample t = D * ti.tan(mix(thetaA, thetaB, u)) dist = delta + t pdf = D / ((thetaB - thetaA) * (D * D + t * t)) return (dist, pdf)
def getDist(p): diskPos = -1.0 * p diskDist = sphere(ti.Vector([diskPos[0], diskPos[1], diskPos[2], 5.0])) diskDist = max(diskDist, diskPos[1] - 0.01) diskDist = max(diskDist, -1.0 * diskPos[1] - 0.01) diskDist = max( diskDist, -1.0 * sphere(ti.Vector([-1.0 * p[0], -1.0 * p[1], -1.0 * p[2], 1.5]) * 10.0)) if diskDist < 2.0: c = ti.Vector([ diskPos.norm(), diskPos[1], ti.atan2(diskPos[2] + 1.0, diskPos[0] + 1.0) * 0.5 ]) c *= 10.0 diskDist += noise(c) * 0.4 diskDist += noise(c * 2.5) * 0.2 return diskDist
def friction(t: ti.i32): # params V, R # updates Fupdated for prtcl in range(N): vx, vy = V[t, prtcl] v = ti.sqrt(vx * vx + vy * vy) theta = ti.atan2(vy, vx) # random doesnt seem to work in tape scope ffx = friction_coef[None] * v * ti.cos( theta) # + ti.randn() * temperature ffy = friction_coef[None] * v * ti.sin( theta) # + ti.randn() * temperature Fupdated[t, prtcl][0] += ffx Fupdated[t, prtcl][0] += ffx
def func(): x[0] = y[None] + z[None] x[1] = y[None] - z[None] x[2] = y[None] * z[None] x[3] = y[None] / z[None] x[4] = y[None] // z[None] x[5] = y[None] % z[None] x[6] = y[None]**z[None] x[7] = y[None] == z[None] x[8] = y[None] != z[None] x[9] = y[None] > z[None] x[10] = y[None] >= z[None] x[11] = y[None] < z[None] x[12] = y[None] <= z[None] x[13] = ti.atan2(y[None], z[None]) x[14] = ti.min(y[None], z[None]) x[15] = ti.max(y[None], z[None])
def test_constant_matrices(): assert ti.cos(ti.math.pi / 3) == approx(0.5) assert np.allclose((-ti.Vector([2, 3])).to_numpy(), np.array([-2, -3])) assert ti.cos(ti.Vector([2, 3])).to_numpy() == approx(np.cos(np.array([2, 3]))) assert ti.max(2, 3) == 3 res = ti.max(4, ti.Vector([3, 4, 5])) assert np.allclose(res.to_numpy(), np.array([4, 4, 5])) res = ti.Vector([2, 3]) + ti.Vector([3, 4]) assert np.allclose(res.to_numpy(), np.array([5, 7])) res = ti.atan2(ti.Vector([2, 3]), ti.Vector([3, 4])) assert res.to_numpy() == approx( np.arctan2(np.array([2, 3]), np.array([3, 4]))) res = ti.Matrix([[2, 3], [4, 5]]) @ ti.Vector([2, 3]) assert np.allclose(res.to_numpy(), np.array([13, 23])) v = ti.Vector([3, 4]) w = ti.Vector([5, -12]) r = ti.Vector([1, 2, 3, 4]) s = ti.Matrix([[1, 2], [3, 4]]) assert v.normalized().to_numpy() == approx(np.array([0.6, 0.8])) assert v.cross(w) == approx(-12 * 3 - 4 * 5) w.y = v.x * w[0] r.x = r.y r.y = r.z r.z = r.w r.w = r.x assert np.allclose(w.to_numpy(), np.array([5, 15])) assert ti.select(ti.Vector([1, 0]), ti.Vector([2, 3]), ti.Vector([4, 5])) == ti.Vector([2, 5]) s[0, 1] = 2 assert s[0, 1] == 2 @ti.kernel def func(t: ti.i32): m = ti.Matrix([[2, 3], [4, t]]) print(m @ ti.Vector([2, 3])) m += ti.Matrix([[3, 4], [5, t]]) print(m @ v) print(r.x, r.y, r.z, r.w) s = w.transpose() @ m print(s) print(m) func(5)
def ang(self): '''Phase angle of the complex''' return ti.atan2(self.y, self.x)
def test_case_2() -> ti.f32: x[0] = ti.i32(3) y[0] = ti.i32(1) return ti.atan2(x[0], y[0])
def test_case_1() -> ti.f32: x[0] = ti.i32(2) return ti.atan2(x[0], 1)
def test_case_0() -> ti.f32: i = ti.i32(2) return ti.atan2(i, 1)
def func(): y[0] = x[0] % 3 @ti.kernel def func2(): ti.atomic_add(y[0], x[0] % 3) func() func.grad() func2() func2.grad() @pytest.mark.parametrize('tifunc,npfunc', [ (lambda x: ti.atan2(0.4, x), lambda x: np.arctan2(0.4, x)), (lambda y: ti.atan2(y, 0.4), lambda y: np.arctan2(y, 0.4)), ]) @if_has_autograd @test_utils.test() def test_atan2(tifunc, npfunc): grad_test(tifunc, npfunc) @pytest.mark.parametrize('tifunc,npfunc', [ (lambda x: ti.atan2(0.4, x), lambda x: np.arctan2(0.4, x)), (lambda y: ti.atan2(y, 0.4), lambda y: np.arctan2(y, 0.4)), ]) @if_has_autograd @test_utils.test(require=ti.extension.data64, default_fp=ti.f64) def test_atan2_f64(tifunc, npfunc):
def increment_vector_inplace( array_vector: ti.template(), magnitude: float, dy: float, dx: float): # increment array_vector (which is/may be row in an [? x 2]) vector field) theta = ti.atan2(dy, dx) array_vector[0] += magnitude * ti.cos(theta) array_vector[1] += magnitude * ti.sin(theta)
def computeNormalAndCurvature(): """ Compute the normal and the curvature at all points voxels. Based on the PC limplementation: https://pointclouds.org/documentation/group__features.html """ radius = 50 for i,j in pts: nb_pts = ti.cast(0, ti.f32) accu_0 = ti.cast(0, ti.f32) accu_1 = ti.cast(0, ti.f32) accu_2 = ti.cast(0, ti.f32) accu_3 = ti.cast(0, ti.f32) accu_4 = ti.cast(0, ti.f32) accu_5 = ti.cast(0, ti.f32) accu_6 = ti.cast(0, ti.f32) accu_7 = ti.cast(0, ti.f32) accu_8 = ti.cast(0, ti.f32) z = 0 for x in range(i-radius, i+radius): for y in range(j-radius, j+radius): if ti.is_active(block1, [x,y]): accu_0 += x * x accu_1 += x * y accu_2 += x * z accu_3 += y * y accu_4 += y * z accu_5 += z * z accu_6 += x accu_7 += y accu_8 += z nb_pts += 1 accu_0 /= nb_pts accu_1 /= nb_pts accu_2 /= nb_pts accu_3 /= nb_pts accu_4 /= nb_pts accu_5 /= nb_pts accu_6 /= nb_pts accu_7 /= nb_pts accu_8 /= nb_pts cov_mat_0 = accu_0 - accu_6 * accu_6 cov_mat_1 = accu_1 - accu_6 * accu_7 cov_mat_2 = accu_2 - accu_6 * accu_8 cov_mat_4 = accu_3 - accu_7 * accu_7 cov_mat_5 = accu_4 - accu_7 * accu_8 cov_mat_8 = accu_5 - accu_8 * accu_8 cov_mat_3 = cov_mat_1 cov_mat_6 = cov_mat_2 cov_mat_7 = cov_mat_5 # Compute eigen value and eigen vector # Make sure in [-1, 1] scale = ti.max(1.0, ti.abs(cov_mat_0)) scale = ti.max(scale, ti.abs(cov_mat_1)) scale = ti.max(scale, ti.abs(cov_mat_2)) scale = ti.max(scale, ti.abs(cov_mat_3)) scale = ti.max(scale, ti.abs(cov_mat_4)) scale = ti.max(scale, ti.abs(cov_mat_5)) scale = ti.max(scale, ti.abs(cov_mat_6)) scale = ti.max(scale, ti.abs(cov_mat_7)) scale = ti.max(scale, ti.abs(cov_mat_8)) if scale > 1.0: cov_mat_0 /= scale cov_mat_1 /= scale cov_mat_2 /= scale cov_mat_3 /= scale cov_mat_4 /= scale cov_mat_5 /= scale cov_mat_6 /= scale cov_mat_7 /= scale cov_mat_8 /= scale # Compute roots eigen_val_0 = ti.cast(0, ti.f32) eigen_val_1 = ti.cast(0, ti.f32) eigen_val_2 = ti.cast(0, ti.f32) c0 = cov_mat_0 * cov_mat_4 * cov_mat_8 \ + 2 * cov_mat_3 * cov_mat_6 * cov_mat_7 \ - cov_mat_0 * cov_mat_7 * cov_mat_7 \ - cov_mat_4 * cov_mat_6 * cov_mat_6 \ - cov_mat_8 * cov_mat_3 * cov_mat_3 c1 = cov_mat_0 * cov_mat_4 \ - cov_mat_3 * cov_mat_3 \ + cov_mat_0 * cov_mat_8 \ - cov_mat_6 * cov_mat_6 \ + cov_mat_4 * cov_mat_8 \ - cov_mat_7 * cov_mat_7 c2 = cov_mat_0 + cov_mat_4 + cov_mat_8 if ti.abs(c0) < 0.00001: eigen_val_0 = 0 d = c2 * c2 - 4.0 * c1 if d < 0.0: # no real roots ! THIS SHOULD NOT HAPPEN! d = 0.0 sd = ti.sqrt(d) eigen_val_2 = 0.5 * (c2 + sd) eigen_val_1 = 0.5 * (c2 - sd) else: s_inv3 = ti.cast(1.0 / 3.0, ti.f32) s_sqrt3 = ti.sqrt(3.0) c2_over_3 = c2 * s_inv3 a_over_3 = (c1 - c2 * c2_over_3) * s_inv3 if a_over_3 > 0: a_over_3 = 0 half_b = 0.5 * (c0 + c2_over_3 * (2 * c2_over_3 * c2_over_3 - c1)) q = half_b * half_b + a_over_3 * a_over_3 * a_over_3 if q > 0: q = 0 rho = ti.sqrt(-a_over_3) theta = ti.atan2(ti.sqrt(-q), half_b) * s_inv3 cos_theta = ti.cos(theta) sin_theta = ti.sin(theta) eigen_val_0 = c2_over_3 + 2 * rho * cos_theta eigen_val_1 = c2_over_3 - rho * (cos_theta + s_sqrt3 * sin_theta) eigen_val_2 = c2_over_3 - rho * (cos_theta - s_sqrt3 * sin_theta) temp_swap = ti.cast(0, ti.f32) # Sort in increasing order. if eigen_val_0 >= eigen_val_1: temp_swap = eigen_val_1 eigen_val_1 = eigen_val_0 eigen_val_0 = temp_swap if eigen_val_1 >= eigen_val_2: temp_swap = eigen_val_2 eigen_val_2 = eigen_val_1 eigen_val_1 = temp_swap if eigen_val_0 >= eigen_val_1: temp_swap = eigen_val_1 eigen_val_1 = eigen_val_0 eigen_val_0 = temp_swap if eigen_val_0 <= 0: eigen_val_0 = 0 d = c2 * c2 - 4.0 * c1 if d < 0.0: # no real roots ! THIS SHOULD NOT HAPPEN! d = 0.0 sd = ti.sqrt(d) eigen_val_2 = 0.5 * (c2 + sd) eigen_val_1 = 0.5 * (c2 - sd) # end of compute roots eigen_value = eigen_val_1 * scale # eigen value for 2D SDF # eigen value for 3D SDF #eigen_value = eigen_val_0 * scale #print("eigen_val_0 ", eigen_val_0) #print("eigen_val_1 ", eigen_val_1) #print("eigen_val_2 ", eigen_val_2) # TODO #scaledMat.diagonal ().array () -= eigenvalues (0) #eigenvector = detail::getLargest3x3Eigenvector<Vector> (scaledMat).vector; # Compute normal vector (TODO) #visual_norm[i,j][0] = eigen_val_0 #eigen_vector[0] #visual_norm[i,j][1] = eigen_val_1 #eigen_vector[1] #visual_norm[i,j][2] = eigen_val_2 #eigen_vector[2] # Compute the curvature surface change eig_sum = cov_mat_0 + cov_mat_1 + cov_mat_2 visual_curv[i,j][0] = 0 if eig_sum != 0: visual_curv[i,j][0] = eigen_val_1 # true curvature is: ti.abs(eigen_value / eig_sum)
def unspherical(dir): p = ti.atan2(dir.y, dir.x) / ti.tau return dir.z, p % 1
def complex_power(z, power: ti.i32): r = ti.sqrt(z[0]**2 + z[1]**2) theta = ti.atan2(z[1], z[0]) return ti.Vector( [r**power * ti.cos(power * theta), r**power * ti.sin(power * theta)])
def dir2tex(dir): dir = dir.normalized() s = ti.atan2(dir.z, dir.x) / ti.pi * 0.5 + 0.5 t = ti.atan2(dir.y, dir.xz.norm()) / ti.pi + 0.5 return V(s, t)
def foo(): y[None] = x[None]**2 z[None] = ti.atan2(y[None], 0.3)
def test_atan2(): grad_test(lambda x: ti.atan2(0.4, x), lambda x: np.arctan2(0.4, x)) grad_test(lambda y: ti.atan2(y, 0.4), lambda y: np.arctan2(y, 0.4))
def test_atan2_f64(): ti.set_default_fp(ti.f64) grad_test(lambda x: ti.atan2(0.4, x), lambda x: np.arctan2(0.4, x)) grad_test(lambda y: ti.atan2(y, 0.4), lambda y: np.arctan2(y, 0.4))