- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
Good afternoon, All,
When someone has a minute, if they could help me out or point me in the right direction I would appreciate it.
First, I am running Revit 2018.2, and I am dealing with Taps connected to straight pieces of duct or pipe.
I am disconnecting the taps and saving off connection information to reconnect after some processing, and I am only running into one issue - the current tap rotation around the host duct/pipe.
I have found endless articles on how to rotate objects, or get rotation around one of the base axes, but I am not understanding how to tweak these to fit my need.
I don't want rotation around any of the base axes, all I want is the current rotation around the vector of the host part centerline.
By manually setting the rotation to a value of Pi/2, I have succeeded in making it work for when the duct is facing up, down, left, or right by comparing the host direction to the different view directions, and could probably continue to figure out the values for when the host direction matches ViewDirection or ViewDirection.Negate(), but if the duct or pipe is skewed even a little bit it doesn't work.
In trig there is a way to calculate the angle given an origin, a known point on the circle, and another point that also exists on the circle.
I am trying to apply that formula - but I am not figuring out how to get the proper unit vectors to use.
Here is what I have (see code below):
The vector to the tap connector origin from the host centerline
The host centerline vector (I can get the vector on the host that aligns with where the tap vector starts)
What I cannot determine (in bold):
The correct unit vectors to use to call unknownVector.AngleOnPlaneTo(unknownRightDirection, hostVector.Direction)
The only axis of rotation I am worried about is the host vector itself, not any of the base axes.
I am not even moving the tap or the host, I just want to reconnect it, and that requires calling FabricationPart.PlaceAsTap() which calls for two potential rotations (I only need the first one, the other spins the tap in place I believe).
Any help would be appreciated.
Thanks,
Matt
Code:
var hostCon1Id = 0;
var hostCon1 = conManager.Lookup(hostCon1Id);
var hostCon2Id = 1;
var hostCon2 = conManager.Lookup(hostCon2Id);
var hostCenterLine = Line.CreateBound(hostCon1.Origin, hostCon2.Origin);
var hostDirection = hostCenterLine.Direction;
var tap = connectedPart;
var tapCon = connectedConnector;
var tapCon1Origin = tapCon.Origin;
var tapCon2Id = tapCon.Id == 0 ? 1 : 0;
var tapCon2 = tap.ConnectorManager.Lookup(tapCon2Id);
var tapCon2Origin = tap.ConnectorManager.Lookup(tapCon2Id).Origin;
var a = hostCenterLine.Distance(tapCon.Origin);
var c = (hostCon1.Origin - tapCon.Origin).GetLength();
var b = Math.Sqrt((Math.Pow(c, 2) - Math.Pow(a, 2)));
var distanceToTapCon = Math.Abs(b);
var vectorToTapConDir = Line.CreateBound(hostCenterLine.Evaluate(distanceToTapCon, false), tapCon1Origin).Direction;
var viewDir = doc.ActiveView.ViewDirection;
var viewRightDir = doc.ActiveView.RightDirection;
var viewUpDir = doc.ActiveView.UpDirection;
var tapRotation1 = 0.0;
//(Matt) these work if the host direction lines up with view directions
//if (hostDirection.IsAlmostEqualTo(viewUpDir))
// tapRotation1 = viewRightDir.Negate().AngleOnPlaneTo(vectorToTapConDir, viewUpDir);
//else if (hostDirection.IsAlmostEqualTo(viewUpDir.Negate()))
// tapRotation1 = viewRightDir.AngleOnPlaneTo(vectorToTapConDir, viewUpDir.Negate());
//else if (hostDirection.IsAlmostEqualTo(viewRightDir))
// tapRotation1 = viewUpDir.AngleOnPlaneTo(vectorToTapConDir, viewRightDir);
//else if (hostDirection.IsAlmostEqualTo(viewRightDir.Negate()))
//
Solved! Go to Solution.