var tag = CreatedFrom.Tag;
var taggedElement = tag.Document.GetElement(tag.GetTaggedReference());
var taggedElementBbx = taggedElement.get_BoundingBox(tag.Document.ActiveView);
hostMaxbbx = taggedElementBbx.Max;
hostMinbbx = taggedElementBbx.Min;
hostTopMid = new XYZ((hostMaxbbx.X + hostMinbbx.X) / 2, hostMaxbbx.Y, tag.TagHeadPosition.Z);
hostLowerMid = new XYZ((hostMaxbbx.X + hostMinbbx.X) / 2, hostMinbbx.Y, tag.TagHeadPosition.Z);
hostLeftMid = new XYZ(hostMinbbx.X, (hostMaxbbx.Y + hostMinbbx.Y) / 2, tag.TagHeadPosition.Z);
hostRightMid = new XYZ(hostMaxbbx.X, (hostMaxbbx.Y + hostMinbbx.Y) / 2, tag.TagHeadPosition.Z);
var tagBbx = tagBounding.BoundingBox;
tagMaxbbx = tagBbx.Max;
tagMinbbx = tagBbx.Min;
tagTopMid = new XYZ((tagMaxbbx.X + tagMinbbx.X) / 2, tagMaxbbx.Y, tag.TagHeadPosition.Z);
tagLowerMid = new XYZ((tagMaxbbx.X + tagMinbbx.X) / 2, tagMinbbx.Y, tag.TagHeadPosition.Z);
tagLeftMid = new XYZ(tagMinbbx.X, (tagMaxbbx.Y + tagMinbbx.Y) / 2, tag.TagHeadPosition.Z);
tagRightMid = new XYZ(tagMaxbbx.X, (tagMaxbbx.Y + tagMinbbx.Y) / 2, tag.TagHeadPosition.Z);
tagBbxPoints = new List<PositionXYZ>()
{new PositionXYZ(){xyz= tagLeftMid,position=Position.LeftMid },
new PositionXYZ(){xyz= tagTopMid, position=Position.TopMid},
new PositionXYZ(){xyz= tagRightMid, position=Position.RightMid},
new PositionXYZ(){ xyz= tagLowerMid ,position=Position.LowerMid}};
hostBbxPoints = new List<PositionXYZ>()
{new PositionXYZ(){xyz= hostLeftMid,position=Position.LeftMid },
new PositionXYZ(){xyz= hostTopMid, position=Position.TopMid},
new PositionXYZ(){xyz= hostRightMid, position=Position.RightMid},
new PositionXYZ(){ xyz= hostLowerMid ,position=Position.LowerMid}};
public PositionXYZ ClosestPoint(ElemType elemType)
{
var combinedDistData = hostBbxPoints.SelectMany(h =>
{
return tagBbxPoints.Select(t =>
{
return new { host = h, tag = t, dist = t.xyz.DistanceTo(h.xyz) };
});
});
var closest = combinedDistData.OrderBy(x => x.dist).FirstOrDefault();
if (elemType is ElemType.Host)
return closest.host;
else
return closest.tag;
}
public PositionXYZ ClosestPoint(ElemType elemType, XYZ otherPoint)
{
var hostPoint = hostBbxPoints.OrderBy(x => x.xyz.DistanceTo(otherPoint)).FirstOrDefault();
var tagPoint = tagBbxPoints.OrderBy(x => x.xyz.DistanceTo(otherPoint)).FirstOrDefault();
if (elemType is ElemType.Host)
return hostPoint;
else
return tagPoint;
}
This are the methods I'm using to calculate the starting and end position.
Where taggedElementBbx is the Host Elements Bounding Box
and TagBbx is taken by temporary transaction and turning off the leader then taking the bounding box.
Other Point I'm giving when leader elbow is available, It's working for attached end geometry as well.
Just don't know why some cases are giving anomalies.