从顶点U,V的三角形中推导出U,V

时间:2013-06-18 08:44:41

标签: python geometry raytracing cgkit

我正在使用CGKitRTree在python中编写一个非常简单的光线跟踪器。在使光线与三角形相交后,我想推断出顶点的U,V的交点的U,V。这样做的适当方法是什么?

目前我正在使用距离相对边缘的加权平均值,如下所示。除了CGKit相关的东西,我有3个顶点v1,v2,v3和3个UV的vt1,vt2,vt3。 hit_p是CGKit交集返回的三角形上的xyz点。

def extract_hit_vt(tri_geom, tri_vt,hit_p, oa_face):

    hit_face = tri_geom.faces[oa_face]

    vt1 = np.array(vec3(tri_vt[oa_face * 3]))
    vt2 = np.array(vec3(tri_vt[oa_face * 3 + 1]))
    vt3 = np.array(vec3(tri_vt[oa_face * 3 + 2]))

    v1 = tri_geom.verts[hit_face[0]]
    v2 = tri_geom.verts[hit_face[1]]
    v3 = tri_geom.verts[hit_face[2]]

    d1 = ptlined(v2, v3, hit_p)
    d2 = ptlined(v3, v1, hit_p)
    d3 = ptlined(v1, v2, hit_p)

    hit_vt = (d1*vt1+d2*vt2+d3*vt3)/(d1+d2+d3)

    return hit_vt

2 个答案:

答案 0 :(得分:4)

这是从LuxRays(http://src.luxrender.net/luxrays)获取的代码。获得重心坐标:

static bool GetBaryCoords(const Point &p0, const Point &p1, const Point &p2,
        const Point &hitPoint, float *b1, float *b2) {
    const Vector u = p1 - p0;
    const Vector v = p2 - p0;
    const Vector w = hitPoint - p0;

    const Vector vCrossW = Cross(v, w);
    const Vector vCrossU = Cross(v, u);

    if (Dot(vCrossW, vCrossU) < 0.f)
        return false;

    const Vector uCrossW = Cross(u, w);
    const Vector uCrossV = Cross(u, v);

    if (Dot(uCrossW, uCrossV) < 0.f)
        return false;

    const float denom = uCrossV.Length();
    const float r = vCrossW.Length() / denom;
    const float t = uCrossW.Length() / denom;

    *b1 = r;
    *b2 = t;

    return ((r <= 1.f) && (t <= 1.f) && (r + t <= 1.f));
}

p0,p1,p2是三角形顶点,hitPoint是光线/三角形交点,b1,b2返回重心坐标。 一旦你有了b1,b2,就可以得到插值(u,v)值:

const float b0 = 1.f - b1 - b2;
const u = b0 * u_v0 + b1 * u_v1 + b2 * u_v2;
const v = b0 * v_v0 + b1 * v_v1 + b2 * v_v2;

其中u_v0,v_v0等是三角形顶点的(u,v)坐标。

答案 1 :(得分:0)

要决定的主要是你想要在三角形中插入UV的确切程度。既然你说你只有三个点,那么你不太可能比简单的线性插值更好。

在这种情况下,您需要三角形内部点的重心坐标:http://en.wikipedia.org/wiki/Barycentric_coordinate_system

简而言之,三角形内部的每个点都可以表示为顶点的加权和,其中每个权重都在0到1之间。权重可以通过求解2x2线性方程组来找到。

当你有这些权重时,可以使用它们来获得UV坐标的加权和。