Ok, I resolved my own problem but I'll post the code here in case anyone comes across this in the future.
foreach (FamilyInstance instance in famInstances)
{
if (instance.ViewSpecific != true)
{
Location instLocation = instance.Location;
LocationPoint instLocPt = instLocation as LocationPoint;
Double instRotationRad = instLocPt.Rotation;
double instRotationDeg = UnitUtils.ConvertFromInternalUnits(instRotationRad, DisplayUnitType.DUT_DECIMAL_DEGREES);
// Collect 4x corners of symbol Bbox
BoundingBoxXYZ symBox = instance.Symbol.get_BoundingBox(doc.ActiveView);
XYZ symBoxBL = symBox.Min; // BL=bottom left
XYZ symBoxTR = symBox.Max; // TR=top right
XYZ symBoxTL = new XYZ(symBoxBL.X, symBoxTR.Y, 0);
XYZ symBoxBR = new XYZ(symBoxTR.X, symBoxBL.Y, 0);
// Apply transform to each corner to find actual instance Bbox coordinates
var transf = instance.GetTransform();
XYZ coordBL = transf.OfPoint(symBoxBL);
XYZ coordTR = transf.OfPoint(symBoxTR);
XYZ coordTL = transf.OfPoint(symBoxTL);
XYZ coordBR = transf.OfPoint(symBoxBR);
// L=left, B=bottom, R=right, T=top
double distL = 30;
double distB = 15;
double distR = 20;
double distT = 10;
//Formulas
//double newX = oldX + dist * Math.Cos(angle * Math.PI / 180);
//double newY = oldY + dist * Math.Sin(angle * Math.PI / 180);
#region BOTTOM LEFT CORNER
double startBLx = coordBL.X +
UnitUtils.ConvertToInternalUnits(distL, DisplayUnitType.DUT_MILLIMETERS) *
Math.Cos((instRotationDeg) * Math.PI / 180);
double startBLy = coordBL.Y +
UnitUtils.ConvertToInternalUnits(distL, DisplayUnitType.DUT_MILLIMETERS) *
Math.Sin((instRotationDeg) * Math.PI / 180);
double finalBLx = startBLx +
UnitUtils.ConvertToInternalUnits(distB, DisplayUnitType.DUT_MILLIMETERS) *
Math.Cos((instRotationDeg + 90) * Math.PI / 180);
double finalBLy = startBLy +
UnitUtils.ConvertToInternalUnits(distB, DisplayUnitType.DUT_MILLIMETERS) *
Math.Sin((instRotationDeg + 90) * Math.PI / 180);
Log.Information("BotL: ({0},{1})", finalBLx, finalBLy);
#endregion
#region BOTTOM RIGHT CORNER
double startBRx = coordBR.X +
UnitUtils.ConvertToInternalUnits(distR, DisplayUnitType.DUT_MILLIMETERS) *
Math.Cos((instRotationDeg + 180) * Math.PI / 180);
double startBRy = coordBR.Y +
UnitUtils.ConvertToInternalUnits(distR, DisplayUnitType.DUT_MILLIMETERS) *
Math.Sin((instRotationDeg + 180) * Math.PI / 180);
double finalBRx = startBRx +
UnitUtils.ConvertToInternalUnits(distB, DisplayUnitType.DUT_MILLIMETERS) *
Math.Cos((instRotationDeg + 90) * Math.PI / 180);
double finalBRy = startBRy +
UnitUtils.ConvertToInternalUnits(distB, DisplayUnitType.DUT_MILLIMETERS) *
Math.Sin((instRotationDeg + 90) * Math.PI / 180);
Log.Information("BotR: ({0},{1})", finalBRx, finalBRy);
#endregion
#region TOP RIGHT CORNER
double startTRx = coordTR.X +
UnitUtils.ConvertToInternalUnits(distR, DisplayUnitType.DUT_MILLIMETERS) *
Math.Cos((instRotationDeg + 180) * Math.PI / 180);
double startTRy = coordTR.Y +
UnitUtils.ConvertToInternalUnits(distR, DisplayUnitType.DUT_MILLIMETERS) *
Math.Sin((instRotationDeg + 180) * Math.PI / 180);
double finalTRx = startTRx +
UnitUtils.ConvertToInternalUnits(distT, DisplayUnitType.DUT_MILLIMETERS) *
Math.Cos((instRotationDeg + 270) * Math.PI / 180);
double finalTRy = startTRy +
UnitUtils.ConvertToInternalUnits(distT, DisplayUnitType.DUT_MILLIMETERS) *
Math.Sin((instRotationDeg + 270) * Math.PI / 180);
Log.Information("TopR: ({0},{1})", finalTRx, finalTRy);
#endregion
#region TOP LEFT CORNER
double startTLx = coordTL.X +
UnitUtils.ConvertToInternalUnits(distT, DisplayUnitType.DUT_MILLIMETERS) *
Math.Cos((instRotationDeg + 270) * Math.PI / 180);
double startTLy = coordTL.Y +
UnitUtils.ConvertToInternalUnits(distT, DisplayUnitType.DUT_MILLIMETERS) *
Math.Sin((instRotationDeg + 270) * Math.PI / 180);
double finalTLx = startTLx +
UnitUtils.ConvertToInternalUnits(distL, DisplayUnitType.DUT_MILLIMETERS) *
Math.Cos((instRotationDeg) * Math.PI / 180);
double finalTLy = startTLy +
UnitUtils.ConvertToInternalUnits(distL, DisplayUnitType.DUT_MILLIMETERS) *
Math.Sin((instRotationDeg) * Math.PI / 180);
Log.Information("TopL: ({0},{1})", finalTLx, finalTLy);
#endregion
}
}