25

タイプ SCNVector3 の 2 つのポイント (pointA と pointB と呼びましょう) があります。私はそれらの間に線を引きたい。簡単なように思えますが、それを行う方法が見つかりません。

2 つのオプションが表示されますが、どちらにも問題があります。

半径が非常に小さく、長さが |pointA-pointB| の SCNCylinder を使用します。配置/回転します。

カスタム SCNGeometry を使用しますが、方法がわかりません。おそらく非常に薄い長方形を形成するには、2 つの三角形を定義する必要がありますか?

これを行う簡単な方法があるはずですが、見つけられないようです。

編集:三角形の方法を使用すると、(0,0,0) と (10,10,10) の間に線を引くために次のようになります。

CGFloat delta = 0.1;
SCNVector3 positions[] = {  SCNVector3Make(0,0,0),
    SCNVector3Make(10, 10, 10),
    SCNVector3Make(0+delta, 0+delta, 0+delta),
    SCNVector3Make(10+delta, 10+delta, 10+delta)};
int indicies[] = {
    0,2,1,
    1,2,3
};

SCNGeometrySource *vertexSource = [SCNGeometrySource geometrySourceWithVertices:positions count:4];
NSData *indexData = [NSData dataWithBytes:indicies length:sizeof(indicies)];
SCNGeometryElement *element = [SCNGeometryElement geometryElementWithData:indexData primitiveType:SCNGeometryPrimitiveTypeTriangles primitiveCount:2 bytesPerIndex:sizeof(int)];
SCNGeometry *line = [SCNGeometry geometryWithSources:@[vertexSource] elements:@[element]];

SCNNode *lineNode = [SCNNode nodeWithGeometry:line];
[root addChildNode:lineNode];

しかし、問題があります。法線が原因で、この線は片側からしか見えません! 向こうからは見えません。また、「デルタ」が小さすぎると、線がまったく見えなくなります。そのままでは、技術的には、目的の線ではなく長方形であり、複数の結合された線を描画したい場合、小さなグラフィックの不具合が発生する可能性があります.

4

7 に答える 7

20

Swift での簡単な拡張は次のとおりです。

extension SCNGeometry {
    class func lineFrom(vector vector1: SCNVector3, toVector vector2: SCNVector3) -> SCNGeometry {
        let indices: [Int32] = [0, 1]

        let source = SCNGeometrySource(vertices: [vector1, vector2])
        let element = SCNGeometryElement(indices: indices, primitiveType: .Line)

        return SCNGeometry(sources: [source], elements: [element])

    }
}
于 2016-06-18T12:11:19.997 に答える
15

これを行う方法はたくさんあります。

前述のように、カスタム ジオメトリ アプローチにはいくつかの欠点があります。doubleSidedマテリアルにプロパティを与えることで、片側から見えないという問題を修正できるはずです。ただし、2 次元であることに問題がある場合もあります。

カスタム ジオメトリを変更してより多くの三角形を含めることもできます。これにより、平らな長方形ではなく、3 つ以上の側面を持つチューブ形状が得られます。または、ジオメトリ ソースに 2 つのポイントを配置し、SCNGeometryPrimitiveTypeLineジオメトリ要素タイプを使用してシーン キットにそれらの間に線分を描画させます。(ただし、シェーディング ポリゴンの場合ほど、線画を使用したレンダリング スタイルの柔軟性は得られません。)

SCNCylinderあなたが言及したアプローチ(または他の組み込みのプリミティブ形状)を使用することもできます。ジオメトリは独自のローカル (別名モデル) 座標空間で定義されることに注意してください。シーン キットは、ノードによって定義された座標空間に対して相対的に解釈します。つまり、すべての次元で幅が 1.0 単位の円柱 (またはボックス、カプセル、平面など) を定義し、SCNNodeそのジオメトリを含む の回転/スケール/位置または変換を使用して、それを長く、薄く、そして必要な 2 点間でストレッチします。(また、線がかなり細くなるので、使用している組み込みジオメトリの s を減らすことができることに注意してくださいsegmentCount。それほど詳細が表示されないためです。)

さらに別のオプションはSCNShape、2D ベジエ パスから押し出された 3D オブジェクトを作成できるクラスです。任意の 2 点を結ぶ平面を取得するための適切な変換を行うのは、楽しい数学のように思えますが、一度実行すると、選択した任意の形状の線で点を簡単に接続できます。

于 2014-02-19T19:03:02.273 に答える
10

以下の (0, 0, 0) から (10, 10, 10) までの行の新しいコード。さらに改善できるかどうかはわかりません。

SCNVector3 positions[] = {
    SCNVector3Make(0.0, 0.0, 0.0),
    SCNVector3Make(10.0, 10.0, 10.0)
};

int indices[] = {0, 1};

SCNGeometrySource *vertexSource = [SCNGeometrySource geometrySourceWithVertices:positions
                                                                          count:2];

NSData *indexData = [NSData dataWithBytes:indices
                                   length:sizeof(indices)];

SCNGeometryElement *element = [SCNGeometryElement geometryElementWithData:indexData
                                                            primitiveType:SCNGeometryPrimitiveTypeLine
                                                           primitiveCount:1
                                                            bytesPerIndex:sizeof(int)];

SCNGeometry *line = [SCNGeometry geometryWithSources:@[vertexSource]
                                            elements:@[element]];

SCNNode *lineNode = [SCNNode nodeWithGeometry:line];

[root addChildNode:lineNode];
于 2014-02-19T20:31:39.093 に答える