Draw straight line

Share on Twitter Share on Facebook Share on LinkedIn

Draw straight line

Description

As you've seen in the Shapes lesson, we can add a number of built in geometry shapes to our scene.

But how do you draw a straight line in ARKit?

If you check out the code sample below, you will be able to see that we can use a long thin cylindar to draw a straight line between two points.


Video


Code

using ARKit;
using SceneKit;
using UIKit;
using System;

namespace XamarinArkitSample
{
    public partial class StraightLineViewController : UIViewController, IARSCNViewDelegate
    {
        private readonly ARSCNView sceneView;
        private static readonly float lineRadius = 0.001f;
        private static readonly int radialSegments = 10;


        public StraightLineViewController()
        {
            this.sceneView = new ARSCNView
            {
                AutoenablesDefaultLighting = true,
                Delegate = this
            };

            this.View.AddSubview(this.sceneView);
        }

        public override void ViewDidLoad()
        {
            base.ViewDidLoad();
            this.sceneView.Frame = this.View.Frame;
        }

        public override void ViewDidAppear(bool animated)
        {
            base.ViewDidAppear(animated);


            this.sceneView.Session.Run(new ARWorldTrackingConfiguration
            {
                AutoFocusEnabled = true,
                LightEstimationEnabled = true,
                WorldAlignment = ARWorldAlignment.Gravity,
            }, ARSessionRunOptions.ResetTracking | ARSessionRunOptions.RemoveExistingAnchors); ;


            // Draw straight line
            DrawLineNode(new SCNVector3(0, 0, 0), new SCNVector3(0.1f, 0, 0), UIColor.Red);

            // Draw square with lines
            DrawLineNode(new SCNVector3(0.2f, 0, 0), new SCNVector3(0.3f, 0, 0), UIColor.Green); // Bottom line
            DrawLineNode(new SCNVector3(0.3f, 0, 0), new SCNVector3(0.3f, 0.1f, 0), UIColor.Green); // Right line
            DrawLineNode(new SCNVector3(0.2f, 0.1f, 0), new SCNVector3(0.3f, 0.1f, 0), UIColor.Green); // Top line
            DrawLineNode(new SCNVector3(0.2f, 0, 0), new SCNVector3(0.2f, 0.1f, 0), UIColor.Green);  // Left line

            // Draw cube with lines
            
            // Front Square
            DrawLineNode(new SCNVector3(0.4f, 0, 0), new SCNVector3(0.5f, 0, 0), UIColor.Blue); // Bottom line
            DrawLineNode(new SCNVector3(0.5f, 0, 0), new SCNVector3(0.5f, 0.1f, 0), UIColor.Blue); // Right line
            DrawLineNode(new SCNVector3(0.4f, 0.1f, 0), new SCNVector3(0.5f, 0.1f, 0), UIColor.Blue); // Top line
            DrawLineNode(new SCNVector3(0.4f, 0, 0), new SCNVector3(0.4f, 0.1f, 0), UIColor.Blue);  // Left line

            // Back Square
            DrawLineNode(new SCNVector3(0.4f, 0, -0.1f), new SCNVector3(0.5f, 0, -0.1f), UIColor.Blue); // Bottom line
            DrawLineNode(new SCNVector3(0.5f, 0, -0.1f), new SCNVector3(0.5f, 0.1f, -0.1f), UIColor.Blue); // Right line
            DrawLineNode(new SCNVector3(0.4f, 0.1f, -0.1f), new SCNVector3(0.5f, 0.1f, -0.1f), UIColor.Blue); // Top line
            DrawLineNode(new SCNVector3(0.4f, 0, -0.1f), new SCNVector3(0.4f, 0.1f, -0.1f), UIColor.Blue);  // Left line

            // Joining Front Square with Back Square
            DrawLineNode(new SCNVector3(0.4f, 0, 0), new SCNVector3(0.4f, 0, -0.1f), UIColor.Blue); 
            DrawLineNode(new SCNVector3(0.5f, 0f, 0), new SCNVector3(0.5f, 0f, -0.1f), UIColor.Blue);
            DrawLineNode(new SCNVector3(0.4f, 0.1f, 0), new SCNVector3(0.4f, 0.1f, -0.1f), UIColor.Blue);
            DrawLineNode(new SCNVector3(0.5f, 0.1f, 0), new SCNVector3(0.5f, 0.1f, -0.1f), UIColor.Blue);
        }

        public void DrawLineNode(SCNVector3 pointA, SCNVector3 pointB, UIColor color)
        {
            var distance = DistanceBetweenPoints(pointA, pointB);
            var line = DrawCylinderBetweenPoints(pointA, pointB, distance, lineRadius, radialSegments, color);
            line.Look(pointB, sceneView.Scene.RootNode.WorldUp, line.WorldUp);

            this.sceneView.Scene.RootNode.AddChildNode(line);
        }

        public static SCNNode DrawCylinderBetweenPoints(SCNVector3 a, SCNVector3 b, nfloat length, nfloat radius, int radialSegments, UIColor color)
        {
            var material = new SCNMaterial();
            material.Diffuse.Contents = color;

            SCNNode cylinderNode;
            SCNCylinder cylinder = new SCNCylinder();
            cylinder.Radius = radius;
            cylinder.Height = length;
            cylinder.RadialSegmentCount = radialSegments;
            cylinderNode = SCNNode.FromGeometry(cylinder);
            cylinderNode.Position = GetMidpoint(a, b);
            cylinderNode.Geometry.FirstMaterial = material;

            return cylinderNode;
        }

        public static nfloat DistanceBetweenPoints(SCNVector3 a, SCNVector3 b)
        {
            SCNVector3 vector = new SCNVector3(a.X - b.X, a.Y - b.Y, a.Z - b.Z);
            return (nfloat)Math.Sqrt(vector.X * vector.X + vector.Y * vector.Y + vector.Z * vector.Z);
        }

        public static SCNVector3 GetMidpoint(SCNVector3 a, SCNVector3 b)
        {
            float x = (a.X + b.X) / 2;
            float y = (a.Y + b.Y) / 2;
            float z = (a.Z + b.Z) / 2;

            return new SCNVector3(x, y, z);
        }

        public override void ViewDidDisappear(bool animated)
        {
            base.ViewDidDisappear(animated);

            foreach (var node in this.sceneView.Scene.RootNode.ChildNodes)
            {
                node.RemoveFromParentNode();
            }

            this.sceneView.Session.Pause();
        }       
    }
}

Next Step : Looking at gaze

After you have mastered this you should try Looking at gaze