# Retrieve coordinates relative to arbitrary coordinate system (Geom::Transformation.axes method)

I’m struggling with the Axes class in Sketchup Ruby. I’m not sure if I understand it’s capabilities. I want to define a custom Arbitrary Coordinate System relative to the active group. Let’s say the group is a square, flat on the XY plane of the World Coordinate System for example’s sake. Lets say there is one circle on a random corner of the square, centered on that corner’s vertex. I want to use the Geom::Transformation.axes method to ‘view’ the square from outside of the square itself, so that the Y axis of my Arbitrary Coordinate System always points toward the center of the square and is parallel to the XY plane of the World Coordinate System as well (World and Arbitrary Z axes are parallel and point in the same direction). I Hope that is clear so far.

As I circle around the outside of the square, I want to retrieve the coordinates of the circled vertex relative to the Arbitrary Coordinate System, not the World Coordinate System. But it seems I always retrieve the coordinates relative to the World Coordinate System (I get the correct coordinates, just the wrong sign half the time). For instance, if I circle around the square from any point to another point 180 degrees around (World), the sign of the X coordinate should change for my purposes, but I am unable to accomplish that. I always seem to get the same sign. The reason I believe the signs should change is because my Y axis should always be pointing toward the center of the square.

Here’s what I got. My code is not accomplishing my goal. I get the correct vector length and absolute direction (signed) I want but the sign is not always right. vert1 and vert2 are set up to always be two points directly on the x axis of the arbitrary coordinate system so that the circled vertex is always to either one side or the other of the Y axis. vert1.y = vert2.y and ver1.x = -(vert2.x). (My code always ensures the circled vertex is never bisected by the Y axis of the Arbitrary Coordinate System.)

``````def perp_2(vert1, vert2, edge1)
# vert1 and vert2 are not necessarily on edge1
# edge1 is there only to reference the group's face

# set up to always point the Y axis perpendicular to the edge formed by vert1 and vert2
face = edge1.faces[0]
ang = 90.degrees
ang = -ang if edge1.reversed_in?(face)

start_pt = vert1.position
end_pt = vert2.position

# get the vector perpendicular to the line between the two vertices relative to the face of edge1.
vector1 = start_pt.vector_to end_pt
len_v = vector1.clone
len_v.length = len_v.length / 2
# find the center of the line
center = start_pt.offset(len_v)

puts 'start_pt 1' + start_pt.to_s
puts 'center 1' + center.to_s
# finally get the transformation ...
vector_trans = Geom::Transformation.rotation(center, face.normal, ang)
# ...and the vector pependicular to the line
vector2 = vector1.transform(vector_trans)

# vector2 becomes the Y axis, the vector of the line is the X axis, the center of the line is the origin.
tr = Geom::Transformation.axes(center, vector1, vector2, Z_AXIS)

# try to retrieve the vector to start_pt from the origin
start_pt.transform!(tr)
center.transform!(tr)

puts 'start_pt 2' + start_pt.to_s
puts 'center 2' + center.to_s
# the vector should be relative to the Y axis of tr, but something is wrong
vector2 = center.vector_to(start_pt)

# return the vector...fails to change signs
return vector2

end

``````

First, can the Geom::Transformation.axes method do what I am asking of it? If so, what am I doing wrong/missing?

Thanks for any help you can give me, I appreciate your time.

I don’t really understand your description, what do you want to do and why… some pictures (screenshots with notes on it) and example model would be better to use for explanation.

What I noticed is that depending on where you rotate (+ or - 90°) `vector1` (x axis) to get `vector2`, the `vector1` (x axis), `vector2` (y axis) and the “constant” Z_AXIS can form a non-normal axis order/direction. (I’m not sure if that is matter…)

I would rather calculate `vector2` (y axis) using the cross product method.

``````vector2 = Z_AXIS * vector1
``````
1 Like

The construction line divides the two scenarios. The Arbitrary Axes are represented by the thick red and green lines in each scenario. The world Axes are shown as well (thinner red and green lines). In both cases, vector2 should be positive. edge is any random edge.

Firstly, this class is a singleton class. Meaning you cannot instantiate unattached instances for your own use.
Only `Sketchup::Model` objects can “own” a single `Sketchup::Axes` instance which our extensions access via the `Sketchup::Model#axes` getter method.

Secondly, the Ruby API almost always returns coordinates relative to the model’s non-modifiable “world” origin, referenced as the global constant `ORIGIN`, in `Length` inch values.

When a user uses the Axes tool to move the Drawing Axes the model `ORIGIN`, `X_AXIS`, `Y_AXIS` and `Z_AXIS` remain unchanged. (Do not change these global constants because it will cause havoc with other extensions!) This means that the Model Axes is distinct from the Drawing Axes, (the latter being similar to AutoCAD’s UCS.)

So, …

(1) Native SketchUp tool code is written to adjust to the transformation of the current Drawing Axes.
See: `Sketchup::Axes#transformation()` and it’s code example.

(2) Ruby extension tool code does NOT automatically adjust to the Drawing Axes if it differs from the Model Axes. Extension code must explicitly adjust to the current drawing axes transformation.

Given (2), I do not see your code snippet applying the transformation of the current Drawing Axes.

2 Likes

Thank you both for your time and efforts, I really appreciate it.

1 Like