Texture positioning error

Texture positioning always fails, help me see if the code has errors, trouble to help point out, thanks

m = mat.add "spv"
m.texture = path
module_long = 2.m
module_wide = 1.m
size = m.texture.size = [module_long, module_wide]
pts = []
pts[0] = [0.m,0.m,0.m]
pts[1] = [21.m,0.m,0.m]
pts[2] = [21.m,11.5.m,0.m]
pts[3] = [0.m,11.5.m,0.m]
face = ent.add_face pts

tw = Sketchup.create_texture_writer
uv_helper = face.get_UVHelper(true, true, tw)
p0 = Geom::Point3d.new(21.m,0.m,0.m)
uvq = uv_helper.get_back_UVQ(p0)
u = uvq.x / uvq.z
v = uvq.y / uvq.z
q = uvq.z
p [u,v,q]
mapping = []
mapping[0] = Geom::Point3d.new(21.m,0.m,0.m)
mapping[1] = Geom::Point3d.new(u.m,v.m,q.m)
face.position_material("spv", mapping, true)
face.position_material("spv", mapping, false)

When I try to locate the point in the lower right corner, it always fails, and there is always an extra piece next to it。I shouldn’t really understand the relevant commands

If you are not going to export the texture, then you do not need the texture writer.
Also the first 2 arguments default to true, so …

uv_helper = face.get_UVHelper

To normalize UVQ coordinates to UV, after dividing by q (or z), you need to discard q (ie z) and use 0 as the last coordinate.

Also, UVHelper.html#get_back_UVQ returns coordinates in inches, not meters.
Your setting mapping[1] x to inches number of meters again. Same for y.

I think you need this:

mapping[1] = Geom::Point3d.new(u, v, 0)
# NOT mapping[1] = Geom::Point3d.new(u.m, v.m, 0)

Now in your code you are getting the UVHelper before you have applied and positioned the material. This will likely return default UV coordinates.

Normally the UVHelper is used after a texture is positioned to find out how the texture is positioned on the face.