حرکت کنترل روی فرم ولی با محدودیت مکانی

mhabat

Member
سلام.
به یه مشکل بر خوردم که هرچی فکر روش می کنم به نتیجه نمیرسم.

داخل فرم با تنضیم رویداد ها الان یکی از کنترل هارو میتونیم روی فرم حرکت بدیم با موس.

خوب حالا میخوام که این کنترل رو فقط بتونه روی یک محور دایره یی حرکت کنه و از اون محور داخل یا خارج نشه.

مثلا یک الکترون از روی مدارش به داخل یا خارج حرکت که نمی کنه! .

یعنی نتونیم کنترل رو به هر قسمت از فرم جابه جا کنیم فقط حول یک دایره بتونیم بچرخونیم.

دوستان اگر فکر نمی دونم رفرنسی هر چی که به ذهنتون میرسه بگین شاید به نتیجه برسه!



مممنون

از چنین سورسی هم برای رویداد استفاده می کنم که ببینم در محدوده هست یا نه! ولی فکر کنم باید محیط رو به فرم پیکسلی تغییر بدم که نمیدونم چطور!
کد:
privatevoid button1_LocationChanged(object sender, EventArgs e)
         {            
double x1, y1;             
for (int i = 1; i <= 360; i++)
             {                 x1 = 100 * Math.Cos(i * Math.PI / 180) + 300;
                               y1 = 100 * Math.Sin(i * Math.PI / 180) + 100;
   
                  
if (((Control)sender).Location == newPoint(Convert.ToInt32(x1), Convert.ToInt32(y1)))
                 {
                     
                 }
 
             }
         }
 

the_king

مدیرکل انجمن
سلام.
به یه مشکل بر خوردم که هرچی فکر روش می کنم به نتیجه نمیرسم.

داخل فرم با تنضیم رویداد ها الان یکی از کنترل هارو میتونیم روی فرم حرکت بدیم با موس.

خوب حالا میخوام که این کنترل رو فقط بتونه روی یک محور دایره یی حرکت کنه و از اون محور داخل یا خارج نشه.

مثلا یک الکترون از روی مدارش به داخل یا خارج حرکت که نمی کنه! .

یعنی نتونیم کنترل رو به هر قسمت از فرم جابه جا کنیم فقط حول یک دایره بتونیم بچرخونیم.

دوستان اگر فکر نمی دونم رفرنسی هر چی که به ذهنتون میرسه بگین شاید به نتیجه برسه!



مممنون

از چنین سورسی هم برای رویداد استفاده می کنم که ببینم در محدوده هست یا نه! ولی فکر کنم باید محیط رو به فرم پیکسلی تغییر بدم که نمیدونم چطور!
کد:
privatevoid button1_LocationChanged(object sender, EventArgs e)
         {            
double x1, y1;             
for (int i = 1; i <= 360; i++)
             {                 x1 = 100 * Math.Cos(i * Math.PI / 180) + 300;
                               y1 = 100 * Math.Sin(i * Math.PI / 180) + 100;
   
                  
if (((Control)sender).Location == newPoint(Convert.ToInt32(x1), Convert.ToInt32(y1)))
                 {
                     
                 }
 
             }
         }

MyCircle اسم کمپوننت ای یه که ساخته ام. وقتی پروژه کامپایل میشه، در Toolbox ویژوال استدیو در بالاترین گروه قرار می گیره
و میشه به تعداد دلخواه روی فرم قرارش داد.

مشخصه Angle زاویه فعلی یه، بر حسب درجه.
وقتی عوض بشه رخداد AngleChanged اتفاق می افته.
مشخصه MinAngle و MaxAngle برای محدود کردن کنترل روی یک بازه است.
مشخصه Direction جهت شمارش درجه است، در جهت عقربه های ساعت یا خلاف عقربه های ساعت.
کنترل می تونه تصویری در BackgroundImage داشته باشه.
مشخصه MovableObject می تونه تصویری باشه که کنترل جابجا می کنه، اگر تصویری برایش مشخص نشه، یک دایره رو نشون میده.
مشخصه RotateObject تعیین می کنه که موقع تغییر زاویه، آیا تصویر MovableObject هم تغییر زاویه پیدا کنه یا ثابت بمونه.
مشخصه ShowBorder تعیین می کنه که یک خط دور ناحیه دایره ای دور کنترل رسم بشه یا خیر.
مشخصه BorderColor رنگ خطوط رو مشخص می کنه.
چند مدل مثال هم داخل پروژه هست.

Preview.jpg


مشاهده پیوست MoveObjectAroundACircle.zip

در اوایل کد MyCircle.cs یک سطر namespace MoveObjectAroundACircle هست، برای استفاده در هر پروژه دیگری طبیعتا باید MoveObjectAroundACircle را با نام
namespace پروژه جدید جایگزین کنید.
 

mhabat

Member
سلام.

آقا من یه تسلطی روی سورس کلاستون پیدا کردم.

فقط نتونستم متوجه بشم که چطور وقتی یک شکلی رو در paint رسم کردین

چه کاری می کنید که میتونید باه mouseeventhelender مرتبطش کنید!

یعنی این که من یک شء رو در paint رسم کردم ولی نمیدونم چطور هندلش کنم به رویداد ها!

یعنی اینکه مثلا با drawRectangle یا drawImage شکلی رو رسم کردم و میخوام حرکتش بدم با موس.

ممنون
 

the_king

مدیرکل انجمن
سلام.

آقا من یه تسلطی روی سورس کلاستون پیدا کردم.

فقط نتونستم متوجه بشم که چطور وقتی یک شکلی رو در paint رسم کردین

چه کاری می کنید که میتونید باه mouseeventhelender مرتبطش کنید!

یعنی این که من یک شء رو در paint رسم کردم ولی نمیدونم چطور هندلش کنم به رویداد ها!

یعنی اینکه مثلا با drawRectangle یا drawImage شکلی رو رسم کردم و میخوام حرکتش بدم با موس.

ممنون

در کلاس تون متغیر تعریف کنید، فرضا x و y از نوع int یا یک متغیر از نوع Point یا یک متغیر برای زاویه
اونوقت در موقع رسم کردن تصویر در رخداد Paint بجای اینکه مختصات و زاویه رسم رو صریحا و ثابت تعیین کنید از این متغیر ها استفاده کنید.
در رخداد های مرتبط با ماوس، مقدار این متغیر ها را تغییر دهید. فقط فراموش نکنید که تغییر متغیر به تنهایی موجب Paint مجدد نمی شود
و بلافاصله تغییری در ظاهر رخ نمی دهد. برای همین بعد از تغییر مقدار متغیر باید یک Invalidate روی اون کنترل اجرا بشه تا رخداد Paint مجددا اجرا بشه.
 

mhabat

Member
آقا یه مشکلی وجود داره!
اون هم توی رویداد های موس مقدار متغیر هارو بدیم.
ما باید مشخص کنیم که اگر رویداد موس down روی تصویر اتفاق افتاد متغیر هارو تغییر مقدار بده. واسه همین ما نمیدونیم که موس روی تصویر کلیلک کرده یا نه!
خوب حالا به نظرتون چی کار کنم؟ مثلا یه پنل بزارم پشت تصویر بگم اگر موس روی مختصات این پنل کلیلک کرد اون موقه رویداد موس دون اتفاق افتاده ؟
 

the_king

مدیرکل انجمن
آقا یه مشکلی وجود داره!
اون هم توی رویداد های موس مقدار متغیر هارو بدیم.
ما باید مشخص کنیم که اگر رویداد موس down روی تصویر اتفاق افتاد متغیر هارو تغییر مقدار بده. واسه همین ما نمیدونیم که موس روی تصویر کلیلک کرده یا نه!
خوب حالا به نظرتون چی کار کنم؟ مثلا یه پنل بزارم پشت تصویر بگم اگر موس روی مختصات این پنل کلیلک کرد اون موقه رویداد موس دون اتفاق افتاده ؟

نیازی به پنل نیست، شما فقط باید بدانید که تصویر کجا نمایش داده میشه.
موقعیت تصویری که شما نمایش داده اید مشخصه، فرضا اون مختصات در یک شیء از نوع Rectangle ذخیره شده :
کد:
private Rectangle _pos;

مختصات جایی که ماوس Down شده هم مشخصه، در e.X, e.Y و بصورت ترکیبی در e.Location
کد:
        protected override void OnMouseDown(MouseEventArgs e)
        {
        }

حالا می توانید چک کنید که آیا اون Rectangle شامل اون e.Location هست یا نه، یعنی آیا کلیک روی Picture مورد نظر صورت گرفته یا خیر :
کد:
        protected override void OnMouseDown(MouseEventArgs e)
        {
            if (_pos.Contains(e.Location))
            {
[COLOR="#A9A9A9"]...[/COLOR]
            }
        }
 

mhabat

Member
سلام. یه مشکل که هم هستش این هست که برای حرکت کنترل وقتی از invalidate استفاده می کنم باعث میشه که تصویر فرم پشت سرهم در زمان کوتاه بره و بیاد یعنی تصویر فرم قطع و وصل میشه.
 

the_king

مدیرکل انجمن
سلام. یه مشکل که هم هستش این هست که برای حرکت کنترل وقتی از invalidate استفاده می کنم باعث میشه که تصویر فرم پشت سرهم در زمان کوتاه بره و بیاد یعنی تصویر فرم قطع و وصل میشه.

این جلوه Flicker یا پرپر زدن زمانی اتفاق می افته که در فاصله زمانی که ترسیم داره انجام میشه و هنوز به اتمام نرسیده ترسیم نیمه کاره نمایش داده میشه.
طبیعتا زمانی این جلوه بیشتر به چشم میاد که ترسیم پیچیده و زمانبر باشه. راه حل اینه که بافر ترسیم از بافری که نمایش داده میشه مستقل باشه.
فقط زمانی این دو تا یکسان می شوند که ترسیم به پایان رسیده و داخل بافر نمایشی کپی اش می کنیم. در حین ترسیم، بافر ترسیم پشت پرده در حال تغییر ئه.
مصرف حافظه بیشتر ئه، چون یک بافر اضافی لازمه، اما در عوض تا زمانی که ترسیم به پایان نرسیده هیچ تغییری که موجب پرپر زدن بشه روی ظاهر تصویر نمیاد.
رجوع شود به :
چند مشکل در visual #c
 

mhabat

Member
نیازی به پنل نیست، شما فقط باید بدانید که تصویر کجا نمایش داده میشه.
موقعیت تصویری که شما نمایش داده اید مشخصه، فرضا اون مختصات در یک شیء از نوع Rectangle ذخیره شده :
کد:
private Rectangle _pos;

مختصات جایی که ماوس Down شده هم مشخصه، در e.X, e.Y و بصورت ترکیبی در e.Location
کد:
        protected override void OnMouseDown(MouseEventArgs e)
        {
        }

حالا می توانید چک کنید که آیا اون Rectangle شامل اون e.Location هست یا نه، یعنی آیا کلیک روی Picture مورد نظر صورت گرفته یا خیر :
کد:
        protected override void OnMouseDown(MouseEventArgs e)
        {
            if (_pos.Contains(e.Location))
            {
[COLOR=#a9a9a9]...[/COLOR]
            }
        }
سلام .
یه سوال!
ما از یک rectangel استفاده کردیم که ببینیم داخل اون مستطیل نقطه ی مورد نظر ما هستش یا نه!
این یه مشکلی داره
اون هم این هستش که اگر شکل مورد نظر ما مثلا یک دایره باشه! می خوایم کاری کنیم که فقط مختصات روی دایره رو چک کنه ! نه مختصات یک مستطیل رو
چون در اصل دایره ی ما یک مستطیل بوده که تنرس پرنت شده!

در کل میخوام کاری کنم که اگر موس دقیق روی عکسمون کلیک کرد متوجه بشیم! و اگر روی نقاطی از عکس کلیلک کرد که ترنس پرنت بود اون جارو بیخیال شه!
نمونش هم اشیاء shap در مایکروسافت که وقتی روی فرم قرار شون میدی مثلا یک دایره رو روی فرم قرار میدی اگر روی دایره کلیک کنی عمل می کنه.
 

the_king

مدیرکل انجمن
سلام .
یه سوال!
ما از یک rectangel استفاده کردیم که ببینیم داخل اون مستطیل نقطه ی مورد نظر ما هستش یا نه!
این یه مشکلی داره
اون هم این هستش که اگر شکل مورد نظر ما مثلا یک دایره باشه! می خوایم کاری کنیم که فقط مختصات روی دایره رو چک کنه ! نه مختصات یک مستطیل رو
چون در اصل دایره ی ما یک مستطیل بوده که تنرس پرنت شده!

در کل میخوام کاری کنم که اگر موس دقیق روی عکسمون کلیک کرد متوجه بشیم! و اگر روی نقاطی از عکس کلیلک کرد که ترنس پرنت بود اون جارو بیخیال شه!
نمونش هم اشیاء shap در مایکروسافت که وقتی روی فرم قرار شون میدی مثلا یک دایره رو روی فرم قرار میدی اگر روی دایره کلیک کنی عمل می کنه.

ساده است، اگر تصویر ئه، رنگ اون نقطه از تصویر که رویش کلیک میشه را بخوانید، اگر A (کانال Alpha) اش از مقداری کمتر بود (فرضا 50)، اون کلیک رو بی خیال شوید.
اگر شی مورد نظر GraphicsPath است (بقول شما Shape ئه)، GraphicsPath.IsVisible می تونه بررسی کنه که آیا اون نقطه مورد نظر داخل اش هست یا خیر.

عمدا آیکون رو با ابعاد نامتعارف و کشیده رسم کردم تا مقیاس پذیر بودن کد ()IsOver رو نشون بدم :
مشاهده پیوست ClickOnShape.zip
 

جدیدترین ارسال ها

بالا