混合在同一个形状和一个具有相同原点的完美圆之间?

2024-09-30 08:36:37 发布

您现在位置:Python中文网/ 问答频道 /正文

我目前正在为一个计算机程序编写一个3D着色器,我遇到了一个小问题,希望有人能帮我解决。你知道吗

明暗器设计用于在2D空间中生成N面形状。驱动着色器的3D程序基本上会传递一组x,y坐标(以0,0为中心),并期望您输出适当的颜色。我已经编写了着色器中生成这些形状的部分,效果很好。我遇到的问题是在这些形状的边上添加“曲率”,基本上是完美圆和N边多边形之间的混合。你知道吗

着色器当前的工作方式如下所示:

1)我算出N边形状的单个段的角度:

segmentAngle = (math.pi * 2) / numberOfSides

1)我将问题分解为一个直角三角形,它使用以下等式:

pAngle = abs((math.atan2(y, x) % segmentAngle) - (segmentAngle / 2))
pDist1 = math.sqrt((x * x) + (y * y))

2)我计算从N边形状的原点到边的距离,穿过着色器给定的坐标:

pDist2 = (math.cos(segmentAngle / 2) * radius) / math.cos(pAngle)

其中半径通常为0.5。然后,如果pDist1是>;pDist2,则着色器返回一种颜色,否则返回另一种颜色。这使我能够成功地绘制任意边数的N边形状。你知道吗

这就是事情变得棘手的地方。。。我还需要一个选项,其中“融合”之间的N面形状和一个完美的圆(有相同的半径为N面形状)。最初,我认为我可以通过简单地修改pDist2来做到这一点,如下所示:

pDist2 = ((radius - pDist2) * curvature) + pDist2)

其中曲率是介于0和1之间的值(表示0%到100%)。这根本不起作用,相反,我得到了一个奇怪的波浪边,我相信这和我的角度以及pDist2和圆半径之间的差异有关。从理论上讲,假设pAngle指向多边形一侧的正中心,它应该是可行的,但当它接近一个角时,事情似乎变得越来越扭曲。你知道吗

我怎样才能解决这个问题?根据pAngle和(segmentAngle/2)之间的差异,似乎应该有一些相当简单的公式来修正pDist2,但我似乎不知道应该是什么。你知道吗

示意图:

enter image description here


Tags: 颜色半径mathcos多边形中心角度形状
1条回答
网友
1楼 · 发布于 2024-09-30 08:36:37

这里有一个解决方案,但您必须将测试更改为pDist1 > pDist2以外的内容:

segmentAngle = (math.pi * 2) / numberOfSides
pRawAngle = math.atan2(y, x)
pAngle = abs((pRawAngle % segmentAngle) - (segmentAngle / 2))
pEdgeAngle = pRawAngle - pAngle
pDistanceToEdge = radius * (math.cos(segmentAngle / 2) * radius)
pEdgeVectorX = math.cos(pEdgeAngle)
pEdgeVectorY = math.sin(pEdgeAngle)
pEdgeDot = (x * edgeVectorX) + (y * edgeVectorY)

if pEdgeDot > pDistanceToEdge:        
    pOutsideDistance = pEdgeDot - pDistanceToEdge
    x -= pEdgeVectorX * pOutsideDistance
    y -= pEdgeVectorY * pOutsideDistance
    if curvature > 0:
        pOutsideDistance /= curvature
    x += pEdgeVectorX * pOutsideDistance
    y += pEdgeVectorY * pOutsideDistance

pDist1 = math.sqrt((x * x) + (y * y))

if pDist1 > radius:
    # color one color
else
    # color the other color

此代码将N边多边形的每条边展开为一个沿边法线方向的圆。计算最近边的边角,并用于计算从原点到边中心的距离(取到多边形角点的半径)和法向量。你知道吗

然后取x,y点和边法线的点积,看它是否在多边形之外。如果是,则它计算出它在外的距离,然后根据曲率在边法线方向上调整该量。然后对调整后的点进行点对半径测试。你知道吗

另一种方法是使用初始方程,但改变pDist2的计算方式如下:

segmentAngle = (math.pi * 2) / numberOfSides
pAngle = abs((math.atan2(y, x) % segmentAngle) - (segmentAngle / 2))
pDist1 = math.sqrt((x * x) + (y * y))
if curvature < 1.0:
    pCurvatureAdjustment = (1 / (1.0 - curvature)) - 1.0
    pDist2 = ((math.cos(segmentAngle / 2) + pCurvatureAdjustment) * radius) / (math.cos(pAngle) + pCurvatureAdjustment)
else
    pDist2 = radius

希望这能让你的渐变着色后。你知道吗

如果特别希望在多边形和圆之间沿边法线方向进行线性混合,则需要更精确的计算

pCurvatureAdjustment = ((1 / (1.0 - curvature)) - 1.0) * math.cos(pAngle)

相关问题 更多 >

    热门问题