如何使用 drop shape function(Piriform Curve)对齐物体?

huangapple go评论63阅读模式
英文:

How to align object with drop shape function (Piriform Curve)

问题

I am trying to place the objects based on an equation, so let us say that I want to draw a circle.

Please check my codesandbox

so I use this function to get the coordinates of x and y..

const getCircleCoordinates = (angle, distance = 25) => {
    angle *= Math.PI / 180
    let x = distance * Math.cos(angle),
        y = distance * Math.sin(angle)

    return { x, y, angle, distance }
}

and this is my loop to place the objects.

let i = -1
const theta = 360 / (36)
return (
    <axesHelper args={[5, 5, 5]} />
    <Center>
        <group scale={scale}>
            {[...Array(36)].map((e, index) => {
                i++
                let { x, y, angle } = getCircleCoordinates(i * theta, hight, width)
                return (
                    <mesh
                        key={index}
                        scale-z={z}
                        position-x={x}
                        position-y={y}
                        rotation-x={Math.PI / 2}
                        rotation-y={angle}
                        lookAt={[0, 0, 0]}
                    >
                        <torusGeometry args={[radius, tube, radialSeg, tubSeg]} />
                        <meshNormalMaterial
                            color="red"
                        // wireframe
                        />
                    </mesh>
                )
            })}
        </group>
    </Center>
</>

Now my issue is with the rotation, in the circle the rotation was simply the angle in radian, but what If I want to draw a square or triangle?

In my case, I want to draw a drop..

and this is the function...

const getDropCoordinates = (angle, hight = 15, width = 5) => {
    angle *= Math.PI / 180
    let x = width * Math.cos(angle) * (1 + Math.sin(angle)),
        y = hight * (1 + Math.sin(angle))

    return { x, y, angle }
}
英文:

I am trying to place the objects based on an equation, so let us say that I want to draw a circle.

Please check my codesandbox

so I use this function to get the coordinates of x and y..

const getCircleCoordinates = (angle, distance = 25) =&gt; {
    angle *= Math.PI / 180
    let x = distance * Math.cos(angle),
        y = distance * Math.sin(angle)

    return { x, y, angle, distance }
}

and this is my loop to place the objects.

let i = -1
const theta = 360 / (36)
return &lt;&gt;
    &lt;axesHelper args={[5, 5, 5]} /&gt;
    &lt;Center&gt;
        &lt;group scale={scale}&gt;
            {[...Array(36)].map((e, index) =&gt; {
                i++
                let { x, y, angle } = getCircleCoordinates(i * theta, hight, width)
                return &lt;mesh
                    key={index}
                    scale-z={z}
                    position-x={x}
                    position-y={y}
                    rotation-x={Math.PI / 2}
                    rotation-y={angle}
                    lookAt={[0, 0, 0]}
                &gt;
                    &lt;torusGeometry args={[radius, tube, radialSeg, tubSeg]} /&gt;
                    &lt;meshNormalMaterial
                        color=&quot;red&quot;
                    // wireframe
                    /&gt;
                &lt;/mesh&gt;
            })}
        &lt;/group&gt;
    &lt;/Center&gt;
&lt;/&gt;

Now my issue is with the rotation, in the circle the rotation was simply the angle in radian, but what If I want to draw a square or triangle?

In my case, I want to draw a drop..

and this is the function...

const getDropCoordinates = (angle, hight = 15, width = 5) =&gt; {
    angle *= Math.PI / 180
    let x = width * Math.cos(angle) * (1 + Math.sin(angle)),
        y = hight * (1 + Math.sin(angle))

    return { x, y, angle }
}

答案1

得分: 0

根据prisoner849所说,这个函数将为下落形状获得正确的旋转值 - 似乎适用于所有形状。

  const getAngle = (nextCoordinates, previousCoordinates, x, y) => {
    let nextAngle = Math.atan2(nextCoordinates.y - y, nextCoordinates.x - x)
    let previousAngle = Math.atan2(previousCoordinates.y - y, previousCoordinates.x - x)

    return (nextAngle + previousAngle) / 2
  }

我编辑了我的循环如下:

{[...Array(36)].map((e, index) => {
            i++
            // let getShapeCoordinates = getCircleCoordinates
            let getShapeCoordinates = getDropCoordinates
            let { x, y } = getShapeCoordinates(i * theta, hight, width)
            let nextCoordinates = getShapeCoordinates((i + 1) * theta, hight, width)
            let previousCoordinates = getShapeCoordinates((i - 1) * theta, hight, width)
            let angle = getAngle(nextCoordinates, previousCoordinates, x, y)
            // consolesole.log(a)

            return (
              <mesh
                key={index}
                scale-z={z}
                position-x={x}
                position-y={y}
                rotation-x={Math.PI / 2}
                // 这里是我传递旋转的地方
                rotation-y={angle}>
                <torusGeometry args={[radius, tube, radialSeg, tubSeg]} />
                <meshNormalMaterial
                  color="red"
                  // wireframe
                />
              </mesh>
            )
          })}
英文:

According to

> You've got an array of points. Find the angle between two vectors, formed by (next - current) and (previous - current), multiply it with 0.5, rotate you mesh with this angle around Z-axis: i.imgur.com/2YFzU5W.png – prisoner849

this function will get the right rotation value for the drop shape - it seems to work with all shapes.

  const getAngle = (nextCoordinates, previousCoordinates, x, y) =&gt; {
    let nextAngle = Math.atan2(nextCoordinates.y - y, nextCoordinates.x - x)
    let previousAngle = Math.atan2(previousCoordinates.y - y, previousCoordinates.x - x)

    return (nextAngle + previousAngle) / 2
  }

I edited my loop to be

{[...Array(36)].map((e, index) =&gt; {
            i++
            // let getShapeCoordinates = getCircleCoordinates
            let getShapeCoordinates = getDropCoordinates
            let { x, y } = getShapeCoordinates(i * theta, hight, width)
            let nextCoordinates = getShapeCoordinates((i + 1) * theta, hight, width)
            let previousCoordinates = getShapeCoordinates((i - 1) * theta, hight, width)
            let angle = getAngle(nextCoordinates, previousCoordinates, x, y)
            // console.log(a)

            return (
              &lt;mesh
                key={index}
                scale-z={z}
                position-x={x}
                position-y={y}
                rotation-x={Math.PI / 2}
                // Here where I pass the rotation
                rotation-y={angle}&gt;
                &lt;torusGeometry args={[radius, tube, radialSeg, tubSeg]} /&gt;
                &lt;meshNormalMaterial
                  color=&quot;red&quot;
                  // wireframe
                /&gt;
              &lt;/mesh&gt;
            )
          })}

huangapple
  • 本文由 发表于 2023年2月19日 09:53:33
  • 转载请务必保留本文链接:https://go.coder-hub.com/75497527.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定