# How to create a coordinate system in Discovery/SpaceClaim based on 3 points coordinates?

Member, Employee Posts: 82
✭✭✭✭
edited April 25

For doing some mapping in Mechanical it might be useful to create a coordinate system based on source points. This coordinate system will have the origin on the first point, its x-axis will go from 1 to 2 point and the z-axis will be normal to the plane defined by the 3 points.

Tagged:

• Member, Employee Posts: 82
✭✭✭✭
edited April 25

This might come in handy for users who are importing data coming from injection molding software with an input mesh that cannot be read by External Model or if we want to avoid having to use the assembly approach in Workbench.
We use this solution posted for making sure that the document has mm as units (the input is assumed to be in mm). Here the script:

```# Point 1 CS origin
# Point 1-2 x axis
# z axis normal to plane
import os
import math

# Here the script for setting mm as units
version = dir(SpaceClaim.Api)[-1]
cmd = 'from SpaceClaim.Api.{} import *'.format(version)
exec(cmd)
doc = Window.ActiveWindow.Document
doc.Units.ActiveUnitsSystem = UnitsSystemType.Metric
doc.Units.MetricUnits = MetricUnits(MetricLengthUnit.Millimeters,MetricMassUnit.Kilograms, AngleUnit.Degrees)

def dot_product(vector1, vector2):
return sum(a * b for a, b in zip(vector1, vector2))

def magnitude(vector):
return math.sqrt(sum(component**2 for component in vector))

def angle_between_vectors(vector1, vector2):
dot_product_value = dot_product(vector1, vector2)
magnitude_product = magnitude(vector1) * magnitude(vector2)

cos_theta = max(min(dot_product_value / magnitude_product, 1.0), -1.0)

return angle_degrees

#######################################################
# Input by user
# Point 1 / Point 2 / Point 1 / Point 3 coordinates in mm
points = [[x1,y1,z1],[x2,y2,z2],[x1,y1,z1],[x3,y3,z3]]
##
# Here it is created a file to import these points and create curves
points_SCDM = []
[points_SCDM.append([point[2],point[0],point[1]]) for point in points]
path = os.path.dirname(GetActiveWindow().Document.Path)
myfile = os.path.join(path,'Curve.txt')
with open(myfile, "w") as file:
file.write("polyline=false\n")
file.write("3d=true\n")
for i, array in enumerate(points_SCDM):
line = " ".join(str(value) for value in array)
line += "\n"
if i % 2 == 1 and i != len(points_SCDM) - 1:
line += "\n"
file.write(line)
file.write("\n")
DocumentInsert.Execute(myfile)

os.remove(myfile)

# A plane is created normal to the 3 given points
CurvesSelection = Selection.Create(GetRootPart()).ConvertToCurves()
origin = CurvesSelection.Items[0].EvalStart().Point
Curve_1 = CurvesSelection.Items[0]
Curve_2 = CurvesSelection.Items[1]
x_Dir = Curve_1.EvalEnd().Point.Vector- Curve_1.EvalStart().Point.Vector
result = DatumPlaneCreator.Create(CurvesSelection, True, None)
Plane_Ref = result.CreatedPlanes[0]
DirZ_Plane = Plane_Ref.Shape.Geometry.Frame.AxisZ.Direction

# A CS is created
CS_Ref = DatumOriginCreator.Create(origin,Plane_Ref.Shape.Geometry.Frame.AxisZ.Direction,None).CreatedOrigin

# Angle is calculated between x-axis from CS and x-axis given by points 1-2
x_axis = CS_Ref.Axes[0].Shape.Geometry.Direction.UnitVector
x_Dir = Curve_1.EvalEnd().Point.Vector- Curve_1.EvalStart().Point.Vector
vector1 = [x_axis[0],x_axis[1],x_axis[2]]
vector2 = [x_Dir[0],x_Dir[1],x_Dir[2]]
angle = angle_between_vectors(vector1, vector2)

# Align x axis with points 1-2
selection = Selection.Create(CS_Ref)
axis = CS_Ref.Axes[2].Shape.Geometry
options = MoveOptions()
result = Move.Rotate(selection, axis, DEG(angle), options, None)
# EndBlock

Delete.Execute(CurvesSelection)
Delete.Execute(Selection.Create(Plane_Ref))
```
• Member, Employee Posts: 287
✭✭✭✭

@Jimmy He Can we update the Coordinate System tool to include SpaceClaim and Discovery?

• Member, Employee Posts: 82
✭✭✭✭
edited April 25

Hello @Landon Mitchell Kanner ,
I verified that this script works in Discovery too, so I modified the title. I also included a verification of units based on your post.