This is MiscRoundedRectShape.m in view mode; [Download] [Up]
/* MiscRoundedRectShape.m
Copyright 1996 Uwe Hoffmann.
This notice may not be removed from this source code.
The use and distribution of this software is governed by the
terms of the MiscKit license agreement. Refer to the license
document included with the MiscKit distribution for the terms.
Version 2 (August 1996)
*/
#import <Foundation/Foundation.h>
#import "MiscRoundedRectShape.h"
#import "MiscUserPath.h"
#import "MiscHitPath.h"
#import "MiscTDUtils.h"
@implementation MiscRoundedRectShape
- (NSRect)innerBounds
{
NSRect br,ir;
NSPoint m;
float a,b,cx,cy,r;
br = [path bounds];
r = MIN(br.size.width / 3, br.size.height / 3);
m.x = br.origin.x + br.size.width / 2;
m.y = br.origin.y + br.size.height / 2;
a = br.size.width / 2;
b = br.size.height / 2;
cx = a - r / 2;
cy = b - 0.1339746 * r;
ir.origin.x = m.x - cx;
ir.origin.y = m.y - cy;
ir.size.width = 2 * cx;
ir.size.height = 2 * cy;
return ir;
}
- (MiscShapeType)shapeType
{
return MiscRoundedRectShapeType;
}
- (void)calcIntersection:(NSPoint *)ip angle:(float *)alpha toPoint:(NSPoint)aPoint
{
NSPoint middle,l1,l2,pos;
float s,width,height,*bbox;
float xm,ym,x0,y0,r,ausdruck;
bbox = [path bbox];
pos.x = bbox[0];
pos.y = bbox[1];
width = bbox[2] - bbox[0];
height = bbox[3] - bbox[1]; middle.x = pos.x + width / 2;
middle.y = pos.y + height / 2;
if(aPoint.y == middle.y){
ip->y = middle.y;
if(aPoint.x > middle.x){
*alpha = 0;
ip->x = pos.x + width;
} else {
*alpha = 180;
ip->x = pos.x;
}
return;
}
if(aPoint.x == middle.x){
ip->x = middle.x;
if(aPoint.y > middle.y){
ip->y = pos.y + height;
*alpha = 90;
} else {
ip->y = pos.y;
*alpha = -90;
}
return;
}
s = (aPoint.y - middle.y) / (aPoint.x - middle.x);
*alpha = 57.29577951 * atan(s);
r = MIN(width,height) / 3;
if(aPoint.y > middle.y){
if(aPoint.x > middle.x){ // I. quadrant
l1.x = middle.x;
l1.y = pos.y + height;
l2.x = pos.x + width - r;
l2.y = pos.y + height;
if(miscTD_straddles(l1, l2, middle, aPoint)){
ip->y = l1.y;
ip->x = middle.x + (ip->y - middle.y) / s;
} else {
l1.x = l2.x = pos.x + width;
l1.y = middle.y;
l2.y = pos.y + height - r;
if(miscTD_straddles(l1, l2, middle, aPoint)){
ip->x = l2.x;
ip->y = middle.y + s * (ip->x - middle.x);
} else {
x0 = middle.x;
y0 = middle.y;
xm = pos.x + width - r;
ym = pos.y + height - r;
ausdruck = (pow(r,2) + pow(r,2)*pow(s,2) - pow(s,2)*pow(xm,2) +
2*pow(s,2)*xm*x0 - pow(s,2)*pow(x0,2) + 2*s*xm*ym - 2*s*x0*ym -
pow(ym,2) - 2*s*xm*y0 + 2*s*x0*y0 + 2*ym*y0 - pow(y0,2));
ip->x = (xm + pow(s,2)*x0 + s*ym - s*y0 + sqrt(ausdruck))/(1 + pow(s,2));
ip->y = (s*xm - s*x0 + pow(s,2)*ym + y0 + s*sqrt(ausdruck))/(1 + pow(s,2));
if(ip->y < ym){
ip->x = (xm + pow(s,2)*x0 + s*ym - s*y0 - sqrt(ausdruck))/(1 + pow(s,2));
ip->y = (s*xm - s*x0 + pow(s,2)*ym + y0 - s*sqrt(ausdruck))/(1 + pow(s,2));
}
}
}
} else { // II. quadrant
l1.x = middle.x;
l1.y = pos.y + height;
l2.x = pos.x + r;
l2.y = pos.y + height;
if(miscTD_straddles(l1, l2, middle, aPoint)){
ip->y = l1.y;
ip->x = middle.x + (ip->y - middle.y) / s;
} else {
l1.x = l2.x = pos.x;
l1.y = middle.y;
l2.y = pos.y + height - r;
if(miscTD_straddles(l1, l2, middle, aPoint)){
ip->x = l2.x;
ip->y = middle.y + s * (ip->x - middle.x);
} else {
x0 = middle.x;
y0 = middle.y;
xm = pos.x + r;
ym = pos.y + height - r;
ausdruck = (pow(r,2) + pow(r,2)*pow(s,2) - pow(s,2)*pow(xm,2) +
2*pow(s,2)*xm*x0 - pow(s,2)*pow(x0,2) + 2*s*xm*ym - 2*s*x0*ym -
pow(ym,2) - 2*s*xm*y0 + 2*s*x0*y0 + 2*ym*y0 - pow(y0,2));
ip->x = (xm + pow(s,2)*x0 + s*ym - s*y0 + sqrt(ausdruck))/(1 + pow(s,2));
ip->y = (s*xm - s*x0 + pow(s,2)*ym + y0 + s*sqrt(ausdruck))/(1 + pow(s,2));
if(ip->y < ym){
ip->x = (xm + pow(s,2)*x0 + s*ym - s*y0 - sqrt(ausdruck))/(1 + pow(s,2));
ip->y = (s*xm - s*x0 + pow(s,2)*ym + y0 - s*sqrt(ausdruck))/(1 + pow(s,2));
}
}
}
*alpha += 180;
}
} else {
if(aPoint.x > middle.x){ // IV. quadrant
l1.x = middle.x;
l1.y = pos.y;
l2.x = pos.x + width - r;
l2.y = pos.y;
if(miscTD_straddles(l1, l2, middle, aPoint)){
ip->y = l1.y;
ip->x = middle.x + (ip->y - middle.y) / s;
} else {
l1.x = l2.x = pos.x + width;
l1.y = middle.y;
l2.y = pos.y + r;
if(miscTD_straddles(l1, l2, middle, aPoint)){
ip->x = l2.x;
ip->y = middle.y + s * (ip->x - middle.x);
} else {
x0 = middle.x;
y0 = middle.y;
xm = pos.x + width - r;
ym = pos.y + r;
ausdruck = (pow(r,2) + pow(r,2)*pow(s,2) - pow(s,2)*pow(xm,2) +
2*pow(s,2)*xm*x0 - pow(s,2)*pow(x0,2) + 2*s*xm*ym - 2*s*x0*ym -
pow(ym,2) - 2*s*xm*y0 + 2*s*x0*y0 + 2*ym*y0 - pow(y0,2));
ip->x = (xm + pow(s,2)*x0 + s*ym - s*y0 + sqrt(ausdruck))/(1 + pow(s,2));
ip->y = (s*xm - s*x0 + pow(s,2)*ym + y0 + s*sqrt(ausdruck))/(1 + pow(s,2));
if(ip->y > ym){
ip->x = (xm + pow(s,2)*x0 + s*ym - s*y0 - sqrt(ausdruck))/(1 + pow(s,2));
ip->y = (s*xm - s*x0 + pow(s,2)*ym + y0 - s*sqrt(ausdruck))/(1 + pow(s,2));
}
}
}
} else { // III. quadrant
l1.x = middle.x;
l1.y = pos.y;
l2.x = pos.x + r;
l2.y = pos.y;
if(miscTD_straddles(l1, l2, middle, aPoint)){
ip->y = l1.y;
ip->x = middle.x + (ip->y - middle.y) / s;
} else {
l1.x = l2.x = pos.x;
l1.y = middle.y;
l2.y = pos.y + r;
if(miscTD_straddles(l1, l2, middle, aPoint)){
ip->x = l2.x;
ip->y = middle.y + s * (ip->x - middle.x);
} else {
x0 = middle.x;
y0 = middle.y;
xm = pos.x + r;
ym = pos.y + r;
ausdruck = (pow(r,2) + pow(r,2)*pow(s,2) - pow(s,2)*pow(xm,2) +
2*pow(s,2)*xm*x0 - pow(s,2)*pow(x0,2) + 2*s*xm*ym - 2*s*x0*ym -
pow(ym,2) - 2*s*xm*y0 + 2*s*x0*y0 + 2*ym*y0 - pow(y0,2));
ip->x = (xm + pow(s,2)*x0 + s*ym - s*y0 + sqrt(ausdruck))/(1 + pow(s,2));
ip->y = (s*xm - s*x0 + pow(s,2)*ym + y0 + s*sqrt(ausdruck))/(1 + pow(s,2));
if(ip->y > ym){
ip->x = (xm + pow(s,2)*x0 + s*ym - s*y0 - sqrt(ausdruck))/(1 + pow(s,2));
ip->y = (s*xm - s*x0 + pow(s,2)*ym + y0 - s*sqrt(ausdruck))/(1 + pow(s,2));
}
}
}
*alpha += 180;
}
}
}
- (void)makePathWithBounds:(NSRect)aRect
{
float r;
r = MIN(aRect.size.width / 3, aRect.size.height / 3);
[path moveto:aRect.origin.x :aRect.origin.y + r];
[path lineto:aRect.origin.x :aRect.origin.y + aRect.size.height - r];
[path curveto:aRect.origin.x :aRect.origin.y + aRect.size.height - r + r * 0.5519
:aRect.origin.x + r - r * 0.5519 :aRect.origin.y + aRect.size.height
:aRect.origin.x + r :aRect.origin.y + aRect.size.height];
[path lineto:aRect.origin.x + aRect.size.width - r :aRect.origin.y + aRect.size.height];
[path curveto:aRect.origin.x + aRect.size.width - r + r * 0.5519 :aRect.origin.y + aRect.size.height
:aRect.origin.x + aRect.size.width :aRect.origin.y + aRect.size.height - r + r * 0.5519
:aRect.origin.x + aRect.size.width :aRect.origin.y + aRect.size.height - r];
[path lineto:aRect.origin.x + aRect.size.width :aRect.origin.y + r];
[path curveto:aRect.origin.x + aRect.size.width :aRect.origin.y + r - r * 0.5519
:aRect.origin.x + aRect.size.width - r + r * 0.5519 :aRect.origin.y
:aRect.origin.x + aRect.size.width - r :aRect.origin.y];
[path lineto:aRect.origin.x + r :aRect.origin.y];
[path curveto:aRect.origin.x + r - r * 0.5519 :aRect.origin.y
:aRect.origin.x :aRect.origin.y + r - r * 0.5519
:aRect.origin.x :aRect.origin.y + r];
[path closepath];
}
- (void)fillParamsWithBounds:(NSRect)aRect
{
float *params, *bbox,r;
params = [path params];
bbox = [path bbox];
bbox[0] = aRect.origin.x;
bbox[1] = aRect.origin.y;
bbox[2] = aRect.origin.x + aRect.size.width;
bbox[3] = aRect.origin.y + aRect.size.height;
r = MIN(aRect.size.width / 3, aRect.size.height / 3);
params[0] = aRect.origin.x;
params[1] = aRect.origin.y + r;
params[2] = aRect.origin.x;
params[3] = aRect.origin.y + aRect.size.height - r;
params[4] = aRect.origin.x;
params[5] = aRect.origin.y + aRect.size.height - r + r * 0.5519;
params[6] = aRect.origin.x + r - r * 0.5519;
params[7] = aRect.origin.y + aRect.size.height;
params[8] = aRect.origin.x + r;
params[9] = aRect.origin.y + aRect.size.height;
params[10] = aRect.origin.x + aRect.size.width - r;
params[11] = aRect.origin.y + aRect.size.height;
params[12] = aRect.origin.x + aRect.size.width - r + r * 0.5519;
params[13] = aRect.origin.y + aRect.size.height;
params[14] = aRect.origin.x + aRect.size.width;
params[15] = aRect.origin.y + aRect.size.height - r + r * 0.5519;
params[16] = aRect.origin.x + aRect.size.width;
params[17] = aRect.origin.y + aRect.size.height - r;
params[18] = aRect.origin.x + aRect.size.width;
params[19] = aRect.origin.y + r;
params[20] = aRect.origin.x + aRect.size.width;
params[21] = aRect.origin.y + r - r * 0.5519;
params[22] = aRect.origin.x + aRect.size.width - r + r * 0.5519;
params[23] = aRect.origin.y;
params[24] = aRect.origin.x + aRect.size.width - r;
params[25] = aRect.origin.y;
params[26] = aRect.origin.x + r;
params[27] = aRect.origin.y;
params[28] = aRect.origin.x + r - r * 0.5519;
params[29] = aRect.origin.y;
params[30] = aRect.origin.x;
params[31] = aRect.origin.y + r - r * 0.5519;
params[32] = aRect.origin.x;
params[33] = aRect.origin.y + r;
}
+ (NSSize)calcSizeForInnerSize:(NSSize)aSize
{
NSSize os;
float cx,cy;
cx = aSize.width / 2;
cy = aSize.height / 2;
if(aSize.width > aSize.height){
os.height = 2 * cy / (1 - 0.1339746 * 2 / 3);
os.width = 2 * cx + os.height / 3;
} else {
os.width = 3 * cx;
os.height = 2 * cy + os.width * 2 / 3 * 0.1339746;
}
return os;
}
@end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.