int UVW_ChannelClass::EdgeIntersect(Point3 p, float threshold, int i1,int i2) { static int startEdge = 0; if (startEdge >= ePtrList.Count()) startEdge = 0; if (ePtrList.Count() == 0) return -1; int ct = 0; BOOL done = FALSE; int hitEdge = -1; while (!done) { //check bounding volumes Box3 bounds; bounds.Init(); int index1 = ePtrList[startEdge]->a; int index2 = ePtrList[startEdge]->b; if (v[index1].IsHidden() && v[index2].IsHidden()) { } else if (v[index1].IsFrozen() && v[index1].IsFrozen()) { } else { Point3 p1(0.0f,0.0f,0.0f); p1[i1] = v[index1].GetP()[i1]; p1[i2] = v[index1].GetP()[i2]; // p1.z = 0.0f; bounds += p1; Point3 p2(0.0f,0.0f,0.0f); p2[i1] = v[index2].GetP()[i1]; p2[i2] = v[index2].GetP()[i2]; // p2.z = 0.0f; bounds += p2; bounds.EnlargeBy(threshold); if (bounds.Contains(p)) { //check edge distance if (LineToPoint(p, p1, p2) < threshold) { hitEdge = startEdge; done = TRUE; // LineToPoint(p, p1, p2); } } } ct++; startEdge++; if (ct == ePtrList.Count()) done = TRUE; if (startEdge >= ePtrList.Count()) startEdge = 0; } return hitEdge; }
void PointGatherer::AddWeightFromSegment(Point3 a, float radiusA, float strA, Point3 b, float radiusB, float strB, ICurve *pCurve, BOOL additveMode, BOOL isMirror, float currentLength) { float segLength = Length(a-b); //get the bounding box from the segment Box3 bounds; bounds.Init(); bounds += a; bounds += b; if (radiusA > radiusB) bounds.EnlargeBy(radiusA); else bounds.EnlargeBy(radiusB); int startX, endX; int startY, endY; int startZ, endZ; startX = (bounds.pmin.x - upperLeft.x)/xOffset; startY= (bounds.pmin.y - upperLeft.y)/yOffset; startZ= (bounds.pmin.z - upperLeft.z)/zOffset; endX = (bounds.pmax.x - upperLeft.x)/xOffset; endY= (bounds.pmax.y - upperLeft.y)/yOffset; endZ= (bounds.pmax.z - upperLeft.z)/zOffset; //need to constrains the indices since a brush envelope can exist past our bounds if (startX < 0) startX = 0; if (startX >= width) startX = width-1; if (endX < 0) endX = 0; if (endX >= width) endX = width-1; if (startY < 0) startY = 0; if (startY >= width) startY = width-1; if (endY < 0) endY = 0; if (endY >= width) endY = width-1; if (startZ < 0) startZ = 0; if (startZ >= width) startZ = width-1; if (endZ < 0) endZ = 0; if (endZ >= width) endZ = width-1; //get all the cells that intersect with the bounding box //loop through those points adding weight to em if they are within the envelope float u = 0.0f; float dist = 0.0f; float envDist = 0.0f; /* //Brute force method checks against every point for (int i = 0; i < cellData.Count(); i++) { for (int j = 0; j < cellElementCount[i]; j++) { Point3 p = *cellData[i].p[j]; dist = LineToPoint(p,a,b,u); envDist = radiusA + ((radiusB-radiusA) * u); if (dist <= envDist) { //DebugPrint("dist %f envdist %f\n",dist,envDist); float weight = 1.0f - dist/envDist; float str = (strA + ((strB-strA) * u)) * weight; float listWeight = cellData[i].weight[j]; if (weight > listWeight) { cellData[i].str[j] = str; cellData[i].weight[j] = weight; } } } } */ //checks against cells first then those points only within the hit cells //2 d gather /* for (int i = startY; i <= endY; i++) { int currentCell = i * width; for (int j = startX; j <= endX; j++) { if (CellDataXY[currentCell+j]) { for (int k = 0; k < CellDataXY[currentCell+j]->whichPoint.Count(); k++) { int whichPoint = CellDataXY[currentCell+j]->whichPoint[k]; int whichNode = CellDataXY[currentCell+j]->whichNode[k]; Point3 p = *cellData[whichNode].p[whichPoint]; dist = LineToPoint(p,a,b,u); envDist = radiusA + ((radiusB-radiusA) * u); if (dist <= envDist) { //DebugPrint("dist %f envdist %f\n",dist,envDist); float weight = 1.0f - dist/envDist; float str = (strA + ((strB-strA) * u)) * weight; float listWeight = cellData[whichNode].weight[whichPoint]; if (weight > listWeight) { cellData[whichNode].str[whichPoint] = str; cellData[whichNode].weight[whichPoint] = weight; } } } } } } */ for (int i = 0; i < cellData.Count(); i++) { int* countAmount = cellData[i].count; memset(countAmount,0,cellElementCount[i]*sizeof(int)); /* for (int j = 0; j < cellElementCount[i]; j++) { *countAmount = 0; countAmount++; } */ } // 3 d gather //in xy for (i = startY; i <= endY; i++) { int currentCell = i * width; for (int j = startX; j <= endX; j++) { if (CellDataXY[currentCell+j]) { for (int k = 0; k < CellDataXY[currentCell+j]->whichPoint.Count(); k++) { int whichPoint = CellDataXY[currentCell+j]->whichPoint[k]; int whichNode = CellDataXY[currentCell+j]->whichNode[k]; cellData[whichNode].count[whichPoint]++; } } } } //in yz for (i = startZ; i <= endZ; i++) { int currentCell = i * width; for (int j = startY; j <= endY; j++) { if (CellDataYZ[currentCell+j]) { for (int k = 0; k < CellDataYZ[currentCell+j]->whichPoint.Count(); k++) { int whichPoint = CellDataYZ[currentCell+j]->whichPoint[k]; int whichNode = CellDataYZ[currentCell+j]->whichNode[k]; cellData[whichNode].count[whichPoint]++; } } } } //in xz for ( i = startZ; i <= endZ; i++) { int currentCell = i * width; for (int j = startX; j <= endX; j++) { if (CellDataXZ[currentCell+j]) { for (int k = 0; k < CellDataXZ[currentCell+j]->whichPoint.Count(); k++) { int whichPoint = CellDataXZ[currentCell+j]->whichPoint[k]; int whichNode = CellDataXZ[currentCell+j]->whichNode[k]; cellData[whichNode].count[whichPoint]++; } } } } for ( i = 0; i < cellData.Count(); i++) { int* countAmount = cellData[i].count; for (int j = 0; j < cellElementCount[i]; j++) { if (*countAmount == 3) { int whichPoint = j; int whichNode =i; Point3 p = cellData[whichNode].p[whichPoint]; dist = LineToPoint(p,a,b,u); envDist = radiusA + ((radiusB-radiusA) * u); if (dist <= envDist) { float weight = 1.0f - dist/envDist; float str = (strA + ((strB-strA) * u)); float listWeight = cellData[whichNode].weight[whichPoint]; if (additveMode) { pointGatherHitVerts[whichNode]->Set(whichPoint,TRUE); cellData[whichNode].weight[whichPoint] += weight; weight = pCurve->GetValue(0,1.0f-weight); cellData[whichNode].str[whichPoint] += str*weight; cellData[whichNode].u[whichPoint] = (currentLength + (u*segLength)); } else if (weight > listWeight) { pointGatherHitVerts[whichNode]->Set(whichPoint,TRUE); cellData[whichNode].weight[whichPoint] = weight; weight = pCurve->GetValue(0,1.0f-weight); cellData[whichNode].str[whichPoint] = str*weight; cellData[whichNode].u[whichPoint] = (currentLength + (u*segLength)); } //if first mirror if ((isMirror) && (cellData[whichNode].isMirror[whichPoint] == NO_MIRRROR)) cellData[whichNode].isMirror[whichPoint] = MIRRRORED; else if ((!isMirror) && (cellData[whichNode].isMirror[whichPoint] == MIRRRORED)) cellData[whichNode].isMirror[whichPoint] = MIRRROR_SHARED; //if mirrored and now appliying a non mirror weight } } countAmount++; } } //DebugPrint("Solving Stroke %f %f %f \n",a.x,a.y,a.z); //DebugPrint(" %f %f %f \n",b.x,b.y,b.z); }
int TDrawingItem::CheckDrag(float x, float y, int size) { //ドラッグ開始可能かを調べる。ドラッグの種類を返す m_fDragStartX = x; m_fDragStartY = y; memcpy(m_DragRect, m_Rect, sizeof(m_Rect)); //実座標へ変換 int rx = x * size; int ry = y * size; //4隅 for (int i = 0 ; i < 4 ; i++){ if (m_nType != 2 || i == 0 || i == 3){ if (rx >= size * m_Rect[(i % 2) * 2] - 4 && ry >= size * m_Rect[(i / 2) * 2 + 1] - 4 && rx < size * m_Rect[(i % 2) * 2] + 4 && ry < size * m_Rect[(i / 2) * 2 + 1] + 4){ return 0x10 | i; } } } //平行移動 switch(m_nType){ case 1://FreeHand { float w2 = m_Rect[2] - m_Rect[0]; float h2 = m_Rect[3] - m_Rect[1]; int result = 0; if (w2 != 0.0f && h2 != 0.0f){ float *p = new float[Count]; for (int i = 0 ; i < Count / 2 ; i++){ int ix = (int)Items[i * 2]; float fx = *(float*)&ix; int iy = (int)Items[i * 2 + 1]; float fy = *(float*)&iy; p[i * 2] = m_Rect[0] + fx * w2; p[i * 2 + 1] = m_Rect[1] + fy * h2; } for (int i = 1 ; i < Count / 2 ; i++){ if (LineToPoint(size * p[(i - 1) * 2], size * p[(i - 1) * 2 + 1], size * p[i * 2], size * p[i * 2 + 1], rx, ry) <= 4){ result = 0x01; } } delete[] p; } if (result) { return result; } } break; case 2://Line if (LineToPoint(size * m_Rect[0], size * m_Rect[1], size * m_Rect[2], size * m_Rect[3], rx, ry) <= 4){ return 0x01; } break; case 3://Box if (LineToPoint(size * m_Rect[0], size * m_Rect[1], size * m_Rect[0], size * m_Rect[3], rx, ry) <= 4 || LineToPoint(size * m_Rect[0], size * m_Rect[1], size * m_Rect[2], size * m_Rect[1], rx, ry) <= 4 || LineToPoint(size * m_Rect[2], size * m_Rect[1], size * m_Rect[2], size * m_Rect[3], rx, ry) <= 4 || LineToPoint(size * m_Rect[0], size * m_Rect[3], size * m_Rect[2], size * m_Rect[3], rx, ry) <= 4){ return 0x01; } break; case 4://Circle { if (m_Rect[3] - m_Rect[1] == 0.0f || m_Rect[2] - m_Rect[0] == 0.0f) { //円が線状である場合 if (LineToPoint(size * m_Rect[0], size * m_Rect[1], size * m_Rect[2], size * m_Rect[3], rx, ry) <= 4){ return 0x01; } }else{ double xx = (m_Rect[3] - m_Rect[1]) / (m_Rect[2] - m_Rect[0]);//楕円を円にするためのXにかける係数 double cx = (m_Rect[2] + m_Rect[0]) * 0.5 * xx;//円にした場合のX座標中心 double cy = (m_Rect[3] + m_Rect[1]) * 0.5;//Y座標中心 double dx = x * xx;//円にした場合のカーソル位置 double dist = sqrt((dx - cx) * (dx - cx) + (y - cy) * (y - cy));//円にした場合の中心とカーソルの距離 double r = fabs(m_Rect[3] - m_Rect[1]) * 0.5;//円にした場合の半径 double rd = r / dist;//中心からカーソル位置にrdだけ近づけた点が円周上の点 double ccx = (cx * (1.0 - rd) + dx * rd) / xx;//円周上のX double ccy = cy * (1.0 - rd) + y * rd;//円周上のY if (sqrt((x - ccx) * (x - ccx) * size * size + (y - ccy) * (y - ccy) * size * size) <= 6){ //円周上の点からカーソル位置までの距離が小さければドラッグ return 0x01; } } } break; } return 0;//ドラッグ不能 }